Skip to content

Commit 102fe0e

Browse files
authored
[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`
1 parent 9844079 commit 102fe0e

2 files changed

Lines changed: 27 additions & 1 deletion

File tree

include/tvm/ffi/object.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -971,7 +971,7 @@ struct ObjectPtrEqual {
971971
TypeName::_type_child_slots_can_overflow, ParentType::_GetOrAllocRuntimeTypeIndex()); \
972972
return tindex; \
973973
} \
974-
static inline const int32_t _type_index = TypeName::_GetOrAllocRuntimeTypeIndex(); \
974+
static inline const int32_t _type_index = _GetOrAllocRuntimeTypeIndex(); \
975975
TVM_FFI_INLINE static int32_t RuntimeTypeIndex() noexcept { return TypeName::_type_index; }
976976

977977
/*!

tests/cpp/test_object.cc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,23 @@ namespace {
2727
using namespace tvm::ffi;
2828
using namespace tvm::ffi::testing;
2929

30+
template <typename T>
31+
class CRTPObject : public Object {
32+
public:
33+
static constexpr int _type_child_slots [[maybe_unused]] = 0;
34+
static constexpr bool _type_final [[maybe_unused]] = true;
35+
TVM_FFI_DECLARE_OBJECT_INFO_PREDEFINED_TYPE_KEY(T, Object);
36+
37+
private:
38+
friend T;
39+
CRTPObject() = default;
40+
};
41+
42+
class LeafObject : public CRTPObject<LeafObject> {
43+
public:
44+
static constexpr const char* _type_key = "test.CRTPLeaf";
45+
};
46+
3047
TEST(Object, RefCounter) {
3148
ObjectPtr<TIntObj> a = make_object<TIntObj>(11);
3249
ObjectPtr<TIntObj> b = a;
@@ -60,6 +77,15 @@ TEST(Object, TypeInfo) {
6077
EXPECT_GE(info->type_index, TypeIndex::kTVMFFIDynObjectBegin);
6178
}
6279

80+
TEST(Object, CRTPObjectInfo) {
81+
const TypeInfo* info = TVMFFIGetTypeInfo(LeafObject::RuntimeTypeIndex());
82+
ASSERT_TRUE(info != nullptr);
83+
EXPECT_EQ(info->type_index, LeafObject::RuntimeTypeIndex());
84+
EXPECT_EQ(info->type_depth, 1);
85+
EXPECT_EQ(info->type_ancestors[0]->type_index, Object::RuntimeTypeIndex());
86+
EXPECT_GE(info->type_index, TypeIndex::kTVMFFIDynObjectBegin);
87+
}
88+
6389
TEST(Object, InstanceCheck) {
6490
ObjectPtr<Object> a = make_object<TIntObj>(11);
6591
ObjectPtr<Object> b = make_object<TFloatObj>(11);

0 commit comments

Comments
 (0)