njames93 created this revision. njames93 added reviewers: klimek, aaron.ballman, gribozavr2, alexfh. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Adds a matcher called `hasOperands` for `BinaryOperator`'s when you need to match both sides but the order isn't important, usually on commutative operators. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D80054 Files: clang/docs/LibASTMatchersReference.html clang/include/clang/ASTMatchers/ASTMatchers.h clang/lib/ASTMatchers/Dynamic/Registry.cpp clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp =================================================================== --- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -1160,6 +1160,17 @@ EXPECT_TRUE(notMatches("void x() { true || true; }", HasOperand)); } +TEST(MatchBinaryOperator, HasOperands) { + StatementMatcher HasOperands = binaryOperator( + hasOperands(integerLiteral(equals(1)), integerLiteral(equals(2)))); + EXPECT_TRUE(matches("void x() { 1 + 2; }", HasOperands)); + EXPECT_TRUE(matches("void x() { 2 + 1; }", HasOperands)); + EXPECT_TRUE(notMatches("void x() { 1 + 1; }", HasOperands)); + EXPECT_TRUE(notMatches("void x() { 2 + 2; }", HasOperands)); + EXPECT_TRUE(notMatches("void x() { 0 + 0; }", HasOperands)); + EXPECT_TRUE(notMatches("void x() { 0 + 1; }", HasOperands)); +} + TEST(Matcher, BinaryOperatorTypes) { // Integration test that verifies the AST provides all binary operators in // a way we expect. Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp =================================================================== --- clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -294,6 +294,7 @@ REGISTER_MATCHER(hasName); REGISTER_MATCHER(hasNullSelector); REGISTER_MATCHER(hasObjectExpression); + REGISTER_MATCHER(hasOperands); REGISTER_MATCHER(hasOperatorName); REGISTER_MATCHER(hasOverloadedOperatorName); REGISTER_MATCHER(hasParameter); Index: clang/include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- clang/include/clang/ASTMatchers/ASTMatchers.h +++ clang/include/clang/ASTMatchers/ASTMatchers.h @@ -4869,6 +4869,23 @@ return anyOf(hasLHS(InnerMatcher), hasRHS(InnerMatcher)); } +/// Matches if both matchers match with opposite sides of the binary operator. +/// +/// Example matcher = binaryOperator(hasOperands(integerLiteral(equals(1), +/// integerLiteral(equals(2))) +/// \code +/// 1 + 2 // Match +/// 2 + 1 // Match +/// 1 + 1 // No match +/// 2 + 2 // No match +/// \endcode +inline internal::Matcher<BinaryOperator> +hasOperands(const internal::Matcher<Expr> &Matcher1, + const internal::Matcher<Expr> &Matcher2) { + return anyOf(allOf(hasLHS(Matcher1), hasRHS(Matcher2)), + allOf(hasLHS(Matcher2), hasRHS(Matcher1))); +} + /// Matches if the operand of a unary operator matches. /// /// Example matches true (matcher = hasUnaryOperand( Index: clang/docs/LibASTMatchersReference.html =================================================================== --- clang/docs/LibASTMatchersReference.html +++ clang/docs/LibASTMatchersReference.html @@ -5033,6 +5033,18 @@ </pre></td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1BinaryOperator.html">BinaryOperator</a>></td><td class="name" onclick="toggle('hasOperands0')"><a name="hasOperands0Anchor">hasOperands</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> Matcher1, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> Matcher2</td></tr> +<tr><td colspan="4" class="doc" id="hasOperands0"><pre>Matches if both matchers match with opposite sides of the binary operator. + +Example matcher = binaryOperator(hasOperands(integerLiteral(equals(1), + integerLiteral(equals(2))) + 1 + 2 // Match + 2 + 1 // Match + 1 + 1 // No match + 2 + 2 // No match +</pre></td></tr> + + <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1BinaryOperator.html">BinaryOperator</a>></td><td class="name" onclick="toggle('hasRHS0')"><a name="hasRHS0Anchor">hasRHS</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> <tr><td colspan="4" class="doc" id="hasRHS0"><pre>Matches the right hand side of binary operator expressions.
Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp =================================================================== --- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -1160,6 +1160,17 @@ EXPECT_TRUE(notMatches("void x() { true || true; }", HasOperand)); } +TEST(MatchBinaryOperator, HasOperands) { + StatementMatcher HasOperands = binaryOperator( + hasOperands(integerLiteral(equals(1)), integerLiteral(equals(2)))); + EXPECT_TRUE(matches("void x() { 1 + 2; }", HasOperands)); + EXPECT_TRUE(matches("void x() { 2 + 1; }", HasOperands)); + EXPECT_TRUE(notMatches("void x() { 1 + 1; }", HasOperands)); + EXPECT_TRUE(notMatches("void x() { 2 + 2; }", HasOperands)); + EXPECT_TRUE(notMatches("void x() { 0 + 0; }", HasOperands)); + EXPECT_TRUE(notMatches("void x() { 0 + 1; }", HasOperands)); +} + TEST(Matcher, BinaryOperatorTypes) { // Integration test that verifies the AST provides all binary operators in // a way we expect. Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp =================================================================== --- clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -294,6 +294,7 @@ REGISTER_MATCHER(hasName); REGISTER_MATCHER(hasNullSelector); REGISTER_MATCHER(hasObjectExpression); + REGISTER_MATCHER(hasOperands); REGISTER_MATCHER(hasOperatorName); REGISTER_MATCHER(hasOverloadedOperatorName); REGISTER_MATCHER(hasParameter); Index: clang/include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- clang/include/clang/ASTMatchers/ASTMatchers.h +++ clang/include/clang/ASTMatchers/ASTMatchers.h @@ -4869,6 +4869,23 @@ return anyOf(hasLHS(InnerMatcher), hasRHS(InnerMatcher)); } +/// Matches if both matchers match with opposite sides of the binary operator. +/// +/// Example matcher = binaryOperator(hasOperands(integerLiteral(equals(1), +/// integerLiteral(equals(2))) +/// \code +/// 1 + 2 // Match +/// 2 + 1 // Match +/// 1 + 1 // No match +/// 2 + 2 // No match +/// \endcode +inline internal::Matcher<BinaryOperator> +hasOperands(const internal::Matcher<Expr> &Matcher1, + const internal::Matcher<Expr> &Matcher2) { + return anyOf(allOf(hasLHS(Matcher1), hasRHS(Matcher2)), + allOf(hasLHS(Matcher2), hasRHS(Matcher1))); +} + /// Matches if the operand of a unary operator matches. /// /// Example matches true (matcher = hasUnaryOperand( Index: clang/docs/LibASTMatchersReference.html =================================================================== --- clang/docs/LibASTMatchersReference.html +++ clang/docs/LibASTMatchersReference.html @@ -5033,6 +5033,18 @@ </pre></td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1BinaryOperator.html">BinaryOperator</a>></td><td class="name" onclick="toggle('hasOperands0')"><a name="hasOperands0Anchor">hasOperands</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> Matcher1, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> Matcher2</td></tr> +<tr><td colspan="4" class="doc" id="hasOperands0"><pre>Matches if both matchers match with opposite sides of the binary operator. + +Example matcher = binaryOperator(hasOperands(integerLiteral(equals(1), + integerLiteral(equals(2))) + 1 + 2 // Match + 2 + 1 // Match + 1 + 1 // No match + 2 + 2 // No match +</pre></td></tr> + + <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1BinaryOperator.html">BinaryOperator</a>></td><td class="name" onclick="toggle('hasRHS0')"><a name="hasRHS0Anchor">hasRHS</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> <tr><td colspan="4" class="doc" id="hasRHS0"><pre>Matches the right hand side of binary operator expressions.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits