Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -890,6 +890,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.

clang-format
------------

Expand Down
28 changes: 22 additions & 6 deletions clang/lib/ASTMatchers/ASTMatchersInternal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -697,27 +698,42 @@ 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;
}
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) {
Expand Down