[clang] b091af7 - [ASTMatchers] Made isExpandedFromMacro Polymorphic

Nathan James via cfe-commits cfe-commits at lists.llvm.org
Tue Nov 3 06:37:00 PST 2020


Author: Nathan James
Date: 2020-11-03T14:36:51Z
New Revision: b091af790f192c5532b59159fc029f9c368285c0

URL: https://github.com/llvm/llvm-project/commit/b091af790f192c5532b59159fc029f9c368285c0
DIFF: https://github.com/llvm/llvm-project/commit/b091af790f192c5532b59159fc029f9c368285c0.diff

LOG: [ASTMatchers] Made isExpandedFromMacro Polymorphic

Made the isExpandedFromMacro matcher work on Stmt's, TypeLocs and Decls in line with the other macro expansion matchers.
Also tweaked it to take a `std::string` instead of a `StringRef`.
This prevents potential use-after-free bugs if the matcher is created with a string thats destroyed before the matcher finishes matching.

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D90303

Added: 
    

Modified: 
    clang/docs/LibASTMatchersReference.html
    clang/include/clang/ASTMatchers/ASTMatchers.h
    clang/lib/ASTMatchers/GtestMatchers.cpp
    clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html
index e281c5d3b850..14dec7d972b3 100644
--- a/clang/docs/LibASTMatchersReference.html
+++ b/clang/docs/LibASTMatchersReference.html
@@ -3042,6 +3042,14 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
 </pre></td></tr>
 
 
+<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('isExpandedFromMacro0')"><a name="isExpandedFromMacro0Anchor">isExpandedFromMacro</a></td><td>std::string MacroName</td></tr>
+<tr><td colspan="4" class="doc" id="isExpandedFromMacro0"><pre>Matches statements that are (transitively) expanded from the named macro.
+Does not match if only part of the statement is expanded from that macro or
+if 
diff erent parts of the the statement are expanded from 
diff erent
+appearances of the macro.
+</pre></td></tr>
+
+
 <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('isExpansionInFileMatching0')"><a name="isExpansionInFileMatching0Anchor">isExpansionInFileMatching</a></td><td>StringRef RegExp, Regex::RegexFlags Flags = NoFlags</td></tr>
 <tr><td colspan="4" class="doc" id="isExpansionInFileMatching0"><pre>Matches AST nodes that were expanded within files whose name is
 partially matching a given regex.
@@ -4293,14 +4301,11 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
 </pre></td></tr>
 
 
-<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('isExpandedFromMacro0')"><a name="isExpandedFromMacro0Anchor">isExpandedFromMacro</a></td><td>llvm::StringRef MacroName</td></tr>
-<tr><td colspan="4" class="doc" id="isExpandedFromMacro0"><pre>Matches statements that are (transitively) expanded from the named macro.
+<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('isExpandedFromMacro1')"><a name="isExpandedFromMacro1Anchor">isExpandedFromMacro</a></td><td>std::string MacroName</td></tr>
+<tr><td colspan="4" class="doc" id="isExpandedFromMacro1"><pre>Matches statements that are (transitively) expanded from the named macro.
 Does not match if only part of the statement is expanded from that macro or
 if 
diff erent parts of the the statement are expanded from 
diff erent
 appearances of the macro.
-
-FIXME: Change to be a polymorphic matcher that works on any syntactic
-node. There's nothing `Stmt`-specific about it.
 </pre></td></tr>
 
 
@@ -4490,6 +4495,14 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
 </pre></td></tr>
 
 
+<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('isExpandedFromMacro2')"><a name="isExpandedFromMacro2Anchor">isExpandedFromMacro</a></td><td>std::string MacroName</td></tr>
+<tr><td colspan="4" class="doc" id="isExpandedFromMacro2"><pre>Matches statements that are (transitively) expanded from the named macro.
+Does not match if only part of the statement is expanded from that macro or
+if 
diff erent parts of the the statement are expanded from 
diff erent
+appearances of the macro.
+</pre></td></tr>
+
+
 <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('isExpansionInFileMatching2')"><a name="isExpansionInFileMatching2Anchor">isExpansionInFileMatching</a></td><td>StringRef RegExp, Regex::RegexFlags Flags = NoFlags</td></tr>
 <tr><td colspan="4" class="doc" id="isExpansionInFileMatching2"><pre>Matches AST nodes that were expanded within files whose name is
 partially matching a given regex.

diff  --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
index c535e538fe8b..73f898a08365 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -308,10 +308,9 @@ AST_POLYMORPHIC_MATCHER_REGEX(isExpansionInFileMatching,
 /// Does not match if only part of the statement is expanded from that macro or
 /// if 
diff erent parts of the the statement are expanded from 
diff erent
 /// appearances of the macro.
-///
-/// FIXME: Change to be a polymorphic matcher that works on any syntactic
-/// node. There's nothing `Stmt`-specific about it.
-AST_MATCHER_P(Stmt, isExpandedFromMacro, llvm::StringRef, MacroName) {
+AST_POLYMORPHIC_MATCHER_P(isExpandedFromMacro,
+                          AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc),
+                          std::string, MacroName) {
   // Verifies that the statement' beginning and ending are both expanded from
   // the same instance of the given macro.
   auto& Context = Finder->getASTContext();

diff  --git a/clang/lib/ASTMatchers/GtestMatchers.cpp b/clang/lib/ASTMatchers/GtestMatchers.cpp
index c99fdf6c0fcd..0e587c0c3b9f 100644
--- a/clang/lib/ASTMatchers/GtestMatchers.cpp
+++ b/clang/lib/ASTMatchers/GtestMatchers.cpp
@@ -89,14 +89,14 @@ static llvm::StringRef getExpectMacro(GtestCmp Cmp) {
 internal::BindableMatcher<Stmt> gtestAssert(GtestCmp Cmp, StatementMatcher Left,
                                             StatementMatcher Right) {
   return callExpr(callee(getComparisonDecl(Cmp)),
-                  isExpandedFromMacro(getAssertMacro(Cmp)),
+                  isExpandedFromMacro(getAssertMacro(Cmp).str()),
                   hasArgument(2, Left), hasArgument(3, Right));
 }
 
 internal::BindableMatcher<Stmt> gtestExpect(GtestCmp Cmp, StatementMatcher Left,
                                             StatementMatcher Right) {
   return callExpr(callee(getComparisonDecl(Cmp)),
-                  isExpandedFromMacro(getExpectMacro(Cmp)),
+                  isExpandedFromMacro(getExpectMacro(Cmp).str()),
                   hasArgument(2, Left), hasArgument(3, Right));
 }
 

diff  --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
index 7e53b71a50e4..d37b53e8f114 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -142,6 +142,22 @@ TEST_P(ASTMatchersTest, IsExpandedFromMacro_NotMatchesDifferentInstances) {
   EXPECT_TRUE(notMatches(input, binaryOperator(isExpandedFromMacro("FOUR"))));
 }
 
+TEST(IsExpandedFromMacro, IsExpandedFromMacro_MatchesDecls) {
+  StringRef input = R"cc(
+#define MY_MACRO(a) int i = a;
+    void Test() { MY_MACRO(4); }
+  )cc";
+  EXPECT_TRUE(matches(input, varDecl(isExpandedFromMacro("MY_MACRO"))));
+}
+
+TEST(IsExpandedFromMacro, IsExpandedFromMacro_MatchesTypelocs) {
+  StringRef input = R"cc(
+#define MY_TYPE int
+    void Test() { MY_TYPE i = 4; }
+  )cc";
+  EXPECT_TRUE(matches(input, typeLoc(isExpandedFromMacro("MY_TYPE"))));
+}
+
 TEST_P(ASTMatchersTest, AllOf) {
   const char Program[] = "struct T { };"
                          "int f(int, struct T*, int, int);"


        


More information about the cfe-commits mailing list