Index: docs/LibASTMatchersReference.html
===================================================================
--- docs/LibASTMatchersReference.html
+++ docs/LibASTMatchersReference.html
@@ -271,6 +271,17 @@
+
Matcher<Decl> | labelDecl | Matcher<LabelDecl>... |
+Matches a declaration of label.
+
+Given
+ goto FOO;
+ FOO: bar();
+labelDecl()
+ matches 'FOO:'
+ |
+
+
Matcher<Decl> | linkageSpecDecl | Matcher<LinkageSpecDecl>... |
Matches a declaration of a linkage specification.
@@ -497,6 +508,18 @@
|
+Matcher<Stmt> | addrLabelExpr | Matcher<AddrLabelExpr>... |
+Matches address of label statements (GNU extension).
+
+Given
+ FOO: bar();
+ void *ptr = &&FOO;
+ goto *bar;
+addrLabelExpr()
+ matches '&&FOO'
+ |
+
+
Matcher<Stmt> | arraySubscriptExpr | Matcher<ArraySubscriptExpr>... |
Matches array subscript expressions.
@@ -517,6 +540,21 @@
|
+Matcher<Stmt> | atomicExpr | Matcher<AtomicExpr>... |
+Matches atomic builtins.
+Example matches __atomic_load_n(ptr, 1)
+ void foo() { int *ptr; __atomic_load_n(ptr, 1); }
+ |
+
+
+Matcher<Stmt> | binaryConditionalOperator | Matcher<BinaryConditionalOperator>... |
+Matches binary conditional operator expressions (GNU extension).
+
+Example matches a ?: b
+ (a ?: b) + 42;
+ |
+
+
Matcher<Stmt> | binaryOperator | Matcher<BinaryOperator>... |
Matches binary operator expressions.
@@ -876,6 +914,14 @@
|
+Matcher<Stmt> | designatedInitExpr | Matcher<DesignatedInitExpr>... |
+Matches C99 designated initializer expressions [C99 6.7.8].
+
+Example: Matches { [2].y = 1.0, [0].x = 1.0 }
+ point ptarray[10] = { [2].y = 1.0, [0].x = 1.0 };
+ |
+
+
Matcher<Stmt> | doStmt | Matcher<DoStmt>... |
Matches do statements.
@@ -974,6 +1020,16 @@
|
+Matcher<Stmt> | implicitValueInitExpr | Matcher<ImplicitValueInitExpr>... |
+Matches implicit initializers of init list expressions.
+
+Given
+ point ptarray[10] = { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 };
+implicitValueInitExpr()
+ matches "[0].y" (implicitly)
+ |
+
+
Matcher<Stmt> | initListExpr | Matcher<InitListExpr>... |
Matches init list expressions.
@@ -1062,6 +1118,16 @@
|
+Matcher<Stmt> | opaqueValueExpr | Matcher<OpaqueValueExpr>... |
+Matches opaque value expressions. They are used as helpers
+to reference another expressions and can be met
+in BinaryConditionalOperators, for example.
+
+Example matches 'a'
+ (a ?: c) + 42;
+ |
+
+
Matcher<Stmt> | parenExpr | Matcher<ParenExpr>... |
Matches parentheses used in expressions.
@@ -1071,6 +1137,31 @@
|
+Matcher<Stmt> | parenListExpr | Matcher<ParenListExpr>... |
+Matches paren list expressions.
+ParenListExprs don't have a predefined type and are used for late parsing.
+In the final AST, they can be met in template declarations.
+
+Given
+ template<typename T> class X {
+ void f() {
+ X x(*this);
+ int a = 0, b = 1; int i = (a, b);
+ }
+ };
+parenListExpr() matches "*this" but NOT matches (a, b) because (a, b)
+has a predefined type and is a ParenExpr, not a ParenListExpr.
+ |
+
+
+Matcher<Stmt> | predefinedExpr | Matcher<PredefinedExpr>... |
+Matches predefined identifier expressions [C99 6.4.2.2].
+
+Example: Matches __func__
+ printf("%s", __func__);
+ |
+
+
Matcher<Stmt> | returnStmt | Matcher<ReturnStmt>... |
Matches return statements.
@@ -1091,6 +1182,14 @@
|
+Matcher<Stmt> | stmtExpr | Matcher<StmtExpr>... |
+Matches statement expression (GNU extension).
+
+Example match: ({ int X = 4; X; })
+ int C = ({ int X = 4; X; });
+ |
+
+
Matcher<Stmt> | stringLiteral | Matcher<StringLiteral>... |
Matches string literals (also matches wide string literals).
@@ -1660,6 +1759,20 @@
|
+Matcher<CXXConstructExpr> | requiresZeroInitialization | |
+Matches a constructor call expression which requires
+zero initialization.
+
+Given
+void foo() {
+ struct point { double x; double y; };
+ point pt[2] = { { 1.0, 2.0 } };
+}
+initListExpr(has(cxxConstructExpr(requiresZeroInitialization()))
+will match the implicit array filler for pt[1].
+ |
+
+
Matcher<CXXConstructorDecl> | isCopyConstructor | |
Matches constructor declarations that are copy constructors.
@@ -2176,6 +2289,19 @@
|
+Matcher<DesignatedInitExpr> | designatorCountIs | unsigned N |
+Matches designated initializer expressions that contain
+a specific number of designators.
+
+Example: Given
+ point ptarray[10] = { [2].y = 1.0, [0].x = 1.0 };
+ point ptarray2[10] = { [2].y = 1.0, [2].x = 0.0, [0].x = 1.0 };
+designatorCountIs(2)
+ matches '{ [2].y = 1.0, [0].x = 1.0 }',
+ but not '{ [2].y = 1.0, [2].x = 0.0, [0].x = 1.0 }'.
+ |
+
+
Matcher<FloatingLiteral> | equals | ValueT Value |
Matches literals that are equal to the given value.
@@ -3266,6 +3392,58 @@
|
+Matcher<AbstractConditionalOperator> | hasCondition | Matcher<Expr> InnerMatcher |
+Matches the condition expression of an if statement, for loop,
+or conditional operator.
+
+Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
+ if (true) {}
+ |
+
+
+Matcher<AbstractConditionalOperator> | hasFalseExpression | Matcher<Expr> InnerMatcher |
+Matches the false branch expression of a conditional operator
+(binary or ternary).
+
+Example matches b
+ condition ? a : b
+ condition ?: b
+ |
+
+
+Matcher<AbstractConditionalOperator> | hasTrueExpression | Matcher<Expr> InnerMatcher |
+Matches the true branch expression of a conditional operator.
+
+Example 1 (conditional ternary operator): matches a
+ condition ? a : b
+
+Example 2 (conditional binary operator): matches opaqueValueExpr(condition)
+ condition ?: b
+ |
+
+
+Matcher<AddrLabelExpr> | hasDeclaration | Matcher<Decl> InnerMatcher |
+Matches a node if the declaration associated with that node
+matches the given matcher.
+
+The associated declaration is:
+- for type nodes, the declaration of the underlying type
+- for CallExpr, the declaration of the callee
+- for MemberExpr, the declaration of the referenced member
+- for CXXConstructExpr, the declaration of the constructor
+
+Also usable as Matcher<T> for any T supporting the getDecl() member
+function. e.g. various subtypes of clang::Type and various expressions.
+
+Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>,
+ Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>,
+ Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>,
+ Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>,
+ Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>,
+ Matcher<TypedefType>, Matcher<UnresolvedUsingType>
+ |
+
+
Matcher<ArraySubscriptExpr> | hasBase | Matcher<Expr> InnerMatcher |
Matches the base expression of an array subscript expression.
@@ -3476,8 +3654,8 @@
|
-Matcher<CXXConstructExpr> | hasDeclaration | Matcher<Decl> InnerMatcher |
-Matches a node if the declaration associated with that node
+Matcher<CXXConstructExpr> | hasDeclaration | Matcher<Decl> InnerMatcher |
+Matches a node if the declaration associated with that node
matches the given matcher.
The associated declaration is:
@@ -3491,8 +3669,8 @@
Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>,
Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>,
- Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>,
- Matcher<RecordType>, Matcher<TagType>,
+ Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>,
+ Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>,
Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>,
Matcher<TypedefType>, Matcher<UnresolvedUsingType>
|
@@ -3747,8 +3925,8 @@
|
-Matcher<CallExpr> | hasDeclaration | Matcher<Decl> InnerMatcher |
-Matches a node if the declaration associated with that node
+Matcher<CallExpr> | hasDeclaration | Matcher<Decl> InnerMatcher |
+Matches a node if the declaration associated with that node
matches the given matcher.
The associated declaration is:
@@ -3762,8 +3940,8 @@
Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>,
Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>,
- Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>,
- Matcher<RecordType>, Matcher<TagType>,
+ Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>,
+ Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>,
Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>,
Matcher<TypedefType>, Matcher<UnresolvedUsingType>
|
@@ -3781,13 +3959,7 @@
Matcher<CastExpr> | hasSourceExpression | Matcher<Expr> InnerMatcher |
-Matches if the cast's source expression matches the given matcher.
-
-Example: matches "a string" (matcher =
- hasSourceExpression(cxxConstructExpr()))
-class URL { URL(string); };
-URL url = "a string";
- |
+ |
Matcher<ClassTemplateSpecializationDecl> | hasAnyTemplateArgument | Matcher<TemplateArgument> InnerMatcher |
@@ -3850,7 +4022,7 @@
Matcher<CompoundStmt> | hasAnySubstatement | Matcher<Stmt> InnerMatcher |
Matches compound statements where at least one substatement matches
-a given matcher.
+a given matcher. Also matches StmtExprs that have CompoundStmt as children.
Given
{ {}; 1+2; }
@@ -3861,38 +4033,13 @@
|
-Matcher<ConditionalOperator> | hasCondition | Matcher<Expr> InnerMatcher |
-Matches the condition expression of an if statement, for loop,
-or conditional operator.
-
-Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
- if (true) {}
- |
-
-
-Matcher<ConditionalOperator> | hasFalseExpression | Matcher<Expr> InnerMatcher |
-Matches the false branch expression of a conditional operator.
-
-Example matches b
- condition ? a : b
- |
-
-
-Matcher<ConditionalOperator> | hasTrueExpression | Matcher<Expr> InnerMatcher |
-Matches the true branch expression of a conditional operator.
-
-Example matches a
- condition ? a : b
- |
-
-
Matcher<DecayedType> | hasDecayedType | Matcher<QualType> InnerType |
Matches the decayed type, whos decayed type matches InnerMatcher
|
-Matcher<DeclRefExpr> | hasDeclaration | Matcher<Decl> InnerMatcher |
-Matches a node if the declaration associated with that node
+Matcher<DeclRefExpr> | hasDeclaration | Matcher<Decl> InnerMatcher |
+Matches a node if the declaration associated with that node
matches the given matcher.
The associated declaration is:
@@ -3906,8 +4053,8 @@
Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>,
Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>,
- Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>,
- Matcher<RecordType>, Matcher<TagType>,
+ Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>,
+ Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>,
Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>,
Matcher<TypedefType>, Matcher<UnresolvedUsingType>
|
@@ -4053,8 +4200,8 @@
|
-Matcher<EnumType> | hasDeclaration | Matcher<Decl> InnerMatcher |
-Matches a node if the declaration associated with that node
+Matcher<EnumType> | hasDeclaration | Matcher<Decl> InnerMatcher |
+Matches a node if the declaration associated with that node
matches the given matcher.
The associated declaration is:
@@ -4068,8 +4215,8 @@
Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>,
Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>,
- Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>,
- Matcher<RecordType>, Matcher<TagType>,
+ Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>,
+ Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>,
Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>,
Matcher<TypedefType>, Matcher<UnresolvedUsingType>
|
@@ -4316,8 +4463,14 @@
|
-Matcher<InjectedClassNameType> | hasDeclaration | Matcher<Decl> InnerMatcher |
-Matches a node if the declaration associated with that node
+Matcher<InitListExpr> | hasSyntacticForm | Matcher<Expr> InnerMatcher |
+Matches the syntactic form of init list expressions
+(if expression have it).
+ |
+
+
+Matcher<InjectedClassNameType> | hasDeclaration | Matcher<Decl> InnerMatcher |
+Matches a node if the declaration associated with that node
matches the given matcher.
The associated declaration is:
@@ -4331,15 +4484,15 @@
Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>,
Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>,
- Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>,
- Matcher<RecordType>, Matcher<TagType>,
+ Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>,
+ Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>,
Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>,
Matcher<TypedefType>, Matcher<UnresolvedUsingType>
|
-Matcher<LabelStmt> | hasDeclaration | Matcher<Decl> InnerMatcher |
-Matches a node if the declaration associated with that node
+Matcher<LabelStmt> | hasDeclaration | Matcher<Decl> InnerMatcher |
+Matches a node if the declaration associated with that node
matches the given matcher.
The associated declaration is:
@@ -4353,8 +4506,8 @@
Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>,
Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>,
- Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>,
- Matcher<RecordType>, Matcher<TagType>,
+ Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>,
+ Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>,
Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>,
Matcher<TypedefType>, Matcher<UnresolvedUsingType>
|
@@ -4375,8 +4528,8 @@
Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>,
Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>,
- Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>,
- Matcher<RecordType>, Matcher<TagType>,
+ Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>,
+ Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>,
Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>,
Matcher<TypedefType>, Matcher<UnresolvedUsingType>
|
@@ -4525,6 +4678,10 @@
|
+Matcher<OpaqueValueExpr> | hasSourceExpression | Matcher<Expr> InnerMatcher |
+ |
+
+
Matcher<ParenType> | innerType | Matcher<Type> |
Matches ParenType nodes where the inner type is a specific type.
@@ -4599,8 +4756,8 @@
Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>,
Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>,
- Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>,
- Matcher<RecordType>, Matcher<TagType>,
+ Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>,
+ Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>,
Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>,
Matcher<TypedefType>, Matcher<UnresolvedUsingType>
|
@@ -4658,8 +4815,8 @@
Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>,
Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>,
- Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>,
- Matcher<RecordType>, Matcher<TagType>,
+ Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>,
+ Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>,
Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>,
Matcher<TypedefType>, Matcher<UnresolvedUsingType>
|
@@ -4697,6 +4854,19 @@
+Matcher<StmtExpr> | hasAnySubstatement | Matcher<Stmt> InnerMatcher |
+Matches compound statements where at least one substatement matches
+a given matcher. Also matches StmtExprs that have CompoundStmt as children.
+
+Given
+ { {}; 1+2; }
+hasAnySubstatement(compoundStmt())
+ matches '{ {}; 1+2; }'
+with compoundStmt()
+ matching '{}'
+ |
+
+
Matcher<Stmt> | alignOfExpr | Matcher<UnaryExprOrTypeTraitExpr> InnerMatcher |
Same as unaryExprOrTypeTraitExpr, but only matching
alignof.
@@ -4737,8 +4907,8 @@
Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>,
Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>,
- Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>,
- Matcher<RecordType>, Matcher<TagType>,
+ Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>,
+ Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>,
Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>,
Matcher<TypedefType>, Matcher<UnresolvedUsingType>
|
@@ -4827,8 +4997,8 @@
Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>,
Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>,
- Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>,
- Matcher<RecordType>, Matcher<TagType>,
+ Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>,
+ Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>,
Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>,
Matcher<TypedefType>, Matcher<UnresolvedUsingType>
@@ -4863,8 +5033,8 @@
Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>,
Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>,
- Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>,
- Matcher<RecordType>, Matcher<TagType>,
+ Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>,
+ Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>,
Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>,
Matcher<TypedefType>, Matcher<UnresolvedUsingType>
@@ -4914,8 +5084,8 @@
Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>,
Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>,
- Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>,
- Matcher<RecordType>, Matcher<TagType>,
+ Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>,
+ Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>,
Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>,
Matcher<TypedefType>, Matcher<UnresolvedUsingType>
@@ -4955,8 +5125,8 @@
Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>,
Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>,
- Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>,
- Matcher<RecordType>, Matcher<TagType>,
+ Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>,
+ Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>,
Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>,
Matcher<TypedefType>, Matcher<UnresolvedUsingType>
Index: include/clang/ASTMatchers/ASTMatchers.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -282,6 +282,18 @@
/// \endcode
const internal::VariadicDynCastAllOfMatcher namedDecl;
+/// \brief Matches a declaration of label.
+///
+/// Given
+/// \code
+/// goto FOO;
+/// FOO: bar();
+/// \endcode
+/// labelDecl()
+/// matches 'FOO:'
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher labelDecl;
+
/// \brief Matches a declaration of a namespace.
///
/// Given
@@ -976,6 +988,43 @@
/// matches "{ 1, 2 }" and "{ 5, 6 }"
const internal::VariadicDynCastAllOfMatcher initListExpr;
+/// \brief Matches the syntactic form of init list expressions
+/// (if expression have it).
+AST_MATCHER_P(InitListExpr, hasSyntacticForm,
+ internal::Matcher, InnerMatcher) {
+ const Expr *SyntForm = Node.getSyntacticForm();
+ return (SyntForm != nullptr &&
+ InnerMatcher.matches(*SyntForm, Finder, Builder));
+}
+
+/// \brief Matches implicit initializers of init list expressions.
+///
+/// Given
+/// \code
+/// point ptarray[10] = { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 };
+/// \endcode
+/// implicitValueInitExpr()
+/// matches "[0].y" (implicitly)
+const internal::VariadicDynCastAllOfMatcher
+implicitValueInitExpr;
+
+/// \brief Matches paren list expressions.
+/// ParenListExprs don't have a predefined type and are used for late parsing.
+/// In the final AST, they can be met in template declarations.
+///
+/// Given
+/// \code
+/// template class X {
+/// void f() {
+/// X x(*this);
+/// int a = 0, b = 1; int i = (a, b);
+/// }
+/// };
+/// \endcode
+/// parenListExpr() matches "*this" but NOT matches (a, b) because (a, b)
+/// has a predefined type and is a ParenExpr, not a ParenListExpr.
+const internal::VariadicDynCastAllOfMatcher parenListExpr;
+
/// \brief Matches substitutions of non-type template parameters.
///
/// Given
@@ -1368,6 +1417,18 @@
/// matches 'FOO:'
const internal::VariadicDynCastAllOfMatcher labelStmt;
+/// \brief Matches address of label statements (GNU extension).
+///
+/// Given
+/// \code
+/// FOO: bar();
+/// void *ptr = &&FOO;
+/// goto *bar;
+/// \endcode
+/// addrLabelExpr()
+/// matches '&&FOO'
+const internal::VariadicDynCastAllOfMatcher addrLabelExpr;
+
/// \brief Matches switch statements.
///
/// Given
@@ -1537,9 +1598,22 @@
CXXNullPtrLiteralExpr> cxxNullPtrLiteralExpr;
/// \brief Matches GNU __null expression.
-const internal::VariadicDynCastAllOfMatcher<
- Stmt,
- GNUNullExpr> gnuNullExpr;
+const internal::VariadicDynCastAllOfMatcher gnuNullExpr;
+
+/// \brief Matches atomic builtins.
+/// Example matches __atomic_load_n(ptr, 1)
+/// \code
+/// void foo() { int *ptr; __atomic_load_n(ptr, 1); }
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher atomicExpr;
+
+/// \brief Matches statement expression (GNU extension).
+///
+/// Example match: ({ int X = 4; X; })
+/// \code
+/// int C = ({ int X = 4; X; });
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher stmtExpr;
/// \brief Matches binary operator expressions.
///
@@ -1571,6 +1645,28 @@
Stmt,
ConditionalOperator> conditionalOperator;
+/// \brief Matches binary conditional operator expressions (GNU extension).
+///
+/// Example matches a ?: b
+/// \code
+/// (a ?: b) + 42;
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+ Stmt,
+ BinaryConditionalOperator> binaryConditionalOperator;
+
+/// \brief Matches opaque value expressions. They are used as helpers
+/// to reference another expressions and can be met
+/// in BinaryConditionalOperators, for example.
+///
+/// Example matches 'a'
+/// \code
+/// (a ?: c) + 42;
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+ Stmt,
+ OpaqueValueExpr> opaqueValueExpr;
+
/// \brief Matches a C++ static_assert declaration.
///
/// Example:
@@ -1727,6 +1823,41 @@
Stmt,
CXXTemporaryObjectExpr> cxxTemporaryObjectExpr;
+/// \brief Matches predefined identifier expressions [C99 6.4.2.2].
+///
+/// Example: Matches __func__
+/// \code
+/// printf("%s", __func__);
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+ Stmt,
+ PredefinedExpr> predefinedExpr;
+
+/// \brief Matches C99 designated initializer expressions [C99 6.7.8].
+///
+/// Example: Matches { [2].y = 1.0, [0].x = 1.0 }
+/// \code
+/// point ptarray[10] = { [2].y = 1.0, [0].x = 1.0 };
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+ Stmt,
+ DesignatedInitExpr> designatedInitExpr;
+
+/// \brief Matches designated initializer expressions that contain
+/// a specific number of designators.
+///
+/// Example: Given
+/// \code
+/// point ptarray[10] = { [2].y = 1.0, [0].x = 1.0 };
+/// point ptarray2[10] = { [2].y = 1.0, [2].x = 0.0, [0].x = 1.0 };
+/// \endcode
+/// designatorCountIs(2)
+/// matches '{ [2].y = 1.0, [0].x = 1.0 }',
+/// but not '{ [2].y = 1.0, [2].x = 0.0, [0].x = 1.0 }'.
+AST_MATCHER_P(DesignatedInitExpr, designatorCountIs, unsigned, N) {
+ return Node.size() == N;
+}
+
/// \brief Matches \c QualTypes in the clang AST.
const internal::VariadicAllOfMatcher qualType;
@@ -2144,8 +2275,8 @@
///
/// Usable as: Matcher, Matcher,
/// Matcher, Matcher, Matcher,
-/// Matcher, Matcher, Matcher,
-/// Matcher, Matcher,
+/// Matcher, Matcher, Matcher,
+/// Matcher, Matcher, Matcher,
/// Matcher, Matcher,
/// Matcher, Matcher
inline internal::PolymorphicMatcherWithParam1<
@@ -2883,6 +3014,22 @@
return Node.isListInitialization();
}
+/// \brief Matches a constructor call expression which requires
+/// zero initialization.
+///
+/// Given
+/// \code
+/// void foo() {
+/// struct point { double x; double y; };
+/// point pt[2] = { { 1.0, 2.0 } };
+/// }
+/// \endcode
+/// initListExpr(has(cxxConstructExpr(requiresZeroInitialization()))
+/// will match the implicit array filler for pt[1].
+AST_MATCHER(CXXConstructExpr, requiresZeroInitialization) {
+ return Node.requiresZeroInitialization();
+}
+
/// \brief Matches the n'th parameter of a function declaration.
///
/// Given
@@ -3099,11 +3246,11 @@
/// \code
/// if (true) {}
/// \endcode
-AST_POLYMORPHIC_MATCHER_P(hasCondition,
- AST_POLYMORPHIC_SUPPORTED_TYPES(IfStmt, ForStmt,
- WhileStmt, DoStmt,
- ConditionalOperator),
- internal::Matcher, InnerMatcher) {
+AST_POLYMORPHIC_MATCHER_P(
+ hasCondition,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(IfStmt, ForStmt, WhileStmt, DoStmt,
+ AbstractConditionalOperator),
+ internal::Matcher, InnerMatcher) {
const Expr *const Condition = Node.getCond();
return (Condition != nullptr &&
InnerMatcher.matches(*Condition, Finder, Builder));
@@ -3242,7 +3389,7 @@
}
/// \brief Matches compound statements where at least one substatement matches
-/// a given matcher.
+/// a given matcher. Also matches StmtExprs that have CompoundStmt as children.
///
/// Given
/// \code
@@ -3252,10 +3399,13 @@
/// matches '{ {}; 1+2; }'
/// with compoundStmt()
/// matching '{}'
-AST_MATCHER_P(CompoundStmt, hasAnySubstatement,
- internal::Matcher, InnerMatcher) {
- return matchesFirstInPointerRange(InnerMatcher, Node.body_begin(),
- Node.body_end(), Finder, Builder);
+AST_POLYMORPHIC_MATCHER_P(hasAnySubstatement,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(CompoundStmt,
+ StmtExpr),
+ internal::Matcher, InnerMatcher) {
+ const CompoundStmt *CS = CompoundStmtMatcher::get(Node);
+ return CS && matchesFirstInPointerRange(InnerMatcher, CS->body_begin(),
+ CS->body_end(), Finder, Builder);
}
/// \brief Checks that a compound statement contains a specific number of
@@ -3354,17 +3504,28 @@
InnerMatcher.matches(*Operand, Finder, Builder));
}
-/// \brief Matches if the cast's source expression matches the given matcher.
+/// \brief Matches if the cast's source expression
+/// or opaque value's source expression matches the given matcher.
///
-/// Example: matches "a string" (matcher =
-/// hasSourceExpression(cxxConstructExpr()))
+/// Example 1: matches "a string"
+/// (matcher = castExpr(hasSourceExpression(cxxConstructExpr())))
/// \code
/// class URL { URL(string); };
/// URL url = "a string";
/// \endcode
-AST_MATCHER_P(CastExpr, hasSourceExpression,
- internal::Matcher, InnerMatcher) {
- const Expr* const SubExpression = Node.getSubExpr();
+///
+/// Example 2: matches 'b' (matcher =
+/// opaqueValueExpr(hasSourceExpression(implicitCastExpr(declRefExpr())))
+/// \code
+/// int a = b ?: 1;
+/// \endcode
+
+AST_POLYMORPHIC_MATCHER_P(hasSourceExpression,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(CastExpr,
+ OpaqueValueExpr),
+ internal::Matcher, InnerMatcher) {
+ const Expr *const SubExpression =
+ internal::GetSourceExpressionMatcher::get(Node);
return (SubExpression != nullptr &&
InnerMatcher.matches(*SubExpression, Finder, Builder));
}
@@ -3426,24 +3587,31 @@
/// \brief Matches the true branch expression of a conditional operator.
///
-/// Example matches a
+/// Example 1 (conditional ternary operator): matches a
/// \code
/// condition ? a : b
/// \endcode
-AST_MATCHER_P(ConditionalOperator, hasTrueExpression,
+///
+/// Example 2 (conditional binary operator): matches opaqueValueExpr(condition)
+/// \code
+/// condition ?: b
+/// \endcode
+AST_MATCHER_P(AbstractConditionalOperator, hasTrueExpression,
internal::Matcher, InnerMatcher) {
const Expr *Expression = Node.getTrueExpr();
return (Expression != nullptr &&
InnerMatcher.matches(*Expression, Finder, Builder));
}
-/// \brief Matches the false branch expression of a conditional operator.
+/// \brief Matches the false branch expression of a conditional operator
+/// (binary or ternary).
///
/// Example matches b
/// \code
/// condition ? a : b
+/// condition ?: b
/// \endcode
-AST_MATCHER_P(ConditionalOperator, hasFalseExpression,
+AST_MATCHER_P(AbstractConditionalOperator, hasFalseExpression,
internal::Matcher, InnerMatcher) {
const Expr *Expression = Node.getFalseExpr();
return (Expression != nullptr &&
Index: include/clang/ASTMatchers/ASTMatchersInternal.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchersInternal.h
+++ include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -749,6 +749,14 @@
return matchesDecl(Node.getMemberDecl(), Finder, Builder);
}
+ /// \brief Extracts the \c LabelDecl a \c AddrLabelExpr refers to and returns
+ /// whether the inner matcher matches on it.
+ bool matchesSpecialized(const AddrLabelExpr &Node,
+ ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const {
+ return matchesDecl(Node.getLabel(), Finder, Builder);
+ }
+
/// \brief Returns whether the inner matcher \c Node. Returns false if \c Node
/// is \c NULL.
bool matchesDecl(const Decl *Node, ASTMatchFinder *Finder,
@@ -954,8 +962,8 @@
/// \brief All types that are supported by HasDeclarationMatcher above.
typedef TypeList HasDeclarationSupportedTypes;
@@ -1608,6 +1616,33 @@
return Node.doesThisDeclarationHaveABody() ? Node.getBody() : nullptr;
}
+template
+struct GetSourceExpressionMatcher {
+ static const Expr *get(const Ty &Node) {
+ return Node.getSubExpr();
+ }
+};
+
+template <>
+inline const Expr *GetSourceExpressionMatcher::get(
+ const OpaqueValueExpr &Node) {
+ return Node.getSourceExpr();
+}
+
+template
+struct CompoundStmtMatcher {
+ static const CompoundStmt *get(const Ty &Node) {
+ return &Node;
+ }
+};
+
+template <>
+inline const CompoundStmt *
+CompoundStmtMatcher::get(const StmtExpr &Node) {
+ return Node.getSubStmt();
+}
+
+
} // end namespace internal
} // end namespace ast_matchers
} // end namespace clang
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===================================================================
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -95,6 +95,7 @@
REGISTER_OVERLOADED_2(thisPointerType);
REGISTER_MATCHER(accessSpecDecl);
+ REGISTER_MATCHER(addrLabelExpr);
REGISTER_MATCHER(alignOfExpr);
REGISTER_MATCHER(allOf);
REGISTER_MATCHER(anyOf);
@@ -104,9 +105,11 @@
REGISTER_MATCHER(arrayType);
REGISTER_MATCHER(asmStmt);
REGISTER_MATCHER(asString);
+ REGISTER_MATCHER(atomicExpr);
REGISTER_MATCHER(atomicType);
REGISTER_MATCHER(autoType);
REGISTER_MATCHER(binaryOperator);
+ REGISTER_MATCHER(binaryConditionalOperator);
REGISTER_MATCHER(blockPointerType);
REGISTER_MATCHER(booleanType);
REGISTER_MATCHER(breakStmt);
@@ -161,6 +164,8 @@
REGISTER_MATCHER(declStmt);
REGISTER_MATCHER(defaultStmt);
REGISTER_MATCHER(dependentSizedArrayType);
+ REGISTER_MATCHER(designatedInitExpr);
+ REGISTER_MATCHER(designatorCountIs);
REGISTER_MATCHER(doStmt);
REGISTER_MATCHER(eachOf);
REGISTER_MATCHER(elaboratedType);
@@ -245,6 +250,7 @@
REGISTER_MATCHER(hasSizeExpr);
REGISTER_MATCHER(hasSourceExpression);
REGISTER_MATCHER(hasStaticStorageDuration);
+ REGISTER_MATCHER(hasSyntacticForm);
REGISTER_MATCHER(hasTargetDecl);
REGISTER_MATCHER(hasTemplateArgument);
REGISTER_MATCHER(hasThen);
@@ -259,6 +265,7 @@
REGISTER_MATCHER(ignoringParenCasts);
REGISTER_MATCHER(ignoringParenImpCasts);
REGISTER_MATCHER(implicitCastExpr);
+ REGISTER_MATCHER(implicitValueInitExpr);
REGISTER_MATCHER(incompleteArrayType);
REGISTER_MATCHER(initListExpr);
REGISTER_MATCHER(injectedClassNameType);
@@ -312,6 +319,7 @@
REGISTER_MATCHER(isVirtualAsWritten);
REGISTER_MATCHER(isVolatileQualified);
REGISTER_MATCHER(isWritten);
+ REGISTER_MATCHER(labelDecl);
REGISTER_MATCHER(labelStmt);
REGISTER_MATCHER(lambdaExpr);
REGISTER_MATCHER(lValueReferenceType);
@@ -336,12 +344,15 @@
REGISTER_MATCHER(objcObjectPointerType);
REGISTER_MATCHER(on);
REGISTER_MATCHER(onImplicitObjectArgument);
+ REGISTER_MATCHER(opaqueValueExpr);
REGISTER_MATCHER(parameterCountIs);
REGISTER_MATCHER(parenExpr);
+ REGISTER_MATCHER(parenListExpr);
REGISTER_MATCHER(parenType);
REGISTER_MATCHER(parmVarDecl);
REGISTER_MATCHER(pointee);
REGISTER_MATCHER(pointerType);
+ REGISTER_MATCHER(predefinedExpr);
REGISTER_MATCHER(qualType);
REGISTER_MATCHER(realFloatingPointType);
REGISTER_MATCHER(recordDecl);
@@ -350,6 +361,7 @@
REGISTER_MATCHER(refersToDeclaration);
REGISTER_MATCHER(refersToIntegralType);
REGISTER_MATCHER(refersToType);
+ REGISTER_MATCHER(requiresZeroInitialization);
REGISTER_MATCHER(returns);
REGISTER_MATCHER(returnStmt);
REGISTER_MATCHER(rValueReferenceType);
@@ -360,6 +372,7 @@
REGISTER_MATCHER(statementCountIs);
REGISTER_MATCHER(staticAssertDecl);
REGISTER_MATCHER(stmt);
+ REGISTER_MATCHER(stmtExpr);
REGISTER_MATCHER(stringLiteral);
REGISTER_MATCHER(substNonTypeTemplateParmExpr);
REGISTER_MATCHER(substTemplateTypeParmType);
Index: unittests/AST/MatchVerifier.h
===================================================================
--- unittests/AST/MatchVerifier.h
+++ unittests/AST/MatchVerifier.h
@@ -62,6 +62,9 @@
std::vector& Args,
Language L);
+ template
+ testing::AssertionResult match(const Decl *D, const MatcherType &AMatcher);
+
protected:
void run(const MatchFinder::MatchResult &Result) override;
virtual void verify(const MatchFinder::MatchResult &Result,
@@ -127,6 +130,22 @@
return testing::AssertionSuccess();
}
+/// \brief Runs a matcher over some AST, and returns the result of the
+/// verifier for the matched node.
+template template
+testing::AssertionResult MatchVerifier::match(
+ const Decl *D, const MatcherType &AMatcher) {
+ MatchFinder Finder;
+ Finder.addMatcher(AMatcher.bind(""), this);
+
+ setFailure("Could not find match");
+ Finder.match(*D, D->getASTContext());
+
+ if (!Verified)
+ return testing::AssertionFailure() << VerifyResult;
+ return testing::AssertionSuccess();
+}
+
template
void MatchVerifier::run(const MatchFinder::MatchResult &Result) {
const NodeType *Node = Result.Nodes.getNodeAs("");
Index: unittests/ASTMatchers/ASTMatchersTest.h
===================================================================
--- unittests/ASTMatchers/ASTMatchersTest.h
+++ unittests/ASTMatchers/ASTMatchersTest.h
@@ -126,6 +126,13 @@
}
template
+testing::AssertionResult matchesC99(const std::string &Code,
+ const T &AMatcher) {
+ return matchesConditionally(Code, AMatcher, true, "-std=c99",
+ FileContentMappings(), "input.c");
+}
+
+template
testing::AssertionResult notMatchesC(const std::string &Code,
const T &AMatcher) {
return matchesConditionally(Code, AMatcher, false, "", FileContentMappings(),
Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===================================================================
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -1209,7 +1209,12 @@
EXPECT_TRUE(matches("void f() { while(true) { continue; } }",
continueStmt()));
EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}", gotoStmt()));
- EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}", labelStmt()));
+ EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}",
+ labelStmt(
+ hasDeclaration(
+ labelDecl(hasName("FOO"))))));
+ EXPECT_TRUE(matches("void f() { FOO: ; void *ptr = &&FOO; goto *ptr; }",
+ addrLabelExpr()));
EXPECT_TRUE(matches("void f() { return; }", returnStmt()));
}
@@ -2527,6 +2532,82 @@
EXPECT_TRUE(matches("int* i = __null;", gnuNullExpr()));
}
+TEST(Matcher, AtomicExpr) {
+ EXPECT_TRUE(matches("void foo() { int *ptr; __atomic_load_n(ptr, 1); }",
+ atomicExpr()));
+}
+
+TEST(Matcher, Initializers) {
+ const char *ToMatch = "void foo() { struct point { double x; double y; };"
+ " struct point ptarray[10] = "
+ " { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 }; }";
+ EXPECT_TRUE(matchesConditionally(
+ ToMatch,
+ initListExpr(
+ has(
+ cxxConstructExpr(
+ requiresZeroInitialization())),
+ has(
+ initListExpr(
+ hasType(asString("struct point")),
+ has(floatLiteral(equals(1.0))),
+ has(implicitValueInitExpr(
+ hasType(asString("double")))))),
+ has(
+ initListExpr(
+ hasType(asString("struct point")),
+ has(floatLiteral(equals(2.0))),
+ has(floatLiteral(equals(1.0)))))
+ ), true, "-std=gnu++98"));
+
+ EXPECT_TRUE(matchesC99(ToMatch,
+ initListExpr(
+ hasSyntacticForm(
+ initListExpr(
+ has(
+ designatedInitExpr(
+ designatorCountIs(2),
+ has(floatLiteral(
+ equals(1.0))),
+ has(integerLiteral(
+ equals(2))))),
+ has(
+ designatedInitExpr(
+ designatorCountIs(2),
+ has(floatLiteral(
+ equals(2.0))),
+ has(integerLiteral(
+ equals(2))))),
+ has(
+ designatedInitExpr(
+ designatorCountIs(2),
+ has(floatLiteral(
+ equals(1.0))),
+ has(integerLiteral(
+ equals(0)))))
+ )))));
+}
+
+TEST(Matcher, ParenListExpr) {
+ EXPECT_TRUE(
+ matches(
+ " template class foo { void bar() { foo X(*this); } }; ",
+ varDecl(hasInitializer(parenListExpr(has(unaryOperator()))))));
+}
+
+TEST(Matcher, StmtExpr) {
+ EXPECT_TRUE(matches("void declToImport() { int C = ({int X=4; X;}); }",
+ varDecl(hasInitializer(stmtExpr()))));
+}
+
+TEST(Matcher, ImportPredefinedExpr) {
+ // __func__ expands as StringLiteral("foo")
+ EXPECT_TRUE(matches("void foo() { __func__; }",
+ predefinedExpr(
+ hasType(asString("const char [4]")),
+ has(stringLiteral()))));
+}
+
TEST(Matcher, AsmStatement) {
EXPECT_TRUE(matches("void foo() { __asm(\"mov al, 2\"); }", asmStmt()));
}
@@ -2750,6 +2831,28 @@
EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse));
EXPECT_TRUE(
notMatches("void x() { true ? false : true; }", ConditionalFalse));
+
+ EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse));
+ EXPECT_TRUE(
+ notMatches("void x() { true ? false : true; }", ConditionalFalse));
+}
+
+TEST(Matcher, BinaryConditionalOperator) {
+ StatementMatcher AlwaysOne = binaryConditionalOperator(
+ hasCondition(implicitCastExpr(
+ has(
+ opaqueValueExpr(
+ hasSourceExpression((integerLiteral(equals(1)))))))),
+ hasFalseExpression(integerLiteral(equals(0))));
+
+ EXPECT_TRUE(matches("void x() { 1 ?: 0; }", AlwaysOne));
+
+ StatementMatcher FourNotFive = binaryConditionalOperator(
+ hasTrueExpression(opaqueValueExpr(
+ hasSourceExpression((integerLiteral(equals(4)))))),
+ hasFalseExpression(integerLiteral(equals(5))));
+
+ EXPECT_TRUE(matches("void x() { 4 ?: 5; }", FourNotFive));
}
TEST(ArraySubscriptMatchers, ArraySubscripts) {