[cfe-dev] How to correlate macro expansions with AST nodes?
David Rector via cfe-dev
cfe-dev at lists.llvm.org
Sun Jan 9 13:38:35 PST 2022
> On Jan 9, 2022, at 4:06 PM, Richard via cfe-dev <cfe-dev at lists.llvm.org> wrote:
>
> [Please reply *only* to the list and do not include my email directly
> in the To: or Cc: of your reply; otherwise I will not see your reply.
>
> Thanks.]
>
> In article <00DEDF73-162C-4EA7-93D3-90D3ED411F42 at gmail.com>,
> David Rector via cfe-dev <cfe-dev at lists.llvm.org> writes:
>
>> As you're aware there's no map from source locations to AST nodes, nor
>> would that be a good use of memory in general; and while you could manually
>> search the AST I suppose, that is a lot of work, given that you'd have to
>> look at nodes in the right order etc.
>
> I was thinking of writing an ASTVisitor. At the moment I'm playing
> around with a matcher for TranslationUnitDecl(); is there an AST node
> at a higher level than that?
>
Yup, that’s the highest. Actually a RecursiveASTVisitor might not be so bad, so long as there are not too many locations to look up.
This is probably the most efficient way to write it:
```
/// Finds the outermost declaration whose getBeginLoc() matches SearchLoc.
struct FindOuterDeclFromBeginLoc : RecursiveASTVisitor<FindOuterDeclFromBeginLoc> {
SourceLocation SearchLoc; //initialize from ctor
Decl *Res = nullptr;
static bool LocIsBetween(SourceLocation Loc, SourceLocation Begin, SourceLocation End) {…}
bool TraverseDecl(Decl *D) {
if (D->getBeginLoc() == SearchLoc) {
Res = D;
return false; // We’re done, halt traversal
}
if (!LocIsBetween(MacroSourceLoc, D->getBeginLoc(), D->getEndLoc())
return true; // Don’t traverse children, but don’t halt traversal
// Traverse children
return RecursiveASTVisitor<FindOuterDeclFromBeginLoc>::TraverseDecl(D);
}
};
```
>> So having exhausted the alternatives let's consider what I think is the
>> ``right'' way to do it, given that this could be very helpful in other
>> tools too: introduce a handle for ASTConsumers to call during
>> ASTContext::Allocate<T>(). Something like this:
>> [...]
>> Then, for your case I *think* you could just keep track of the last macro
>> expansion, and the last Decl/Type/StmtAllocateCallbacks, and just check if
>> their source locations match --- probably a little more complexity
>> involved, but not more than any other solution.
>
> That's an interesting idea. In my case, I don't think it's essential
> that I be able to examine the nodes during parsing, but it feels like
> less work than building the entire AST and visiting it after the fact.
Now that I think about it it wouldn’t work to add the callback in ASTContext::Allocate<T>(...); many nodes allocate via a llvm::TrailingObjects base, which calls the non-typed Allocate overload, through a line like Context.Allocate(totalSizeToAlloc<…>(…)); so all of those would need special handling. Probably, the callback would need to be called in each node’s Create function, instead of in ASTContext::Allocate. Not too bad, but not as simple as before.
And it definitely wouldn’t be trivial to get ASTMatchers to work with this. Instead, a user would probably use these callbacks to simply map relevant Parser/Sema/Preprocessor state data accessed at the time of allocation to the nodes of interest, then do the real processing accessing that map during HandleTranslationUnit.
Still though, I think introducing these handles would be a huge step forward for AST tooling.
>
>> Worth a shot?
>
> I'm going to prototype something with the existing matching framework
> first and see how poorly that performs.
>
> For context, this is what I'm working on:
> Create modernize-enum-from-macros check
> <https://github.com/llvm/llvm-project/issues/27408>
>
> I'm less concerned about "torture" cases and more concerned with
> common cases that occur in normal code. Anything that helps migrate
> away from macros (particularly now that modules are in C++20) is
> useful.
> --
> "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
> The Terminals Wiki <http://terminals-wiki.org>
> The Computer Graphics Museum <http://ComputerGraphicsMuseum.org>
> Legalize Adulthood! (my blog) <http://LegalizeAdulthood.wordpress.com>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20220109/1bf4763e/attachment.html>
More information about the cfe-dev
mailing list