[clang] [ASTMatcher] Fix redundant macro expansion checks in getExpansionLocOfMacro (PR #117143)

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Tue Nov 26 05:28:20 PST 2024


================
@@ -697,27 +698,61 @@ static bool isTokenAtLoc(const SourceManager &SM, const LangOptions &LangOpts,
   return !Invalid && Text == TokenText;
 }
 
-std::optional<SourceLocation>
-getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc,
-                       const ASTContext &Context) {
+namespace {
+struct SourceLocationHash {
+  std::size_t operator()(const SourceLocation &Loc) const {
+    return Loc.getHashValue();
+  }
+};
+
+struct SourceLocationEqual {
+  bool operator()(const SourceLocation &LHS, const SourceLocation &RHS) const {
+    return LHS == RHS;
+  }
+};
+
+} // namespace
+
+static std::optional<SourceLocation> getExpansionLocOfMacroRecursive(
+    StringRef MacroName, SourceLocation Loc, const ASTContext &Context,
+    std::unordered_set<SourceLocation, SourceLocationHash, SourceLocationEqual>
+        &CheckedLocations) {
   auto &SM = Context.getSourceManager();
   const LangOptions &LangOpts = Context.getLangOpts();
   while (Loc.isMacroID()) {
+    if (CheckedLocations.count(Loc)) {
+      return std::nullopt;
+    }
+    CheckedLocations.insert(Loc);
     SrcMgr::ExpansionInfo Expansion =
         SM.getSLocEntry(SM.getFileID(Loc)).getExpansion();
-    if (Expansion.isMacroArgExpansion())
+    if (Expansion.isMacroArgExpansion()) {
       // Check macro argument for an expansion of the given macro. For example,
       // `F(G(3))`, where `MacroName` is `G`.
-      if (std::optional<SourceLocation> ArgLoc = getExpansionLocOfMacro(
-              MacroName, Expansion.getSpellingLoc(), Context))
+      if (std::optional<SourceLocation> ArgLoc =
+              getExpansionLocOfMacroRecursive(MacroName,
+                                              Expansion.getSpellingLoc(),
+                                              Context, CheckedLocations)) {
         return ArgLoc;
+      }
+    }
     Loc = Expansion.getExpansionLocStart();
-    if (isTokenAtLoc(SM, LangOpts, MacroName, Loc))
+    if (isTokenAtLoc(SM, LangOpts, MacroName, Loc)) {
       return Loc;
+    }
----------------
AaronBallman wrote:

```suggestion
    if (isTokenAtLoc(SM, LangOpts, MacroName, Loc))
      return Loc;
```

https://github.com/llvm/llvm-project/pull/117143


More information about the cfe-commits mailing list