Leandros / metareflect

Metareflect is a lightweight reflection system for C++, based on LLVM and Clangs libtooling.
https://arvid.io
MIT License
228 stars 33 forks source link

classfinder onEndOfTranslationUnit() assert failure #7

Open M-Herr opened 3 years ago

M-Herr commented 3 years ago

I've been messing around with this tool, as part of some personal research into clang and llvm. I think the reflection possibilities are really interesting and I like how it has a similar interface to UHT. Anyways I'm having an issue when I try to run the tool on a test header file, which is properly annotated.

It looks like the classfinder m_filename is never set, which results in an assert failure in the classfinder override of onEndOfTranslationUnit(). From what I've been able to gather the classfinder FoundRecord function seems to set this filename, but it never gets called. So it looks like for whatever reason the AST isn't finding matches and I cannot figure out why.

I know this is kind of a shot in the dark since this doesn't seem to be a very active repo, but I was wondering if anyone else has run into this. Thanks!

M-Herr commented 3 years ago

In case anyone happens on this, the reason AST wasn't finding matches is because this section of code:

#ifdef __METAREFLECT__
    #define CLASS(...) class __attribute__((annotate("reflect-class;" #__VA_ARGS__)))
    #define UNION(...) union __attribute__((annotate("reflect-class;" #__VA_ARGS__)))
    #define PROPERTY(...) __attribute__((annotate("reflect-property;" #__VA_ARGS__)))
    #define FUNCTION(...) __attribute__((annotate("reflect-function;" #__VA_ARGS__)))
    #define META_OBJECT
#else /* else __METAREFLECT__ */

If METAREFLECT isn't defined, then the annotate attribute isn't substituted into the code via the macro. Since nothing is found, the program throws an error code and exits.

Here's the following code block looks like

#else /* else __METAREFLECT__ */
    #define CLASS(...) class
    #define UNION(...) union
    #define PROPERTY(...)
    #define FUNCTION(...)
    #define META_OBJECT \
        friend struct PrimitiveResolver; \
        static constexpr bool IsReflected = true; \
        template<class T> \
        friend constexpr bool AfterSerialize(T *) noexcept; \
        template<class T> \
        friend constexpr bool BeforeSerialize(T *) noexcept; \
        template<class T> \
        friend metareflect::Class const *metareflect::detail::GetClassImpl(metareflect::ClassTag<T>) noexcept;
#endif /* __METAREFLECT__ */

It makes sense that the CLASS() etc macros are just defined as class or union. But I'm not sure what the purpose of the META_OBJECT macro is.

Anyways, since then I've been able to get this up and running on using llvm via vcpkg, which was quite an adventure to get building.

RussellZhou-hub commented 1 year ago

need add predefine __METAREFLECT__ in ClangTool. So when metareflect parsing test.hxx can substituted these macro into the code. at the same time, MSVC wont have __METAREFLECT__ macro when compiling main.cxx. (maybe later i will pull an request to suthor).