<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Jan 9, 2022, at 4:06 PM, Richard via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" class="">cfe-dev@lists.llvm.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">[Please reply *only* to the list and do not include my email directly<br class="">in the To: or Cc: of your reply; otherwise I will not see your reply.<br class=""><br class="">Thanks.]<br class=""><br class="">In article <<a href="mailto:00DEDF73-162C-4EA7-93D3-90D3ED411F42@gmail.com" class="">00DEDF73-162C-4EA7-93D3-90D3ED411F42@gmail.com</a>>,<br class="">    David Rector via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" class="">cfe-dev@lists.llvm.org</a>> writes:<br class=""><br class=""><blockquote type="cite" class="">As you're aware there's no map from source locations to AST nodes, nor<br class="">would that be a good use of memory in general; and while you could manually<br class="">search the AST I suppose, that is a lot of work, given that you'd have to<br class="">look at nodes in the right order etc.<br class=""></blockquote><br class="">I was thinking of writing an ASTVisitor.  At the moment I'm playing<br class="">around with a matcher for TranslationUnitDecl(); is there an AST node<br class="">at a higher level than that?<br class=""><br class=""></div></div></blockquote><div>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.</div><div>This is probably the most efficient way to write it:</div><div><br class=""></div><div>```</div><div><font face="Menlo" class="">/// Finds the outermost declaration whose getBeginLoc() matches SearchLoc.</font></div><div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><font face="Menlo" class="">struct FindOuterDeclFromBeginLoc : RecursiveASTVisitor<FindOuterDeclFromBeginLoc> {</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><font face="Menlo" class="">  SourceLocation SearchLoc; //initialize from ctor</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><font face="Menlo" class="">  Decl *Res = nullptr;</font></div><p style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class=""><font face="Menlo" class="">  </font></p><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><font face="Menlo" class="">  static bool LocIsBetween(SourceLocation Loc, SourceLocation Begin, SourceLocation End) {…}</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class=""><font face="Menlo" class=""><br class=""></font></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><font face="Menlo" class="">  bool TraverseDecl(Decl *D) {</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><font face="Menlo" class="">    if (D->getBeginLoc() == SearchLoc) {</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><font face="Menlo" class="">      Res = D;</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><font face="Menlo" class="">      return false; // We’re done, halt traversal</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><font face="Menlo" class="">    }</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><font face="Menlo" class="">    if (!LocIsBetween(MacroSourceLoc, D->getBeginLoc(), D->getEndLoc())</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><font face="Menlo" class="">      return true; // Don’t traverse children, but don’t halt traversal</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><font face="Menlo" class=""><br class=""></font></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><font face="Menlo" class="">    </font><span style="font-family: Menlo;" class=""> </span><span style="font-family: Menlo;" class="">// Traverse children</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><font face="Menlo" class="">    return </font><span style="font-family: Menlo;" class="">RecursiveASTVisitor<FindOuterDeclFromBeginLoc></span><font face="Menlo" class="">::TraverseDecl(D);</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><font face="Menlo" class="">  }</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><font face="Menlo" class="">};</font></div></div><div>```</div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><blockquote type="cite" class="">So having exhausted the alternatives let's consider what I think is the<br class="">``right'' way to do it, given that this could be very helpful in other<br class="">tools too: introduce a handle for ASTConsumers to call during<br class="">ASTContext::Allocate<T>().  Something like this:<br class="">[...]<br class="">Then, for your case I *think* you could just keep track of the last macro<br class="">expansion, and the last Decl/Type/StmtAllocateCallbacks, and just check if<br class="">their source locations match --- probably a little more complexity<br class="">involved, but not more than any other solution.<br class=""></blockquote><br class="">That's an interesting idea.  In my case, I don't think it's essential<br class="">that I be able to examine the nodes during parsing, but it feels like<br class="">less work than building the entire AST and visiting it after the fact.<br class=""></div></div></blockquote><div><br class=""></div><div>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.</div><div><br class=""></div><div>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.</div><div><br class=""></div><div>Still though, I think introducing these handles would be a huge step forward for AST tooling.</div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><br class=""><blockquote type="cite" class="">Worth a shot?<br class=""></blockquote><br class="">I'm going to prototype something with the existing matching framework<br class="">first and see how poorly that performs.<br class=""><br class="">For context, this is what I'm working on:<br class="">Create modernize-enum-from-macros check<br class=""><<a href="https://github.com/llvm/llvm-project/issues/27408" class="">https://github.com/llvm/llvm-project/issues/27408</a>><br class=""><br class="">I'm less concerned about "torture" cases and more concerned with<br class="">common cases that occur in normal code.  Anything that helps migrate<br class="">away from macros (particularly now that modules are in C++20) is<br class="">useful.<br class="">-- <br class="">"The Direct3D Graphics Pipeline" free book <<a href="http://tinyurl.com/d3d-pipeline" class="">http://tinyurl.com/d3d-pipeline</a>><br class="">            The Terminals Wiki <<a href="http://terminals-wiki.org" class="">http://terminals-wiki.org</a>><br class="">     The Computer Graphics Museum <<a href="http://ComputerGraphicsMuseum.org" class="">http://ComputerGraphicsMuseum.org</a>><br class="">  Legalize Adulthood! (my blog) <<a href="http://LegalizeAdulthood.wordpress.com" class="">http://LegalizeAdulthood.wordpress.com</a>><br class="">_______________________________________________<br class="">cfe-dev mailing list<br class=""><a href="mailto:cfe-dev@lists.llvm.org" class="">cfe-dev@lists.llvm.org</a><br class="">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev<br class=""></div></div></blockquote></div><br class=""></body></html>