Skip to content

Commit 81c4221

Browse files
committed
add missing support for hasEitherOperand and hasOperands
1 parent ae352f2 commit 81c4221

File tree

4 files changed

+97
-23
lines changed

4 files changed

+97
-23
lines changed

clang/docs/LibASTMatchersReference.html

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6550,7 +6550,7 @@ <h2 id="traversal-matchers">AST Traversal Matchers</h2>
65506550

65516551
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1BinaryOperator.html">BinaryOperator</a>&gt;</td><td class="name" onclick="toggle('hasEitherOperand0')"><a name="hasEitherOperand0Anchor">hasEitherOperand</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
65526552
<tr><td colspan="4" class="doc" id="hasEitherOperand0"><pre>Matches if either the left hand side or the right hand side of a
6553-
binary operator matches.
6553+
binary operator or fold expression matches.
65546554
</pre></td></tr>
65556555

65566556

@@ -6563,7 +6563,8 @@ <h2 id="traversal-matchers">AST Traversal Matchers</h2>
65636563

65646564

65656565
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1BinaryOperator.html">BinaryOperator</a>&gt;</td><td class="name" onclick="toggle('hasOperands0')"><a name="hasOperands0Anchor">hasOperands</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; Matcher1, Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; Matcher2</td></tr>
6566-
<tr><td colspan="4" class="doc" id="hasOperands0"><pre>Matches if both matchers match with opposite sides of the binary operator.
6566+
<tr><td colspan="4" class="doc" id="hasOperands0"><pre>Matches if both matchers match with opposite sides of the binary operator
6567+
or fold expression.
65676568

65686569
Example matcher = binaryOperator(hasOperands(integerLiteral(equals(1),
65696570
integerLiteral(equals(2)))
@@ -7015,6 +7016,12 @@ <h2 id="traversal-matchers">AST Traversal Matchers</h2>
70157016
</pre></td></tr>
70167017

70177018

7019+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXFoldExpr.html">CXXFoldExpr</a>&gt;</td><td class="name" onclick="toggle('hasEitherOperand2')"><a name="hasEitherOperand2Anchor">hasEitherOperand</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
7020+
<tr><td colspan="4" class="doc" id="hasEitherOperand2"><pre>Matches if either the left hand side or the right hand side of a
7021+
binary operator or fold expression matches.
7022+
</pre></td></tr>
7023+
7024+
70187025
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXFoldExpr.html">CXXFoldExpr</a>&gt;</td><td class="name" onclick="toggle('hasFoldInit0')"><a name="hasFoldInit0Anchor">hasFoldInit</a></td><td>ast_matchers::Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMacher</td></tr>
70197026
<tr><td colspan="4" class="doc" id="hasFoldInit0"><pre>Matches the operand that does not contain the parameter pack.
70207027

@@ -7042,6 +7049,19 @@ <h2 id="traversal-matchers">AST Traversal Matchers</h2>
70427049
</pre></td></tr>
70437050

70447051

7052+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXFoldExpr.html">CXXFoldExpr</a>&gt;</td><td class="name" onclick="toggle('hasOperands2')"><a name="hasOperands2Anchor">hasOperands</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; Matcher1, Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; Matcher2</td></tr>
7053+
<tr><td colspan="4" class="doc" id="hasOperands2"><pre>Matches if both matchers match with opposite sides of the binary operator
7054+
or fold expression.
7055+
7056+
Example matcher = binaryOperator(hasOperands(integerLiteral(equals(1),
7057+
integerLiteral(equals(2)))
7058+
1 + 2 // Match
7059+
2 + 1 // Match
7060+
1 + 1 // No match
7061+
2 + 2 // No match
7062+
</pre></td></tr>
7063+
7064+
70457065
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXFoldExpr.html">CXXFoldExpr</a>&gt;</td><td class="name" onclick="toggle('hasPattern0')"><a name="hasPattern0Anchor">hasPattern</a></td><td>ast_matchers::Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMacher</td></tr>
70467066
<tr><td colspan="4" class="doc" id="hasPattern0"><pre>Matches the operand that contains the parameter pack.
70477067

@@ -7363,7 +7383,7 @@ <h2 id="traversal-matchers">AST Traversal Matchers</h2>
73637383

73647384
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXOperatorCallExpr.html">CXXOperatorCallExpr</a>&gt;</td><td class="name" onclick="toggle('hasEitherOperand1')"><a name="hasEitherOperand1Anchor">hasEitherOperand</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
73657385
<tr><td colspan="4" class="doc" id="hasEitherOperand1"><pre>Matches if either the left hand side or the right hand side of a
7366-
binary operator matches.
7386+
binary operator or fold expression matches.
73677387
</pre></td></tr>
73687388

73697389

@@ -7376,7 +7396,8 @@ <h2 id="traversal-matchers">AST Traversal Matchers</h2>
73767396

73777397

73787398
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXOperatorCallExpr.html">CXXOperatorCallExpr</a>&gt;</td><td class="name" onclick="toggle('hasOperands1')"><a name="hasOperands1Anchor">hasOperands</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; Matcher1, Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; Matcher2</td></tr>
7379-
<tr><td colspan="4" class="doc" id="hasOperands1"><pre>Matches if both matchers match with opposite sides of the binary operator.
7399+
<tr><td colspan="4" class="doc" id="hasOperands1"><pre>Matches if both matchers match with opposite sides of the binary operator
7400+
or fold expression.
73807401

73817402
Example matcher = binaryOperator(hasOperands(integerLiteral(equals(1),
73827403
integerLiteral(equals(2)))
@@ -7501,9 +7522,9 @@ <h2 id="traversal-matchers">AST Traversal Matchers</h2>
75017522
</pre></td></tr>
75027523

75037524

7504-
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXRewrittenBinaryOperator.html">CXXRewrittenBinaryOperator</a>&gt;</td><td class="name" onclick="toggle('hasEitherOperand2')"><a name="hasEitherOperand2Anchor">hasEitherOperand</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
7505-
<tr><td colspan="4" class="doc" id="hasEitherOperand2"><pre>Matches if either the left hand side or the right hand side of a
7506-
binary operator matches.
7525+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXRewrittenBinaryOperator.html">CXXRewrittenBinaryOperator</a>&gt;</td><td class="name" onclick="toggle('hasEitherOperand3')"><a name="hasEitherOperand3Anchor">hasEitherOperand</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
7526+
<tr><td colspan="4" class="doc" id="hasEitherOperand3"><pre>Matches if either the left hand side or the right hand side of a
7527+
binary operator or fold expression matches.
75077528
</pre></td></tr>
75087529

75097530

@@ -7515,8 +7536,9 @@ <h2 id="traversal-matchers">AST Traversal Matchers</h2>
75157536
</pre></td></tr>
75167537

75177538

7518-
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXRewrittenBinaryOperator.html">CXXRewrittenBinaryOperator</a>&gt;</td><td class="name" onclick="toggle('hasOperands2')"><a name="hasOperands2Anchor">hasOperands</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; Matcher1, Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; Matcher2</td></tr>
7519-
<tr><td colspan="4" class="doc" id="hasOperands2"><pre>Matches if both matchers match with opposite sides of the binary operator.
7539+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXRewrittenBinaryOperator.html">CXXRewrittenBinaryOperator</a>&gt;</td><td class="name" onclick="toggle('hasOperands3')"><a name="hasOperands3Anchor">hasOperands</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; Matcher1, Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; Matcher2</td></tr>
7540+
<tr><td colspan="4" class="doc" id="hasOperands3"><pre>Matches if both matchers match with opposite sides of the binary operator
7541+
or fold expression.
75207542

75217543
Example matcher = binaryOperator(hasOperands(integerLiteral(equals(1),
75227544
integerLiteral(equals(2)))

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -832,7 +832,7 @@ AST Matchers
832832
- Add ``macroQualifiedType``.
833833
- Add ``CXXFoldExpr`` related matchers: ``cxxFoldExpr``, ``callee``,
834834
``hasInit``, ``hasPattern``, ``isRightFold``, ``isLeftFold``,
835-
``isUnaryFold``, ``isBinaryFold``, ``hasOperator``, ``hasLHS``, ``hasRHS``.
835+
``isUnaryFold``, ``isBinaryFold``, ``hasOperator``, ``hasLHS``, ``hasRHS``, ``hasEitherOperand``.
836836

837837
clang-format
838838
------------

clang/include/clang/ASTMatchers/ASTMatchers.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5982,18 +5982,19 @@ AST_POLYMORPHIC_MATCHER_P(
59825982
}
59835983

59845984
/// Matches if either the left hand side or the right hand side of a
5985-
/// binary operator matches.
5985+
/// binary operator or fold expression matches.
59865986
AST_POLYMORPHIC_MATCHER_P(
59875987
hasEitherOperand,
59885988
AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,
5989-
CXXRewrittenBinaryOperator),
5989+
CXXFoldExpr, CXXRewrittenBinaryOperator),
59905990
internal::Matcher<Expr>, InnerMatcher) {
59915991
return internal::VariadicDynCastAllOfMatcher<Stmt, NodeType>()(
59925992
anyOf(hasLHS(InnerMatcher), hasRHS(InnerMatcher)))
59935993
.matches(Node, Finder, Builder);
59945994
}
59955995

5996-
/// Matches if both matchers match with opposite sides of the binary operator.
5996+
/// Matches if both matchers match with opposite sides of the binary operator
5997+
/// or fold expression.
59975998
///
59985999
/// Example matcher = binaryOperator(hasOperands(integerLiteral(equals(1),
59996000
/// integerLiteral(equals(2)))
@@ -6006,7 +6007,7 @@ AST_POLYMORPHIC_MATCHER_P(
60066007
AST_POLYMORPHIC_MATCHER_P2(
60076008
hasOperands,
60086009
AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,
6009-
CXXRewrittenBinaryOperator),
6010+
CXXFoldExpr, CXXRewrittenBinaryOperator),
60106011
internal::Matcher<Expr>, Matcher1, internal::Matcher<Expr>, Matcher2) {
60116012
return internal::VariadicDynCastAllOfMatcher<Stmt, NodeType>()(
60126013
anyOf(allOf(hasLHS(Matcher1), hasRHS(Matcher2)),

clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -658,27 +658,27 @@ void check_match_co_return() {
658658
co_return 1;
659659
}
660660
)cpp";
661-
EXPECT_TRUE(matchesConditionally(CoReturnCode,
662-
coreturnStmt(isExpansionInMainFile()),
663-
true, {"-std=c++20", "-I/"}, M));
661+
EXPECT_TRUE(matchesConditionally(CoReturnCode,
662+
coreturnStmt(isExpansionInMainFile()), true,
663+
{"-std=c++20", "-I/"}, M));
664664
StringRef CoAwaitCode = R"cpp(
665665
#include <coro_header>
666666
void check_match_co_await() {
667667
co_await a;
668668
}
669669
)cpp";
670-
EXPECT_TRUE(matchesConditionally(CoAwaitCode,
671-
coawaitExpr(isExpansionInMainFile()),
672-
true, {"-std=c++20", "-I/"}, M));
670+
EXPECT_TRUE(matchesConditionally(CoAwaitCode,
671+
coawaitExpr(isExpansionInMainFile()), true,
672+
{"-std=c++20", "-I/"}, M));
673673
StringRef CoYieldCode = R"cpp(
674674
#include <coro_header>
675675
void check_match_co_yield() {
676676
co_yield 1.0;
677677
}
678678
)cpp";
679-
EXPECT_TRUE(matchesConditionally(CoYieldCode,
680-
coyieldExpr(isExpansionInMainFile()),
681-
true, {"-std=c++20", "-I/"}, M));
679+
EXPECT_TRUE(matchesConditionally(CoYieldCode,
680+
coyieldExpr(isExpansionInMainFile()), true,
681+
{"-std=c++20", "-I/"}, M));
682682

683683
StringRef NonCoroCode = R"cpp(
684684
#include <coro_header>
@@ -2075,6 +2075,57 @@ TEST_P(ASTMatchersTest, HasLHSAndHasRHS) {
20752075
cxxFoldExpr(hasRHS(expr()))));
20762076
}
20772077

2078+
TEST_P(ASTMatchersTest, HasEitherOperandAndHasOperands) {
2079+
if (!GetParam().isCXX17OrLater()) {
2080+
return;
2081+
}
2082+
2083+
EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2084+
"return (0 + ... + args); }",
2085+
cxxFoldExpr(hasEitherOperand(integerLiteral()))));
2086+
EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2087+
"return (args + ... + 0); }",
2088+
cxxFoldExpr(hasEitherOperand(integerLiteral()))));
2089+
2090+
EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2091+
"return (0 + ... + args); }",
2092+
cxxFoldExpr(hasEitherOperand(
2093+
declRefExpr(to(namedDecl(hasName("args"))))))));
2094+
EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2095+
"return (args + ... + 0); }",
2096+
cxxFoldExpr(hasEitherOperand(
2097+
declRefExpr(to(namedDecl(hasName("args"))))))));
2098+
EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2099+
"return (... + args); };",
2100+
cxxFoldExpr(hasEitherOperand(
2101+
declRefExpr(to(namedDecl(hasName("args"))))))));
2102+
EXPECT_TRUE(matches("template <typename... Args> auto sum(Args... args) { "
2103+
"return (args + ...); };",
2104+
cxxFoldExpr(hasEitherOperand(
2105+
declRefExpr(to(namedDecl(hasName("args"))))))));
2106+
2107+
EXPECT_TRUE(matches(
2108+
"template <typename... Args> auto sum(Args... args) { "
2109+
"return (0 + ... + args); }",
2110+
cxxFoldExpr(hasOperands(declRefExpr(to(namedDecl(hasName("args")))),
2111+
integerLiteral()))));
2112+
EXPECT_TRUE(matches(
2113+
"template <typename... Args> auto sum(Args... args) { "
2114+
"return (args + ... + 0); }",
2115+
cxxFoldExpr(hasOperands(declRefExpr(to(namedDecl(hasName("args")))),
2116+
integerLiteral()))));
2117+
EXPECT_FALSE(matches(
2118+
"template <typename... Args> auto sum(Args... args) { "
2119+
"return (... + args); };",
2120+
cxxFoldExpr(hasOperands(declRefExpr(to(namedDecl(hasName("args")))),
2121+
integerLiteral()))));
2122+
EXPECT_FALSE(matches(
2123+
"template <typename... Args> auto sum(Args... args) { "
2124+
"return (args + ...); };",
2125+
cxxFoldExpr(hasOperands(declRefExpr(to(namedDecl(hasName("args")))),
2126+
integerLiteral()))));
2127+
}
2128+
20782129
TEST_P(ASTMatchersTest, Callee) {
20792130
if (!GetParam().isCXX17OrLater()) {
20802131
return;

0 commit comments

Comments
 (0)