Author: mandymi Date: 2024-12-03T11:22:56-05:00 New Revision: c9fbabfdc92f12b2b0148762e6e789157a172e4d
URL: https://github.com/llvm/llvm-project/commit/c9fbabfdc92f12b2b0148762e6e789157a172e4d DIFF: https://github.com/llvm/llvm-project/commit/c9fbabfdc92f12b2b0148762e6e789157a172e4d.diff LOG: [ASTMatcher] Fix redundant macro expansion checks in getExpansionLocOfMacro (#117143) A performance issue was descibed in #114521 **Root Cause**: The function getExpansionLocOfMacro is responsible for finding the expansion location of macros. When dealing with macro parameters, it recursively calls itself to check the expansion of macro arguments. This recursive logic redundantly checks previous macro expansions, leading to significant performance degradation when macros are heavily nested. Solution **Modification**: Track already processed macros during recursion. Implementation Details: Introduced a data structure to record processed macros. Before each recursive call, check if the macro has already been processed to avoid redundant calculations. **Testing**: 1. refer to #114521 Finder->addMatcher(expr(isExpandedFromMacro("NULL")).bind("E"), this); run clang-tidy on freecad/src/Mod/Path/App/AreaPyImp.cpp clang-tidy src/Mod/Path/App/AreaPyImp.cpp -checks=-*,testchecker -p=build/compile_commands.json checker runs normally 2. check-clang-unit pass Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/ASTMatchers/ASTMatchersInternal.cpp Removed: ################################################################################ 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<SourceLocation> -getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc, - const ASTContext &Context) { +static std::optional<SourceLocation> getExpansionLocOfMacroRecursive( + StringRef MacroName, SourceLocation Loc, const ASTContext &Context, + llvm::DenseSet<SourceLocation> &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)) return Loc; @@ -718,6 +726,14 @@ getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc, return std::nullopt; } +std::optional<SourceLocation> +getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc, + const ASTContext &Context) { + llvm::DenseSet<SourceLocation> CheckedLocations; + return getExpansionLocOfMacroRecursive(MacroName, Loc, Context, + CheckedLocations); +} + std::shared_ptr<llvm::Regex> createAndVerifyRegex(StringRef Regex, llvm::Regex::RegexFlags Flags, StringRef MatcherID) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits