|
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