If you seek to do something different from what they’re doing, you’ll want to define two different kinds of AST Expr nodes: the first covers your entry-point reflections , i.e. the result of reflexpr(x) for various kinds of x’s (e.g. CXXReflectExpr - they define it to work with typename, template name, etc. operands); the second are queries on an existing reflection to produce another reflection or a primitive (e.g. CXXReflectionReadQueryExpr).
I recommend you do keyword searches on their code to trace how they get from the parsing of the reflexpr keyword to the final evaluation in lib/AST/ExprConstant.cpp.
The basic lifetime/processing of an AST Expression node:
[TransformXYZ(…) -> ActOnXYZ(…) while still dependent ->]
First, though, perhaps consider your goals, as I’m not 100% sure the Reflection TS is the last word on the subject of reflection — though others certainly disagree with me. Are you simply anxious to get reflection support for use in your own code? Perhaps instead look into writing your own clang tools to perform ersatz "metaprogramming" tasks (generating new source files, etc.) using "reflected" info from the AST. It’s not an ideal approach, but until all the debates are resolved surrounding reflection, it’s the most dependable and powerful approach, and there’s already plenty of support.
Best of luck,
Message: 2 Date: Wed, 22 Jan 2020 21:13:35 -0500 From: Nick Meyer via cfe-dev <[hidden email]> To: [hidden email] Subject: Re: [cfe-dev] Reflection TS Message-ID: <[hidden email]> Content-Type: text/plain; charset="utf-8"
I want to start a thread about implementing the Reflection TS in Clang.
I've been chatting a bit with Matus Chochlik about this, but I also want to get input from others on the best way to structure the code. Currently, I'm close to having the parsing for type reflection working. Right now the reflexpr keyword returns a specialized trait. My plan was to then define all the reflection traits as type traits that dispatch to an intrinsic. For value reflection, I was thinking we could follow a similar pattern except we might have to generate a type (instead of simply specializing a template) to represent the value.
I want to get input from others about this direction to see if it is reasonable or not before I go to far. This is my first time working on Clang, so not sure how these discussions typically start. Let me know if I should provide more detail on my comments above.
In reply to this post by Hans Wennborg via cfe-dev
>> First, though, perhaps consider your goals, as I’m not 100% sure the
>> Reflection TS is the last word on the subject of reflection — though
>> others certainly disagree with me.
> Just wanted to chime in on this with my 2c.
> The Reflection TS is certainly not the last word on the subject of reflection -- an improved version of reflection facilities are being worked on for a future C++ standard (such as C+23 or C++26).
> However, the purpose of the Reflection TS is to gather implementation and use experience to guide such improvements prior to final standardization.
> I think it would be very valuable to implement the Reflection TS so that we can gather such use experience.
Yes, but the reflection TS offers only a subset of possible reflection facilities (e.g. no statement/expression reflection), and so the final product after examining use cases would be some subset of that subset. And you’d have to convince implementers to implement this temporary, limited feature, and users to learn it and use it, to base your usage decisions on it.
I’ll rehash my already-implemented solution (https://github.com/drec357/clang-meta/, haven’t updated the git in awhile, but working on big fixes to be out in a month or two). This has already been debated, but just for any who haven’t seen it:
1) Straight-mirror-reflect the entire public AST interface via a clang tool run on the compiler AST headers during building of the compiler.
The result lets a person call
and, if other compilers would get onboard,
Any public const methods/fields the compiler uses in its AST nodes, the user can access in his/her constexpr functions. Current clang users could mostly copy and paste their clang tool code into constexpr metafunctions — you’d have an experienced user base right from the get go.
2) Standardize commonly used reflection type trait properties (the Reflection TS for now) into a std library that calls these builtins, the same way e.g. std::is_trivially_destructible is defined via a builtin.
You could implement the whole Reflection TS in an afternoon right now in terms of the builtins exposed by current implem — however because the clang AST API is not stable, they do not have interest in exposing the AST methods via such builtins, given that some might change over time, and so my fork is on its own.
So just like the case of the ASTMatchers thread I weighed in on earlier, the clang AST is the bottleneck, and because of its issues, the only available option is to implement a parallel architecture of reflection type traits. I.e. we have to implement yet another parallel AST to wallpaper over the inner one.
If only all these efforts — on ASTMatchers, on reflection, on all other efforts to add new AST-like code to interface with a stable, more user-friendly version of the AST, could be redirected to making the AST itself stable and more user-friendly. One could explicitly annotate just the stable parts or just the unstable/ugly parts to maintain some play; so that e.g. just the stable parts could be reflected or otherwise dependend on.
I am even considering forking clang semi-permanently just to be able to clean up the AST in this way — if there are others interested in developing a "stable AST" fork — the main job would be standardizing names, improving the documentation, factoring out helper bases, etc. — please let me know.