diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 395da768f7c322..922f49c453e15d 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -971,6 +971,8 @@ AST Matchers - Ensure ``hasName`` matches template specializations across inline namespaces, making `matchesNodeFullSlow` and `matchesNodeFullFast` consistent. +- Improved the performance of the ``getExpansionLocOfMacro`` by tracking already processed macros during recursion. + - Add ``exportDecl`` matcher to match export declaration. clang-format diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp index cdbdb65195409f..84a7fa4d36b480 100644 --- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp +++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp @@ -21,6 +21,7 @@ #include "clang/Basic/LLVM.h" #include "clang/Lex/Lexer.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" @@ -697,20 +698,27 @@ static bool isTokenAtLoc(const SourceManager &SM, const LangOptions &LangOpts, return !Invalid && Text == TokenText; } -std::optional -getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc, - const ASTContext &Context) { +static std::optional getExpansionLocOfMacroRecursive( + StringRef MacroName, SourceLocation Loc, const ASTContext &Context, + llvm::DenseSet &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 ArgLoc = getExpansionLocOfMacro( - MacroName, Expansion.getSpellingLoc(), Context)) + if (std::optional ArgLoc = + getExpansionLocOfMacroRecursive(MacroName, + Expansion.getSpellingLoc(), + Context, CheckedLocations)) { return ArgLoc; + } + } Loc = Expansion.getExpansionLocStart(); if (isTokenAtLoc(SM, LangOpts, MacroName, Loc)) return Loc; @@ -718,6 +726,14 @@ getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc, return std::nullopt; } +std::optional +getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc, + const ASTContext &Context) { + llvm::DenseSet CheckedLocations; + return getExpansionLocOfMacroRecursive(MacroName, Loc, Context, + CheckedLocations); +} + std::shared_ptr createAndVerifyRegex(StringRef Regex, llvm::Regex::RegexFlags Flags, StringRef MatcherID) {