r305022 - [ASTMatchers] Add clang-query support for equals matcher

Peter Wu via cfe-commits cfe-commits at lists.llvm.org
Thu Jun 8 15:00:59 PDT 2017


Author: lekensteyn
Date: Thu Jun  8 17:00:58 2017
New Revision: 305022

URL: http://llvm.org/viewvc/llvm-project?rev=305022&view=rev
Log:
[ASTMatchers] Add clang-query support for equals matcher

Summary:
This allows the clang-query tool to use matchers like
"integerLiteral(equals(32))". For this to work, an overloaded function
is added for each possible parameter type.

Reviewed By: aaron.ballman

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

Modified:
    cfe/trunk/docs/LibASTMatchersReference.html
    cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
    cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
    cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp

Modified: cfe/trunk/docs/LibASTMatchersReference.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LibASTMatchersReference.html?rev=305022&r1=305021&r2=305022&view=diff
==============================================================================
--- cfe/trunk/docs/LibASTMatchersReference.html (original)
+++ cfe/trunk/docs/LibASTMatchersReference.html Thu Jun  8 17:00:58 2017
@@ -1859,17 +1859,36 @@ Example matches a || b (matcher = binary
 </pre></td></tr>
 
 
-<tr><td>Matcher<CXXBoolLiteral></td><td class="name" onclick="toggle('equals2')"><a name="equals2Anchor">equals</a></td><td>ValueT  Value</td></tr>
-<tr><td colspan="4" class="doc" id="equals2"><pre>Matches literals that are equal to the given value.
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXBoolLiteralExpr.html">CXXBoolLiteralExpr</a>></td><td class="name" onclick="toggle('equals2')"><a name="equals2Anchor">equals</a></td><td>ValueT  Value</td></tr>
+<tr><td colspan="4" class="doc" id="equals2"><pre>Matches literals that are equal to the given value of type ValueT.
 
-Example matches true (matcher = cxxBoolLiteral(equals(true)))
-  true
+Given
+  f('false, 3.14, 42);
+characterLiteral(equals(0))
+  matches 'cxxBoolLiteral(equals(false)) and cxxBoolLiteral(equals(0))
+  match false
+floatLiteral(equals(3.14)) and floatLiteral(equals(314e-2))
+  match 3.14
+integerLiteral(equals(42))
+  matches 42
 
-Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>>, Matcher<CXXBoolLiteral>,
+Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXBoolLiteralExpr.html">CXXBoolLiteralExpr</a>>,
            Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>>
 </pre></td></tr>
 
 
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXBoolLiteralExpr.html">CXXBoolLiteralExpr</a>></td><td class="name" onclick="toggle('equals5')"><a name="equals5Anchor">equals</a></td><td>bool Value</td></tr>
+<tr><td colspan="4" class="doc" id="equals5"><pre></pre></td></tr>
+
+
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXBoolLiteralExpr.html">CXXBoolLiteralExpr</a>></td><td class="name" onclick="toggle('equals11')"><a name="equals11Anchor">equals</a></td><td>double Value</td></tr>
+<tr><td colspan="4" class="doc" id="equals11"><pre></pre></td></tr>
+
+
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXBoolLiteralExpr.html">CXXBoolLiteralExpr</a>></td><td class="name" onclick="toggle('equals8')"><a name="equals8Anchor">equals</a></td><td>unsigned Value</td></tr>
+<tr><td colspan="4" class="doc" id="equals8"><pre></pre></td></tr>
+
+
 <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXCatchStmt.html">CXXCatchStmt</a>></td><td class="name" onclick="toggle('isCatchAll0')"><a name="isCatchAll0Anchor">isCatchAll</a></td><td></td></tr>
 <tr><td colspan="4" class="doc" id="isCatchAll0"><pre>Matches a C++ catch statement that has a catch-all handler.
 
@@ -2296,16 +2315,35 @@ Example: matches the implicit cast aroun
 
 
 <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>></td><td class="name" onclick="toggle('equals3')"><a name="equals3Anchor">equals</a></td><td>ValueT  Value</td></tr>
-<tr><td colspan="4" class="doc" id="equals3"><pre>Matches literals that are equal to the given value.
+<tr><td colspan="4" class="doc" id="equals3"><pre>Matches literals that are equal to the given value of type ValueT.
 
-Example matches true (matcher = cxxBoolLiteral(equals(true)))
-  true
+Given
+  f('false, 3.14, 42);
+characterLiteral(equals(0))
+  matches 'cxxBoolLiteral(equals(false)) and cxxBoolLiteral(equals(0))
+  match false
+floatLiteral(equals(3.14)) and floatLiteral(equals(314e-2))
+  match 3.14
+integerLiteral(equals(42))
+  matches 42
 
-Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>>, Matcher<CXXBoolLiteral>,
+Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXBoolLiteralExpr.html">CXXBoolLiteralExpr</a>>,
            Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>>
 </pre></td></tr>
 
 
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>></td><td class="name" onclick="toggle('equals4')"><a name="equals4Anchor">equals</a></td><td>bool Value</td></tr>
+<tr><td colspan="4" class="doc" id="equals4"><pre></pre></td></tr>
+
+
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>></td><td class="name" onclick="toggle('equals10')"><a name="equals10Anchor">equals</a></td><td>double Value</td></tr>
+<tr><td colspan="4" class="doc" id="equals10"><pre></pre></td></tr>
+
+
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>></td><td class="name" onclick="toggle('equals7')"><a name="equals7Anchor">equals</a></td><td>unsigned Value</td></tr>
+<tr><td colspan="4" class="doc" id="equals7"><pre></pre></td></tr>
+
+
 <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>></td><td class="name" onclick="toggle('templateArgumentCountIs0')"><a name="templateArgumentCountIs0Anchor">templateArgumentCountIs</a></td><td>unsigned N</td></tr>
 <tr><td colspan="4" class="doc" id="templateArgumentCountIs0"><pre>Matches if the number of template arguments equals N.
 
@@ -2533,16 +2571,27 @@ fieldDecl(isBitField())
 
 
 <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>></td><td class="name" onclick="toggle('equals1')"><a name="equals1Anchor">equals</a></td><td>ValueT  Value</td></tr>
-<tr><td colspan="4" class="doc" id="equals1"><pre>Matches literals that are equal to the given value.
+<tr><td colspan="4" class="doc" id="equals1"><pre>Matches literals that are equal to the given value of type ValueT.
 
-Example matches true (matcher = cxxBoolLiteral(equals(true)))
-  true
+Given
+  f('false, 3.14, 42);
+characterLiteral(equals(0))
+  matches 'cxxBoolLiteral(equals(false)) and cxxBoolLiteral(equals(0))
+  match false
+floatLiteral(equals(3.14)) and floatLiteral(equals(314e-2))
+  match 3.14
+integerLiteral(equals(42))
+  matches 42
 
-Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>>, Matcher<CXXBoolLiteral>,
+Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXBoolLiteralExpr.html">CXXBoolLiteralExpr</a>>,
            Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>>
 </pre></td></tr>
 
 
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>></td><td class="name" onclick="toggle('equals12')"><a name="equals12Anchor">equals</a></td><td>double Value</td></tr>
+<tr><td colspan="4" class="doc" id="equals12"><pre></pre></td></tr>
+
+
 <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>></td><td class="name" onclick="toggle('hasDynamicExceptionSpec0')"><a name="hasDynamicExceptionSpec0Anchor">hasDynamicExceptionSpec</a></td><td></td></tr>
 <tr><td colspan="4" class="doc" id="hasDynamicExceptionSpec0"><pre>Matches functions that have a dynamic exception specification.
 
@@ -2805,16 +2854,35 @@ functionProtoType(parameterCountIs(3))
 
 
 <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>></td><td class="name" onclick="toggle('equals0')"><a name="equals0Anchor">equals</a></td><td>ValueT  Value</td></tr>
-<tr><td colspan="4" class="doc" id="equals0"><pre>Matches literals that are equal to the given value.
+<tr><td colspan="4" class="doc" id="equals0"><pre>Matches literals that are equal to the given value of type ValueT.
 
-Example matches true (matcher = cxxBoolLiteral(equals(true)))
-  true
+Given
+  f('false, 3.14, 42);
+characterLiteral(equals(0))
+  matches 'cxxBoolLiteral(equals(false)) and cxxBoolLiteral(equals(0))
+  match false
+floatLiteral(equals(3.14)) and floatLiteral(equals(314e-2))
+  match 3.14
+integerLiteral(equals(42))
+  matches 42
 
-Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>>, Matcher<CXXBoolLiteral>,
+Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXBoolLiteralExpr.html">CXXBoolLiteralExpr</a>>,
            Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>>
 </pre></td></tr>
 
 
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>></td><td class="name" onclick="toggle('equals6')"><a name="equals6Anchor">equals</a></td><td>bool Value</td></tr>
+<tr><td colspan="4" class="doc" id="equals6"><pre></pre></td></tr>
+
+
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>></td><td class="name" onclick="toggle('equals13')"><a name="equals13Anchor">equals</a></td><td>double Value</td></tr>
+<tr><td colspan="4" class="doc" id="equals13"><pre></pre></td></tr>
+
+
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>></td><td class="name" onclick="toggle('equals9')"><a name="equals9Anchor">equals</a></td><td>unsigned Value</td></tr>
+<tr><td colspan="4" class="doc" id="equals9"><pre></pre></td></tr>
+
+
 <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>></td><td class="name" onclick="toggle('isArrow0')"><a name="isArrow0Anchor">isArrow</a></td><td></td></tr>
 <tr><td colspan="4" class="doc" id="isArrow0"><pre>Matches member expressions that are called with '->' as opposed
 to '.'.

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=305022&r1=305021&r2=305022&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Thu Jun  8 17:00:58 2017
@@ -3806,14 +3806,22 @@ AST_MATCHER_P(CompoundStmt, statementCou
   return Node.size() == N;
 }
 
-/// \brief Matches literals that are equal to the given value.
+/// \brief Matches literals that are equal to the given value of type ValueT.
 ///
-/// Example matches true (matcher = cxxBoolLiteral(equals(true)))
+/// Given
 /// \code
-///   true
+///   f('\0', false, 3.14, 42);
 /// \endcode
+/// characterLiteral(equals(0))
+///   matches '\0'
+/// cxxBoolLiteral(equals(false)) and cxxBoolLiteral(equals(0))
+///   match false
+/// floatLiteral(equals(3.14)) and floatLiteral(equals(314e-2))
+///   match 3.14
+/// integerLiteral(equals(42))
+///   matches 42
 ///
-/// Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteral>,
+/// Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteralExpr>,
 ///            Matcher<FloatingLiteral>, Matcher<IntegerLiteral>
 template <typename ValueT>
 internal::PolymorphicMatcherWithParam1<internal::ValueEqualsMatcher, ValueT>
@@ -3823,6 +3831,34 @@ equals(const ValueT &Value) {
     ValueT>(Value);
 }
 
+AST_POLYMORPHIC_MATCHER_P_OVERLOAD(equals,
+                          AST_POLYMORPHIC_SUPPORTED_TYPES(CharacterLiteral,
+                                                          CXXBoolLiteralExpr,
+                                                          IntegerLiteral),
+                          bool, Value, 0) {
+  return internal::ValueEqualsMatcher<NodeType, ParamT>(Value)
+    .matchesNode(Node);
+}
+
+AST_POLYMORPHIC_MATCHER_P_OVERLOAD(equals,
+                          AST_POLYMORPHIC_SUPPORTED_TYPES(CharacterLiteral,
+                                                          CXXBoolLiteralExpr,
+                                                          IntegerLiteral),
+                          unsigned, Value, 1) {
+  return internal::ValueEqualsMatcher<NodeType, ParamT>(Value)
+    .matchesNode(Node);
+}
+
+AST_POLYMORPHIC_MATCHER_P_OVERLOAD(equals,
+                          AST_POLYMORPHIC_SUPPORTED_TYPES(CharacterLiteral,
+                                                          CXXBoolLiteralExpr,
+                                                          FloatingLiteral,
+                                                          IntegerLiteral),
+                          double, Value, 2) {
+  return internal::ValueEqualsMatcher<NodeType, ParamT>(Value)
+    .matchesNode(Node);
+}
+
 /// \brief Matches the operator Name of operator expressions (binary or
 /// unary).
 ///

Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp?rev=305022&r1=305021&r2=305022&view=diff
==============================================================================
--- cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp (original)
+++ cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp Thu Jun  8 17:00:58 2017
@@ -56,20 +56,24 @@ void RegistryMaps::registerMatcher(
   registerMatcher(#name, internal::makeMatcherAutoMarshall(                    \
                              ::clang::ast_matchers::name, #name));
 
+#define REGISTER_MATCHER_OVERLOAD(name)                                        \
+  registerMatcher(#name,                                                       \
+      llvm::make_unique<internal::OverloadedMatcherDescriptor>(name##Callbacks))
+
 #define SPECIFIC_MATCHER_OVERLOAD(name, Id)                                    \
   static_cast<::clang::ast_matchers::name##_Type##Id>(                         \
       ::clang::ast_matchers::name)
 
+#define MATCHER_OVERLOAD_ENTRY(name, Id)                                       \
+        internal::makeMatcherAutoMarshall(SPECIFIC_MATCHER_OVERLOAD(name, Id), \
+                                          #name)
+
 #define REGISTER_OVERLOADED_2(name)                                            \
   do {                                                                         \
-    std::unique_ptr<MatcherDescriptor> Callbacks[] = {                         \
-        internal::makeMatcherAutoMarshall(SPECIFIC_MATCHER_OVERLOAD(name, 0),  \
-                                          #name),                              \
-        internal::makeMatcherAutoMarshall(SPECIFIC_MATCHER_OVERLOAD(name, 1),  \
-                                          #name)};                             \
-    registerMatcher(                                                           \
-        #name,                                                                 \
-        llvm::make_unique<internal::OverloadedMatcherDescriptor>(Callbacks));  \
+    std::unique_ptr<MatcherDescriptor> name##Callbacks[] = {                   \
+        MATCHER_OVERLOAD_ENTRY(name, 0),                                       \
+        MATCHER_OVERLOAD_ENTRY(name, 1)};                                      \
+    REGISTER_MATCHER_OVERLOAD(name);                                           \
   } while (0)
 
 /// \brief Generate a registry map with all the known matchers.
@@ -83,7 +87,6 @@ RegistryMaps::RegistryMaps() {
   // findAll
   //
   // Other:
-  // equals
   // equalsNode
 
   REGISTER_OVERLOADED_2(callee);
@@ -96,6 +99,13 @@ RegistryMaps::RegistryMaps() {
   REGISTER_OVERLOADED_2(references);
   REGISTER_OVERLOADED_2(thisPointerType);
 
+  std::unique_ptr<MatcherDescriptor> equalsCallbacks[] = {
+      MATCHER_OVERLOAD_ENTRY(equals, 0),
+      MATCHER_OVERLOAD_ENTRY(equals, 1),
+      MATCHER_OVERLOAD_ENTRY(equals, 2),
+  };
+  REGISTER_MATCHER_OVERLOAD(equals);
+
   REGISTER_MATCHER(accessSpecDecl);
   REGISTER_MATCHER(addrLabelExpr);
   REGISTER_MATCHER(alignOfExpr);

Modified: cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp?rev=305022&r1=305021&r2=305022&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp Thu Jun  8 17:00:58 2017
@@ -511,6 +511,46 @@ TEST_F(RegistryTest, ParenExpr) {
   EXPECT_FALSE(matches("int i = 1;", Value));
 }
 
+TEST_F(RegistryTest, EqualsMatcher) {
+  Matcher<Stmt> BooleanStmt = constructMatcher(
+      "cxxBoolLiteral", constructMatcher("equals", VariantValue(true)))
+      .getTypedMatcher<Stmt>();
+  EXPECT_TRUE(matches("bool x = true;", BooleanStmt));
+  EXPECT_FALSE(matches("bool x = false;", BooleanStmt));
+  EXPECT_FALSE(matches("bool x = 0;", BooleanStmt));
+
+  BooleanStmt = constructMatcher(
+      "cxxBoolLiteral", constructMatcher("equals", VariantValue(0)))
+      .getTypedMatcher<Stmt>();
+  EXPECT_TRUE(matches("bool x = false;", BooleanStmt));
+  EXPECT_FALSE(matches("bool x = true;", BooleanStmt));
+  EXPECT_FALSE(matches("bool x = 0;", BooleanStmt));
+
+  Matcher<Stmt> DoubleStmt = constructMatcher(
+      "floatLiteral", constructMatcher("equals", VariantValue(1.2)))
+      .getTypedMatcher<Stmt>();
+  EXPECT_TRUE(matches("double x = 1.2;", DoubleStmt));
+  EXPECT_TRUE(matches("double x = 1.2f;", DoubleStmt));
+  EXPECT_TRUE(matches("double x = 1.2l;", DoubleStmt));
+  EXPECT_TRUE(matches("double x = 12e-1;", DoubleStmt));
+  EXPECT_FALSE(matches("double x = 1.23;", DoubleStmt));
+
+  Matcher<Stmt> IntegerStmt = constructMatcher(
+      "integerLiteral", constructMatcher("equals", VariantValue(42)))
+      .getTypedMatcher<Stmt>();
+  EXPECT_TRUE(matches("int x = 42;", IntegerStmt));
+  EXPECT_FALSE(matches("int x = 1;", IntegerStmt));
+
+  Matcher<Stmt> CharStmt = constructMatcher(
+      "characterLiteral", constructMatcher("equals", VariantValue('x')))
+      .getTypedMatcher<Stmt>();
+  EXPECT_TRUE(matches("int x = 'x';", CharStmt));
+  EXPECT_TRUE(matches("int x = L'x';", CharStmt));
+  EXPECT_TRUE(matches("int x = u'x';", CharStmt));
+  EXPECT_TRUE(matches("int x = U'x';", CharStmt));
+  EXPECT_FALSE(matches("int x = 120;", CharStmt));
+}
+
 } // end anonymous namespace
 } // end namespace dynamic
 } // end namespace ast_matchers




More information about the cfe-commits mailing list