@@ -2062,6 +2062,18 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDefaultArgExpr>
2062
2062
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXOperatorCallExpr>
2063
2063
cxxOperatorCallExpr;
2064
2064
2065
+ // / Matches C++17 fold expressions.
2066
+ // /
2067
+ // / Example matches `(0 + ... + args)`:
2068
+ // / \code
2069
+ // / template <typename... Args>
2070
+ // / auto sum(Args... args) {
2071
+ // / return (0 + ... + args);
2072
+ // / }
2073
+ // / \endcode
2074
+ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXFoldExpr>
2075
+ cxxFoldExpr;
2076
+
2065
2077
// / Matches rewritten binary operators
2066
2078
// /
2067
2079
// / Example matches use of "<":
@@ -3881,7 +3893,7 @@ AST_MATCHER_P(ObjCMessageExpr, numSelectorArgs, unsigned, N) {
3881
3893
return Node.getSelector ().getNumArgs () == N;
3882
3894
}
3883
3895
3884
- // / Matches if the call expression's callee expression matches.
3896
+ // / Matches if the call or fold expression's callee expression matches.
3885
3897
// /
3886
3898
// / Given
3887
3899
// / \code
@@ -3893,13 +3905,32 @@ AST_MATCHER_P(ObjCMessageExpr, numSelectorArgs, unsigned, N) {
3893
3905
// / with callee(...)
3894
3906
// / matching this->x, x, y.x, f respectively
3895
3907
// /
3908
+ // / Given
3909
+ // / \code
3910
+ // / template <typename... Args>
3911
+ // / auto sum(Args... args) {
3912
+ // / return (0 + ... + args);
3913
+ // / }
3914
+ // /
3915
+ // / template <typename... Args>
3916
+ // / auto multiply(Args... args) {
3917
+ // / return (args * ... * 1);
3918
+ // / }
3919
+ // / \endcode
3920
+ // / cxxFoldExpr(callee(expr()))
3921
+ // / matches (args * ... * 1)
3922
+ // / with callee(...)
3923
+ // / matching *
3924
+ // /
3896
3925
// / Note: Callee cannot take the more general internal::Matcher<Expr>
3897
3926
// / because this introduces ambiguous overloads with calls to Callee taking a
3898
3927
// / internal::Matcher<Decl>, as the matcher hierarchy is purely
3899
3928
// / implemented in terms of implicit casts.
3900
- AST_MATCHER_P (CallExpr, callee, internal::Matcher<Stmt>,
3901
- InnerMatcher) {
3902
- const Expr *ExprNode = Node.getCallee ();
3929
+ AST_POLYMORPHIC_MATCHER_P_OVERLOAD (callee,
3930
+ AST_POLYMORPHIC_SUPPORTED_TYPES (CallExpr,
3931
+ CXXFoldExpr),
3932
+ internal::Matcher<Stmt>, InnerMatcher, 0) {
3933
+ const auto *ExprNode = Node.getCallee ();
3903
3934
return (ExprNode != nullptr &&
3904
3935
InnerMatcher.matches (*ExprNode, Finder, Builder));
3905
3936
}
@@ -4532,6 +4563,121 @@ AST_POLYMORPHIC_MATCHER_P2(hasArgument,
4532
4563
return InnerMatcher.matches (*Arg->IgnoreParenImpCasts (), Finder, Builder);
4533
4564
}
4534
4565
4566
+ // / Matches the operand that does not contain the parameter pack.
4567
+ // /
4568
+ // / Example matches `(0 + ... + args)` and `(args * ... * 1)`
4569
+ // / (matcher = cxxFoldExpr(hasFoldInit(expr())))
4570
+ // / with hasFoldInit(...)
4571
+ // / matching `0` and `1` respectively
4572
+ // / \code
4573
+ // / template <typename... Args>
4574
+ // / auto sum(Args... args) {
4575
+ // / return (0 + ... + args);
4576
+ // / }
4577
+ // /
4578
+ // / template <typename... Args>
4579
+ // / auto multiply(Args... args) {
4580
+ // / return (args * ... * 1);
4581
+ // / }
4582
+ // / \endcode
4583
+ AST_MATCHER_P (CXXFoldExpr, hasFoldInit, ast_matchers::internal::Matcher<Expr>,
4584
+ InnerMacher) {
4585
+ const auto *const Init = Node.getInit ();
4586
+ return Init && InnerMacher.matches (*Init, Finder, Builder);
4587
+ }
4588
+
4589
+ // / Matches the operand that contains the parameter pack.
4590
+ // /
4591
+ // / Example matches `(0 + ... + args)`
4592
+ // / (matcher = cxxFoldExpr(hasPattern(expr())))
4593
+ // / with hasPattern(...)
4594
+ // / matching `args`
4595
+ // / \code
4596
+ // / template <typename... Args>
4597
+ // / auto sum(Args... args) {
4598
+ // / return (0 + ... + args);
4599
+ // / }
4600
+ // /
4601
+ // / template <typename... Args>
4602
+ // / auto multiply(Args... args) {
4603
+ // / return (args * ... * 1);
4604
+ // / }
4605
+ // / \endcode
4606
+ AST_MATCHER_P (CXXFoldExpr, hasPattern, ast_matchers::internal::Matcher<Expr>,
4607
+ InnerMacher) {
4608
+ const Expr *const Pattern = Node.getPattern ();
4609
+ return Pattern && InnerMacher.matches (*Pattern, Finder, Builder);
4610
+ }
4611
+
4612
+ // / Matches right-folding fold expressions.
4613
+ // /
4614
+ // / Example matches `(args * ... * 1)`
4615
+ // / (matcher = cxxFoldExpr(isRightFold()))
4616
+ // / \code
4617
+ // / template <typename... Args>
4618
+ // / auto sum(Args... args) {
4619
+ // / return (0 + ... + args);
4620
+ // / }
4621
+ // /
4622
+ // / template <typename... Args>
4623
+ // / auto multiply(Args... args) {
4624
+ // / return (args * ... * 1);
4625
+ // / }
4626
+ // / \endcode
4627
+ AST_MATCHER (CXXFoldExpr, isRightFold) { return Node.isRightFold (); }
4628
+
4629
+ // / Matches left-folding fold expressions.
4630
+ // /
4631
+ // / Example matches `(0 + ... + args)`
4632
+ // / (matcher = cxxFoldExpr(isLeftFold()))
4633
+ // / \code
4634
+ // / template <typename... Args>
4635
+ // / auto sum(Args... args) {
4636
+ // / return (0 + ... + args);
4637
+ // / }
4638
+ // /
4639
+ // / template <typename... Args>
4640
+ // / auto multiply(Args... args) {
4641
+ // / return (args * ... * 1);
4642
+ // / }
4643
+ // / \endcode
4644
+ AST_MATCHER (CXXFoldExpr, isLeftFold) { return Node.isLeftFold (); }
4645
+
4646
+ // / Matches unary fold expressions, i.e. fold expressions without an
4647
+ // / initializer.
4648
+ // /
4649
+ // / Example matches `(args * ...)`
4650
+ // / (matcher = cxxFoldExpr(isUnaryFold()))
4651
+ // / \code
4652
+ // / template <typename... Args>
4653
+ // / auto sum(Args... args) {
4654
+ // / return (0 + ... + args);
4655
+ // / }
4656
+ // /
4657
+ // / template <typename... Args>
4658
+ // / auto multiply(Args... args) {
4659
+ // / return (args * ...);
4660
+ // / }
4661
+ // / \endcode
4662
+ AST_MATCHER (CXXFoldExpr, isUnaryFold) { return Node.getInit () == nullptr ; }
4663
+
4664
+ // / Matches binary fold expressions, i.e. fold expressions with an initializer.
4665
+ // /
4666
+ // / Example matches `(0 + ... + args)`
4667
+ // / (matcher = cxxFoldExpr(isBinaryFold()))
4668
+ // / \code
4669
+ // / template <typename... Args>
4670
+ // / auto sum(Args... args) {
4671
+ // / return (0 + ... + args);
4672
+ // / }
4673
+ // /
4674
+ // / template <typename... Args>
4675
+ // / auto multiply(Args... args) {
4676
+ // / return (args * ...);
4677
+ // / }
4678
+ // / \endcode
4679
+ AST_MATCHER (CXXFoldExpr, isBinaryFold) { return Node.getInit () != nullptr ; }
4680
+
4535
4681
// / Matches the n'th item of an initializer list expression.
4536
4682
// /
4537
4683
// / Example matches y.
@@ -5709,17 +5855,27 @@ AST_POLYMORPHIC_MATCHER_P_OVERLOAD(equals,
5709
5855
.matchesNode (Node);
5710
5856
}
5711
5857
5712
- // / Matches the operator Name of operator expressions (binary or
5713
- // / unary).
5858
+ // / Matches the operator Name of operator expressions and fold expressions
5859
+ // / (binary or unary).
5714
5860
// /
5715
5861
// / Example matches a || b (matcher = binaryOperator(hasOperatorName("||")))
5716
5862
// / \code
5717
5863
// / !(a || b)
5718
5864
// / \endcode
5865
+ // /
5866
+ // / Example matches `(0 + ... + args)`
5867
+ // / (matcher = cxxFoldExpr(hasOperatorName("+")))
5868
+ // / \code
5869
+ // / template <typename... Args>
5870
+ // / auto sum(Args... args) {
5871
+ // / return (0 + ... + args);
5872
+ // / }
5873
+ // / \endcode
5719
5874
AST_POLYMORPHIC_MATCHER_P (
5720
5875
hasOperatorName,
5721
5876
AST_POLYMORPHIC_SUPPORTED_TYPES (BinaryOperator, CXXOperatorCallExpr,
5722
- CXXRewrittenBinaryOperator, UnaryOperator),
5877
+ CXXRewrittenBinaryOperator, CXXFoldExpr,
5878
+ UnaryOperator),
5723
5879
std::string, Name) {
5724
5880
if (std::optional<StringRef> OpName = internal::getOpName (Node))
5725
5881
return *OpName == Name;
@@ -5789,11 +5945,12 @@ AST_POLYMORPHIC_MATCHER(
5789
5945
// / \code
5790
5946
// / a || b
5791
5947
// / \endcode
5792
- AST_POLYMORPHIC_MATCHER_P (hasLHS,
5793
- AST_POLYMORPHIC_SUPPORTED_TYPES (
5794
- BinaryOperator, CXXOperatorCallExpr,
5795
- CXXRewrittenBinaryOperator, ArraySubscriptExpr),
5796
- internal::Matcher<Expr>, InnerMatcher) {
5948
+ AST_POLYMORPHIC_MATCHER_P (
5949
+ hasLHS,
5950
+ AST_POLYMORPHIC_SUPPORTED_TYPES (BinaryOperator, CXXOperatorCallExpr,
5951
+ CXXRewrittenBinaryOperator,
5952
+ ArraySubscriptExpr, CXXFoldExpr),
5953
+ internal::Matcher<Expr>, InnerMatcher) {
5797
5954
const Expr *LeftHandSide = internal::getLHS (Node);
5798
5955
return (LeftHandSide != nullptr &&
5799
5956
InnerMatcher.matches (*LeftHandSide, Finder, Builder));
@@ -5805,29 +5962,31 @@ AST_POLYMORPHIC_MATCHER_P(hasLHS,
5805
5962
// / \code
5806
5963
// / a || b
5807
5964
// / \endcode
5808
- AST_POLYMORPHIC_MATCHER_P (hasRHS,
5809
- AST_POLYMORPHIC_SUPPORTED_TYPES (
5810
- BinaryOperator, CXXOperatorCallExpr,
5811
- CXXRewrittenBinaryOperator, ArraySubscriptExpr),
5812
- internal::Matcher<Expr>, InnerMatcher) {
5965
+ AST_POLYMORPHIC_MATCHER_P (
5966
+ hasRHS,
5967
+ AST_POLYMORPHIC_SUPPORTED_TYPES (BinaryOperator, CXXOperatorCallExpr,
5968
+ CXXRewrittenBinaryOperator,
5969
+ ArraySubscriptExpr, CXXFoldExpr),
5970
+ internal::Matcher<Expr>, InnerMatcher) {
5813
5971
const Expr *RightHandSide = internal::getRHS (Node);
5814
5972
return (RightHandSide != nullptr &&
5815
5973
InnerMatcher.matches (*RightHandSide, Finder, Builder));
5816
5974
}
5817
5975
5818
5976
// / Matches if either the left hand side or the right hand side of a
5819
- // / binary operator matches.
5977
+ // / binary operator or fold expression matches.
5820
5978
AST_POLYMORPHIC_MATCHER_P (
5821
5979
hasEitherOperand,
5822
5980
AST_POLYMORPHIC_SUPPORTED_TYPES (BinaryOperator, CXXOperatorCallExpr,
5823
- CXXRewrittenBinaryOperator),
5981
+ CXXFoldExpr, CXXRewrittenBinaryOperator),
5824
5982
internal::Matcher<Expr>, InnerMatcher) {
5825
5983
return internal::VariadicDynCastAllOfMatcher<Stmt, NodeType>()(
5826
5984
anyOf (hasLHS (InnerMatcher), hasRHS (InnerMatcher)))
5827
5985
.matches (Node, Finder, Builder);
5828
5986
}
5829
5987
5830
- // / Matches if both matchers match with opposite sides of the binary operator.
5988
+ // / Matches if both matchers match with opposite sides of the binary operator
5989
+ // / or fold expression.
5831
5990
// /
5832
5991
// / Example matcher = binaryOperator(hasOperands(integerLiteral(equals(1),
5833
5992
// / integerLiteral(equals(2)))
@@ -5840,7 +5999,7 @@ AST_POLYMORPHIC_MATCHER_P(
5840
5999
AST_POLYMORPHIC_MATCHER_P2 (
5841
6000
hasOperands,
5842
6001
AST_POLYMORPHIC_SUPPORTED_TYPES (BinaryOperator, CXXOperatorCallExpr,
5843
- CXXRewrittenBinaryOperator),
6002
+ CXXFoldExpr, CXXRewrittenBinaryOperator),
5844
6003
internal::Matcher<Expr>, Matcher1, internal::Matcher<Expr>, Matcher2) {
5845
6004
return internal::VariadicDynCastAllOfMatcher<Stmt, NodeType>()(
5846
6005
anyOf (allOf (hasLHS (Matcher1), hasRHS (Matcher2)),
0 commit comments