This is an automated email from the ASF dual-hosted git repository.

tqchen pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm-ffi.git


The following commit(s) were added to refs/heads/main by this push:
     new 102fe0e  [OBJECT] Make object info macro compatible with CRTP (#636)
102fe0e is described below

commit 102fe0e93a9627720f3f190d6efc7450c74604a7
Author: Tianqi Chen <[email protected]>
AuthorDate: Thu Jun 18 21:48:58 2026 -0400

    [OBJECT] Make object info macro compatible with CRTP (#636)
    
    This PR makes `TVM_FFI_DECLARE_OBJECT_INFO_PREDEFINED_TYPE_KEY`
    compatible with CRTP-style object declarations, and fixes the MSVC build
    failure seen with that pattern.
    
    When the macro is expanded inside a CRTP base template, the cached
    `_type_index` member is declared in the current CRTP base
    specialization. The `_type_index` initializer now calls
    `_GetOrAllocRuntimeTypeIndex()` through current-class lookup instead of
    qualifying that function through the CRTP leaf type, which avoids MSVC
    lookup failures on incomplete CRTP leaf types.
    
    Other `TypeName::` lookups are preserved so leaf-provided metadata such
    as `_type_key` and child-slot overrides continue to be used.
    
    A generic `CRTPObject<T>` / `LeafObject` regression test is added in
    `test_object.cc`.
    
    Validation:
    - `cmake -S . -B build-crtp -G Ninja -DCMAKE_BUILD_TYPE=Release
    -DTVM_FFI_USE_EXTRA_CXX_API=ON -DTVM_FFI_BUILD_TESTS=ON`
    - `ninja -C build-crtp tvm_ffi_tests`
    - `./build-crtp/lib/tvm_ffi_tests
    --gtest_filter=Object.CRTPObjectInfo:Object.TypeInfo`
    - `./build-crtp/lib/tvm_ffi_tests --gtest_filter=Object.*`
    - `pre-commit run --files include/tvm/ffi/object.h
    tests/cpp/test_object.cc`
---
 include/tvm/ffi/object.h |  2 +-
 tests/cpp/test_object.cc | 26 ++++++++++++++++++++++++++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/include/tvm/ffi/object.h b/include/tvm/ffi/object.h
index 71c69f1..0150c0a 100644
--- a/include/tvm/ffi/object.h
+++ b/include/tvm/ffi/object.h
@@ -971,7 +971,7 @@ struct ObjectPtrEqual {
         TypeName::_type_child_slots_can_overflow, 
ParentType::_GetOrAllocRuntimeTypeIndex()); \
     return tindex;                                                             
               \
   }                                                                            
               \
-  static inline const int32_t _type_index = 
TypeName::_GetOrAllocRuntimeTypeIndex();          \
+  static inline const int32_t _type_index = _GetOrAllocRuntimeTypeIndex();     
               \
   TVM_FFI_INLINE static int32_t RuntimeTypeIndex() noexcept { return 
TypeName::_type_index; }
 
 /*!
diff --git a/tests/cpp/test_object.cc b/tests/cpp/test_object.cc
index 4aeddef..5a5d416 100644
--- a/tests/cpp/test_object.cc
+++ b/tests/cpp/test_object.cc
@@ -27,6 +27,23 @@ namespace {
 using namespace tvm::ffi;
 using namespace tvm::ffi::testing;
 
+template <typename T>
+class CRTPObject : public Object {
+ public:
+  static constexpr int _type_child_slots [[maybe_unused]] = 0;
+  static constexpr bool _type_final [[maybe_unused]] = true;
+  TVM_FFI_DECLARE_OBJECT_INFO_PREDEFINED_TYPE_KEY(T, Object);
+
+ private:
+  friend T;
+  CRTPObject() = default;
+};
+
+class LeafObject : public CRTPObject<LeafObject> {
+ public:
+  static constexpr const char* _type_key = "test.CRTPLeaf";
+};
+
 TEST(Object, RefCounter) {
   ObjectPtr<TIntObj> a = make_object<TIntObj>(11);
   ObjectPtr<TIntObj> b = a;
@@ -60,6 +77,15 @@ TEST(Object, TypeInfo) {
   EXPECT_GE(info->type_index, TypeIndex::kTVMFFIDynObjectBegin);
 }
 
+TEST(Object, CRTPObjectInfo) {
+  const TypeInfo* info = TVMFFIGetTypeInfo(LeafObject::RuntimeTypeIndex());
+  ASSERT_TRUE(info != nullptr);
+  EXPECT_EQ(info->type_index, LeafObject::RuntimeTypeIndex());
+  EXPECT_EQ(info->type_depth, 1);
+  EXPECT_EQ(info->type_ancestors[0]->type_index, Object::RuntimeTypeIndex());
+  EXPECT_GE(info->type_index, TypeIndex::kTVMFFIDynObjectBegin);
+}
+
 TEST(Object, InstanceCheck) {
   ObjectPtr<Object> a = make_object<TIntObj>(11);
   ObjectPtr<Object> b = make_object<TFloatObj>(11);

Reply via email to