|
21 | 21 | #include "clang/Basic/LLVM.h" |
22 | 22 | #include "clang/Lex/Lexer.h" |
23 | 23 | #include "llvm/ADT/ArrayRef.h" |
| 24 | +#include "llvm/ADT/DenseSet.h" |
24 | 25 | #include "llvm/ADT/IntrusiveRefCntPtr.h" |
25 | 26 | #include "llvm/ADT/SmallString.h" |
26 | 27 | #include "llvm/ADT/SmallVector.h" |
@@ -697,27 +698,42 @@ static bool isTokenAtLoc(const SourceManager &SM, const LangOptions &LangOpts, |
697 | 698 | return !Invalid && Text == TokenText; |
698 | 699 | } |
699 | 700 |
|
700 | | -std::optional<SourceLocation> |
701 | | -getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc, |
702 | | - const ASTContext &Context) { |
| 701 | +static std::optional<SourceLocation> getExpansionLocOfMacroRecursive( |
| 702 | + StringRef MacroName, SourceLocation Loc, const ASTContext &Context, |
| 703 | + llvm::DenseSet<SourceLocation> &CheckedLocations) { |
703 | 704 | auto &SM = Context.getSourceManager(); |
704 | 705 | const LangOptions &LangOpts = Context.getLangOpts(); |
705 | 706 | while (Loc.isMacroID()) { |
| 707 | + if (CheckedLocations.count(Loc)) |
| 708 | + return std::nullopt; |
| 709 | + CheckedLocations.insert(Loc); |
706 | 710 | SrcMgr::ExpansionInfo Expansion = |
707 | 711 | SM.getSLocEntry(SM.getFileID(Loc)).getExpansion(); |
708 | | - if (Expansion.isMacroArgExpansion()) |
| 712 | + if (Expansion.isMacroArgExpansion()) { |
709 | 713 | // Check macro argument for an expansion of the given macro. For example, |
710 | 714 | // `F(G(3))`, where `MacroName` is `G`. |
711 | | - if (std::optional<SourceLocation> ArgLoc = getExpansionLocOfMacro( |
712 | | - MacroName, Expansion.getSpellingLoc(), Context)) |
| 715 | + if (std::optional<SourceLocation> ArgLoc = |
| 716 | + getExpansionLocOfMacroRecursive(MacroName, |
| 717 | + Expansion.getSpellingLoc(), |
| 718 | + Context, CheckedLocations)) { |
713 | 719 | return ArgLoc; |
| 720 | + } |
| 721 | + } |
714 | 722 | Loc = Expansion.getExpansionLocStart(); |
715 | 723 | if (isTokenAtLoc(SM, LangOpts, MacroName, Loc)) |
716 | 724 | return Loc; |
717 | 725 | } |
718 | 726 | return std::nullopt; |
719 | 727 | } |
720 | 728 |
|
| 729 | +std::optional<SourceLocation> |
| 730 | +getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc, |
| 731 | + const ASTContext &Context) { |
| 732 | + llvm::DenseSet<SourceLocation> CheckedLocations; |
| 733 | + return getExpansionLocOfMacroRecursive(MacroName, Loc, Context, |
| 734 | + CheckedLocations); |
| 735 | +} |
| 736 | + |
721 | 737 | std::shared_ptr<llvm::Regex> createAndVerifyRegex(StringRef Regex, |
722 | 738 | llvm::Regex::RegexFlags Flags, |
723 | 739 | StringRef MatcherID) { |
|
0 commit comments