diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index ec969b42c6ae4..eadf167dcefe2 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -311,10 +311,10 @@ AST_MATCHER_P(clang::Stmt, isExpandedFromMacro, llvm::StringRef, MacroName) { // Verifies that the statement' beginning and ending are both expanded from // the same instance of the given macro. auto& Context = Finder->getASTContext(); - auto B = + llvm::Optional B = internal::getExpansionLocOfMacro(MacroName, Node.getBeginLoc(), Context); if (!B) return false; - auto E = + llvm::Optional E = internal::getExpansionLocOfMacro(MacroName, Node.getEndLoc(), Context); if (!E) return false; return *B == *E; diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp index 53f6e1d1d2788..e8f06358b9321 100644 --- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp +++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp @@ -603,22 +603,23 @@ static bool isTokenAtLoc(const SourceManager &SM, const LangOptions &LangOpts, bool Invalid = false; // Since `Loc` may point into an expansion buffer, which has no corresponding // source, we need to look at the spelling location to read the actual source. - StringRef TokenText = clang::Lexer::getSpelling( - SM.getSpellingLoc(Loc), Buffer, SM, LangOpts, &Invalid); + StringRef TokenText = Lexer::getSpelling(SM.getSpellingLoc(Loc), Buffer, SM, + LangOpts, &Invalid); return !Invalid && Text == TokenText; } llvm::Optional getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc, const ASTContext &Context) { - auto& SM = Context.getSourceManager(); - const auto& LangOpts = Context.getLangOpts(); + auto &SM = Context.getSourceManager(); + const LangOptions &LangOpts = Context.getLangOpts(); while (Loc.isMacroID()) { - auto Expansion = SM.getSLocEntry(SM.getFileID(Loc)).getExpansion(); + SrcMgr::ExpansionInfo Expansion = + SM.getSLocEntry(SM.getFileID(Loc)).getExpansion(); if (Expansion.isMacroArgExpansion()) // Check macro argument for an expansion of the given macro. For example, // `F(G(3))`, where `MacroName` is `G`. - if (auto ArgLoc = getExpansionLocOfMacro( + if (llvm::Optional ArgLoc = getExpansionLocOfMacro( MacroName, Expansion.getSpellingLoc(), Context)) return ArgLoc; Loc = Expansion.getExpansionLocStart(); diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp index 2d6ce84b13ff7..4b9fce9e3107c 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -99,6 +99,15 @@ TEST(IsExpandedFromMacro, ShouldMatchObjectMacro) { EXPECT_TRUE(matches(input, binaryOperator(isExpandedFromMacro("PLUS")))); } +TEST(IsExpandedFromMacro, ShouldMatchFromCommandLine) { + std::string input = R"cc( + void Test() { FOUR_PLUS_FOUR; } + )cc"; + EXPECT_TRUE(matchesConditionally(input, + binaryOperator(isExpandedFromMacro("FOUR_PLUS_FOUR")), + true, {"-std=c++11", "-DFOUR_PLUS_FOUR=4+4"})); +} + TEST(IsExpandedFromMacro, ShouldNotMatchBeginOnly) { std::string input = R"cc( #define ONE_PLUS 1+