Author: Stephen Kelly Date: 2021-01-28T20:47:09Z New Revision: 3c79734f29284d6b54f1867a03428a3d9fd338d9
URL: https://github.com/llvm/llvm-project/commit/3c79734f29284d6b54f1867a03428a3d9fd338d9 DIFF: https://github.com/llvm/llvm-project/commit/3c79734f29284d6b54f1867a03428a3d9fd338d9.diff LOG: [ASTMatchers] Add invocation matcher Differential Revision: https://reviews.llvm.org/D94865 Added: Modified: clang/docs/LibASTMatchersReference.html clang/include/clang/ASTMatchers/ASTMatchers.h clang/lib/ASTMatchers/ASTMatchersInternal.cpp clang/lib/ASTMatchers/Dynamic/Registry.cpp clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp Removed: ################################################################################ diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html index 912da6e62c2f..ffad8acbeab6 100644 --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -5613,6 +5613,40 @@ <h2 id="traversal-matchers">AST Traversal Matchers</h2> </pre></td></tr> +<tr><td>Matcher<*></td><td class="name" onclick="toggle('invocation0')"><a name="invocation0Anchor">invocation</a></td><td>Matcher<*>...Matcher<*></td></tr> +<tr><td colspan="4" class="doc" id="invocation0"><pre>Matches function calls and constructor calls + +Because CallExpr and CXXConstructExpr do not share a common +base class with API accessing arguments etc, AST Matchers for code +which should match both are typically duplicated. This matcher +removes the need for duplication. + +Given code +struct ConstructorTakesInt +{ + ConstructorTakesInt(int i) {} +}; + +void callTakesInt(int i) +{ +} + +void doCall() +{ + callTakesInt(42); +} + +void doConstruct() +{ + ConstructorTakesInt cti(42); +} + +The matcher +invocation(hasArgument(0, integerLiteral(equals(42)))) +matches the expression in both doCall and doConstruct +</pre></td></tr> + + <tr><td>Matcher<*></td><td class="name" onclick="toggle('eachOf0')"><a name="eachOf0Anchor">eachOf</a></td><td>Matcher<*>, ..., Matcher<*></td></tr> <tr><td colspan="4" class="doc" id="eachOf0"><pre>Matches if any of the given matchers matches. diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 6f6dfab59a39..10532b3da209 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -2829,6 +2829,42 @@ extern const internal::MapAnyOfMatcher<BinaryOperator, CXXOperatorCallExpr, CXXRewrittenBinaryOperator> binaryOperation; +/// Matches function calls and constructor calls +/// +/// Because CallExpr and CXXConstructExpr do not share a common +/// base class with API accessing arguments etc, AST Matchers for code +/// which should match both are typically duplicated. This matcher +/// removes the need for duplication. +/// +/// Given code +/// \code +/// struct ConstructorTakesInt +/// { +/// ConstructorTakesInt(int i) {} +/// }; +/// +/// void callTakesInt(int i) +/// { +/// } +/// +/// void doCall() +/// { +/// callTakesInt(42); +/// } +/// +/// void doConstruct() +/// { +/// ConstructorTakesInt cti(42); +/// } +/// \endcode +/// +/// The matcher +/// \code +/// invocation(hasArgument(0, integerLiteral(equals(42)))) +/// \endcode +/// matches the expression in both doCall and doConstruct +extern const internal::MapAnyOfMatcher<CallExpr, CXXConstructExpr> invocation; + /// Matches unary expressions that have a specific type of argument. /// /// Given diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp index 6c7e14e3499a..6e36842d0660 100644 --- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp +++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp @@ -924,6 +924,7 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, BinaryOperator> const internal::MapAnyOfMatcher<BinaryOperator, CXXOperatorCallExpr, CXXRewrittenBinaryOperator> binaryOperation; +const internal::MapAnyOfMatcher<CallExpr, CXXConstructExpr> invocation; const internal::VariadicDynCastAllOfMatcher<Stmt, UnaryOperator> unaryOperator; const internal::VariadicDynCastAllOfMatcher<Stmt, ConditionalOperator> conditionalOperator; diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp index 00a7c74a0b90..9ac9593e042b 100644 --- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -358,6 +358,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(injectedClassNameType); REGISTER_MATCHER(innerType); REGISTER_MATCHER(integerLiteral); + REGISTER_MATCHER(invocation); REGISTER_MATCHER(isAllowedToContainClauseKind); REGISTER_MATCHER(isAnonymous); REGISTER_MATCHER(isAnyCharacter); diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp index d681620cf548..1c6947acf0ab 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -863,6 +863,47 @@ void opFree() mapAnyOf(unaryOperator, cxxOperatorCallExpr) .with(hasAnyOperatorName("+", "!"), forFunction(functionDecl(hasName("opFree"))))))); + + Code = R"cpp( +struct ConstructorTakesInt +{ + ConstructorTakesInt(int i) {} +}; + +void callTakesInt(int i) +{ + +} + +void doCall() +{ + callTakesInt(42); +} + +void doConstruct() +{ + ConstructorTakesInt cti(42); +} +)cpp"; + + EXPECT_TRUE(matches( + Code, traverse(TK_IgnoreUnlessSpelledInSource, + invocation(forFunction(functionDecl(hasName("doCall"))), + hasArgument(0, integerLiteral(equals(42))), + hasAnyArgument(integerLiteral(equals(42))), + forEachArgumentWithParam( + integerLiteral(equals(42)), + parmVarDecl(hasName("i"))))))); + + EXPECT_TRUE(matches( + Code, + traverse( + TK_IgnoreUnlessSpelledInSource, + invocation(forFunction(functionDecl(hasName("doConstruct"))), + hasArgument(0, integerLiteral(equals(42))), + hasAnyArgument(integerLiteral(equals(42))), + forEachArgumentWithParam(integerLiteral(equals(42)), + parmVarDecl(hasName("i"))))))); } TEST_P(ASTMatchersTest, IsDerivedFrom) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits