[cfe-dev] How to correlate macro expansions with AST nodes?

David Rector via cfe-dev cfe-dev at lists.llvm.org
Sun Jan 9 08:51:18 PST 2022


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.

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:

```
class ASTContext {
  ...
  bool AnyAllocateCallbacks;
  … DeclAllocateCallbacks; //a DeclVisitor or chain of them a la PPCallbacks
  … TypeAllocateCallbacks; //a TypeVisitor “"
  … StmtAllocateCallbacks; //a StmtVisitor “"

public:
  template<typename T, typename = std::enable_if_t<std::is_base_of_v<Decl, T>>>
  void DispatchAllocateCallback(T *D) {
    if (DeclAllocateCallbacks)
      DeclAllocateCallbacks->Visit(D);
  }
  //…Same for Type, Stmt

  void DispatchAllocateCallback(
  template <typename T> T *Allocate(size_t Num = 1) const {
    T *res = static_cast<T *>(Allocate(Num * sizeof(T), alignof(T)));
    DispatchAllocateCallbacks(res);
    return res;
  }
};
```
An ASTConsumer would add its Decl/Type/StmtAllocateCallbacks via some ASTConsumer::handle* virtual method called before parsing, i.e. same way it would add PPCallbacks.

I can’t imagine this would add noticeably to compilation times when there are no callbacks defined, but that would be the key measurement.

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.

More importantly, this would be a big step toward e.g. enabling ASTMatchers to work *during* parsing, for consumers that wanted to see e.g. Sema or Parser state info at the time the node was created.  Maybe doing that would even be trivial — if it were, then you could use your old solution and IdentifierInfo::hasMacroDefinitinion/Preprocessor::isMacroDefined.

Worth a shot?

> On Jan 8, 2022, at 7:37 PM, Richard via cfe-dev <cfe-dev at lists.llvm.org> wrote:
> 
> #
> Hi Team,
> 
> If I'm writing a clang-tidy check that focuses on replacing macros
> with a more suitable modern construct, it's easy to analyze the macro
> definitions by using the PP callbacks.  From the callbacks I can also
> monitor the macro expansions, but the callback only gives me a
> SourceRange for the expansion.
> 
> Is there a way I can correlate the SourceRange to the appropriate
> nodes in the AST for further analysis?
> 
> Thanks,
> -- Richard
> 
> -- 
> "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/209383ff/attachment.html>


More information about the cfe-dev mailing list