Lekensteyn updated this revision to Diff 98917. Lekensteyn marked 9 inline comments as done. Lekensteyn retitled this revision from "[ASTMatchers] Add equals support for integer and boolean literals" to "[ASTMatchers] Add clang-query support for equals matcher". Lekensteyn edited the summary of this revision. Lekensteyn added a comment.
v1 -> v2: - Add CharacterLiteral and FloatingLiterals support - updated documentation comment to include examples for all four supported matcher types - updated docs with dump_ast_matchers.py Depends on: - https://reviews.llvm.org/D33093 for boolean support - https://reviews.llvm.org/D33135 for float support https://reviews.llvm.org/D33094 Files: docs/LibASTMatchersReference.html include/clang/ASTMatchers/ASTMatchers.h lib/ASTMatchers/Dynamic/Registry.cpp unittests/ASTMatchers/Dynamic/RegistryTest.cpp
Index: unittests/ASTMatchers/Dynamic/RegistryTest.cpp =================================================================== --- unittests/ASTMatchers/Dynamic/RegistryTest.cpp +++ unittests/ASTMatchers/Dynamic/RegistryTest.cpp @@ -511,6 +511,41 @@ 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 = 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_FALSE(matches("int x = 120;", CharStmt)); +} + } // end anonymous namespace } // end namespace dynamic } // end namespace ast_matchers Index: lib/ASTMatchers/Dynamic/Registry.cpp =================================================================== --- lib/ASTMatchers/Dynamic/Registry.cpp +++ lib/ASTMatchers/Dynamic/Registry.cpp @@ -56,20 +56,24 @@ 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 @@ // findAll // // Other: - // equals // equalsNode REGISTER_OVERLOADED_2(callee); @@ -96,6 +99,13 @@ 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); Index: include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- include/clang/ASTMatchers/ASTMatchers.h +++ include/clang/ASTMatchers/ASTMatchers.h @@ -3806,14 +3806,22 @@ 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 @@ 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). /// Index: docs/LibASTMatchersReference.html =================================================================== --- docs/LibASTMatchersReference.html +++ docs/LibASTMatchersReference.html @@ -1859,17 +1859,36 @@ </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 @@ <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 @@ <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 @@ <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 '.'.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits