diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html index c6307954d7f1b..99917ccff5260 100644 --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -586,28 +586,36 @@
Matches class bases.
-Examples matches public virtual B.
+Given
class B {};
class C : public virtual B {};
+
+The matcher cxxRecordDecl(hasDirectBase(cxxBaseSpecifier()))
+matches C.
Matches constructor initializers.
-Examples matches i(42).
+Given
class C {
C() : i(42) {}
int i;
};
+
+The matcher cxxCtorInitializer()
+matches i(42).
Matches binding declarations
-Example matches foo and bar
-(matcher = bindingDecl()
- auto [foo, bar] = std::make_pair{42, 42};
+Given
+ struct pair { int x; int y; };
+ pair make(int, int);
+ auto [foo, bar] = make(42, 42);
+
+The matcher bindingDecl()
+matches foo and bar.
Matches C++ class template declarations.
-Example matches Z
+Given
template<class T> class Z {};
+
+The matcher classTemplateDecl()
+matches Z.
Matches concept declarations. -Example matches integral - template<typename T> - concept integral = std::is_integral_v<T>; +Given + template<typename T> concept my_concept = true; + + +The matcher conceptDecl() +matches template<typename T> +concept my_concept = true.
Matches C++ constructor declarations.
-Example matches Foo::Foo() and Foo::Foo(int)
+Given
class Foo {
public:
Foo();
Foo(int);
int DoSomething();
};
+
+ struct Bar {};
+
+
+The matcher cxxConstructorDecl()
+matches Foo() and Foo(int).
Matches conversion operator declarations.
-Example matches the operator.
+Given
class X { operator int() const; };
+
+
+The matcher cxxConversionDecl()
+matches operator int() const.
Matches user-defined and implicitly generated deduction guide.
-Example matches the deduction guide.
+Given
template<typename T>
- class X { X(int) };
+ class X { X(int); };
X(int) -> X<int>;
+
+
+The matcher cxxDeductionGuideDecl()
+matches the written deduction guide
+auto (int) -> X<int>,
+the implicit copy deduction guide auto (int) -> X<T>
+and the implicitly declared deduction guide
+auto (X<T>) -> X<T>.
Matches explicit C++ destructor declarations.
-Example matches Foo::~Foo()
+Given
class Foo {
public:
virtual ~Foo();
};
+
+ struct Bar {};
+
+
+The matcher cxxDestructorDecl()
+matches virtual ~Foo().
Matches method declarations.
-Example matches y
+Given
class X { void y(); };
+
+
+The matcher cxxMethodDecl()
+matches void y().
Matches C++ class declarations.
-Example matches X, Z
+Given
class X;
template<class T> class Z {};
+
+The matcher cxxRecordDecl()
+matches X and Z.
Matches declarations.
-Examples matches X, C, and the friend declaration inside C;
+Given
void X();
class C {
- friend X;
+ friend void X();
};
+
+The matcher decl()
+matches void X(), C
+and friend void X().
Matches decomposition-declarations.
-Examples matches the declaration node with foo and bar, but not
-number.
-(matcher = declStmt(has(decompositionDecl())))
-
+Given
+ struct pair { int x; int y; };
+ pair make(int, int);
int number = 42;
- auto [foo, bar] = std::make_pair{42, 42};
+ auto [foo, bar] = make(42, 42);
+
+The matcher decompositionDecl()
+matches auto [foo, bar] = make(42, 42),
+but does not match number.
Matches enum constants.
-Example matches A, B, C
+Given
enum X {
A, B, C
};
+The matcher enumConstantDecl()
+matches A, B and C.
Matches enum declarations.
-Example matches X
+Given
enum X {
A, B, C
};
+
+The matcher enumDecl()
+matches the enum X.
Matches field declarations.
Given
- class X { int m; };
-fieldDecl()
- matches 'm'.
+ int a;
+ struct Foo {
+ int x;
+ };
+ void bar(int val);
+
+The matcher fieldDecl()
+matches int x.
Matches function declarations. -Example matches f +Given void f(); + +The matcher functionDecl() +matches void f().
Matches a declaration of label.
Given
- goto FOO;
- FOO: bar();
-labelDecl()
- matches 'FOO:'
+ void bar();
+ void foo() {
+ goto FOO;
+ FOO: bar();
+ }
+The matcher labelDecl()
+matches FOO: bar().
Matches a declaration of anything that could have a name.
Example matches X, S, the anonymous union type, i, and U;
+Given
typedef int X;
struct S {
union {
int i;
} U;
};
+The matcher namedDecl()
+matches typedef int X, S, int i
+ and U,
+with S matching twice in C++.
+Once for the injected class name and once for the declaration itself.
Matches class, struct, and union declarations.
-Example matches X, Z, U, and S
+Given
class X;
template<class T> class Z {};
struct S {};
union U {};
+
+The matcher recordDecl()
+matches X, Z,
+S and U.
Matches a C++ static_assert declaration.
-Example:
- staticAssertDecl()
-matches
- static_assert(sizeof(S) == sizeof(int))
-in
+Given
struct S {
int x;
};
static_assert(sizeof(S) == sizeof(int));
+
+
+The matcher staticAssertDecl()
+matches static_assert(sizeof(S) == sizeof(int)).
Matches tag declarations.
-Example matches X, Z, U, S, E
+Given
class X;
template<class T> class Z {};
struct S {};
union U {};
- enum E {
- A, B, C
- };
+ enum E { A, B, C };
+
+
+The matcher tagDecl()
+matches class X, class Z {}, the injected class name
+class Z, struct S {},
+the injected class name struct S, union U {},
+the injected class name union U
+and enum E { A, B, C }.
Matches type alias template declarations.
-typeAliasTemplateDecl() matches
- template <typename T>
- using Y = X<T>;
+Given
+ template <typename T> struct X {};
+ template <typename T> using Y = X<T>;
+
+The matcher typeAliasTemplateDecl()
+matches template <typename T> using Y = X<T>.
Matches using-enum declarations.
Given
- namespace X { enum x {...}; }
+ namespace X { enum x { val1, val2 }; }
using enum X::x;
-usingEnumDecl()
- matches using enum X::x Matches any value declaration.
-Example matches A, B, C and F
+Given
enum X { A, B, C };
void F();
+ int V = 0;
+The matcher valueDecl()
+matches A, B, C, void F()
+and int V = 0.
Same as nestedNameSpecifier but matches NestedNameSpecifierLoc.
+
+Given
+ namespace ns {
+ struct A { static void f(); };
+ void A::f() {}
+ void g() { A::f(); }
+ }
+ ns::A a;
+
+
+The matcher nestedNameSpecifierLoc() matches
+A:: twice, and ns:: once.
Matches OpenMP ``default`` clause.
Given
+ void foo() {
+ #pragma omp parallel default(none)
+ ;
+ #pragma omp parallel default(shared)
+ ;
+ #pragma omp parallel default(private)
+ ;
+ #pragma omp parallel default(firstprivate)
+ ;
+ #pragma omp parallel
+ ;
+ }
- #pragma omp parallel default(none)
- #pragma omp parallel default(shared)
- #pragma omp parallel default(private)
- #pragma omp parallel default(firstprivate)
- #pragma omp parallel
-``ompDefaultClause()`` matches ``default(none)``, ``default(shared)``,
-`` default(private)`` and ``default(firstprivate)``
+The matcher
+ompExecutableDirective(hasAnyClause(ompDefaultClause())) matches
+#pragma omp parallel default(none),
+#pragma omp parallel default(shared),
+#pragma omp parallel default(private) and
+#pragma omp parallel default(firstprivate).
Matches QualTypes in the clang AST. + +Given + int a = 0; + const int b = 1; + +The matcher varDecl(hasType(qualType(isConstQualified()))) +matches const int b = 1, but not int a = 0.
Matches address of label statements (GNU extension).
Given
+void bar();
+void foo() {
FOO: bar();
void *ptr = &&FOO;
- goto *bar;
-addrLabelExpr()
- matches '&&FOO'
+ goto *ptr;
+}
+The matcher addrLabelExpr()
+matches &&FOO
The arrayInitIndexExpr consists of two subexpressions: a common expression
-(the source array) that is evaluated once up-front, and a per-element initializer
-that runs once for each array element. Within the per-element initializer,
-the current index may be obtained via an ArrayInitIndexExpr.
+(the source array) that is evaluated once up-front, and a per-element
+initializer that runs once for each array element. Within the per-element
+initializer, the current index may be obtained via an ArrayInitIndexExpr.
Given
- void testStructBinding() {
+ void testStructuredBinding() {
int a[2] = {1, 2};
auto [x, y] = a;
}
-arrayInitIndexExpr() matches the array index that implicitly iterates
-over the array `a` to copy each element to the anonymous array
-that backs the structured binding `[x, y]` elements of which are
-referred to by their aliases `x` and `y`.
+
+
+The matcher arrayInitIndexExpr() matches the array index
+that implicitly iterates over the array `a` to copy each element to the
+anonymous array that backs the structured binding.
Matches a loop initializing the elements of an array in a number of contexts: +@@ -1307,26 +1495,34 @@ Matches a loop initializing the elements of an array in a number of +contexts: * in the implicit copy/move constructor for a class with an array member * when a lambda-expression captures an array by value * when a decomposition declaration decomposes an array @@ -1293,13 +1482,12 @@Node Matchers
Given void testLambdaCapture() { int a[10]; - auto Lam1 = [a]() { - return; - }; + [a]() {}; } -arrayInitLoopExpr() matches the implicit loop that initializes each element of -the implicit array field inside the lambda object, that represents the array `a` -captured by value. + +The matcher arrayInitLoopExpr() matches the implicit loop that +initializes each element of the implicit array field inside the lambda +object, that represents the array a captured by value.Node Matchers
Matches array subscript expressions. Given - int i = a[1]; -arraySubscriptExpr() - matches "a[1]" + void foo() { + int a[2] = {0, 1}; + int i = a[1]; + } +The matcher arraySubscriptExpr() +matches a[1].Matcher<Stmt> asmStmt Matcher<AsmStmt>... Matches asm statements. +void foo() { int i = 100; - __asm("mov al, 2"); -asmStmt() - matches '__asm("mov al, 2")' + __asm("mov %al, 2"); +} +The matcher asmStmt() +matches __asm("mov %al, 2")Matcher<Stmt> atomicExpr Matcher<AtomicExpr>... @@ -1337,24 +1533,35 @@ Matches atomic builtins. -Example matches __atomic_load_n(ptr, 1) + +Given void foo() { int *ptr; __atomic_load_n(ptr, 1); } + +The matcher atomicExpr() matches __atomic_load_n(ptr, 1).Node Matchers
@autoreleasepool { int x = 0; } -autoreleasePoolStmt(stmt()) matches the declaration of "x" -inside the autorelease pool. + +The matcher autoreleasePoolStmt(stmt()) matches the declaration of +int x = 0 inside the autorelease pool.
Matches binary conditional operator expressions (GNU extension).
-Example matches a ?: b
- (a ?: b) + 42;
+Given
+ int f(int a, int b) {
+ return (a ?: b) + 42;
+ }
+
+The matcher binaryConditionalOperator() matches a ?: b.
Matches binary operator expressions.
-Example matches a || b
- !(a || b)
+Given
+ void foo(bool a, bool b) {
+ !(a || b);
+ }
+
+
+The matcher binaryOperator() matches a || b.
+
See also the binaryOperation() matcher for more-general matching.
Matches a reference to a block.
-Example: matches "^{}":
+Given
void f() { ^{}(); }
+
+
+The matcher blockExpr() matches ^{}.
Matches break statements.
Given
+void foo() {
while (true) { break; }
-breakStmt()
- matches 'break'
+}
+
+The matcher breakStmt()
+matches break
Matches a C-style cast expression. -Example: Matches (int) 2.2f in +Given int i = (int) 2.2f; + +The matcher cStyleCastExpr() +matches (int) 2.2f.
Matches call expressions.
Example matches x.y() and y()
- X x;
- x.y();
- y();
+ struct X { void foo(); };
+ void bar();
+ void foobar() {
+ X x;
+ x.foo();
+ bar();
+ }
+
+The matcher callExpr()
+matches x.foo() and bar();
Matches case statements inside switch statements.
Given
+void foo(int a) {
switch(a) { case 42: break; default: break; }
-caseStmt()
- matches 'case 42:'.
+}
+The matcher caseStmt()
+matches case 42: break.
Matches any cast nodes of Clang's AST.
-Example: castExpr() matches each of the following:
- (int) 3;
- const_cast<Expr *>(SubExpr);
- char c = 0;
-but does not match
- int i = (0);
- int k = 0;
+Given
+ struct S {};
+ const S* s;
+ S* s2 = const_cast<S*>(s);
+
+ const int val = 0;
+ char val0 = 1;
+ char val1 = (char)2;
+ char val2 = static_cast<char>(3);
+ int* val3 = reinterpret_cast<int*>(4);
+ char val4 = char(5);
+
+
+The matcher castExpr()
+matches
+const_cast<S*>(s) and the implicit l- to r-value cast for s,
+the implicit cast to char for the initializer 1,
+the c-style cast (char)2 and it's implicit cast to char
+(part of the c-style cast) 2,
+static_cast<char>(3) and it's implicit cast to char
+(part of the static_cast) 3,
+reinterpret_cast<int*>(4),
+char(5) and it's implicit cast to char
+(part of the functional cast) 5.
Matches GNU __builtin_choose_expr.
+
+Given
+ void f() { (void)__builtin_choose_expr(1, 2, 3); }
+
+The matcher chooseExpr() matches
+__builtin_choose_expr(1, 2, 3).
Matches co_await expressions.
Given
- co_await 1;
-coawaitExpr()
- matches 'co_await 1'
+ namespace std {
+ template <typename T = void>
+ struct coroutine_handle {
+ static constexpr coroutine_handle from_address(void* addr) {
+ return {};
+ }
+ };
+
+ struct always_suspend {
+ bool await_ready() const noexcept;
+ bool await_resume() const noexcept;
+ template <typename T>
+ bool await_suspend(coroutine_handle<T>) const noexcept;
+ };
+
+ template <typename T>
+ struct coroutine_traits {
+ using promise_type = T::promise_type;
+ };
+ } // namespace std
+
+ struct generator {
+ struct promise_type {
+ std::always_suspend yield_value(int&&);
+ std::always_suspend initial_suspend() const noexcept;
+ std::always_suspend final_suspend() const noexcept;
+ void return_void();
+ void unhandled_exception();
+ generator get_return_object();
+ };
+ };
+
+ std::always_suspend h();
+
+ generator g() { co_await h(); }
+
+The matcher
+coawaitExpr(has(callExpr(callee(functionDecl(hasName("h"))))))
+matches co_await h().
Matches compound (i.e. non-scalar) literals
Example match: {1}, (1, 2)
- int array[4] = {1};
- vector int myvec = (vector int)(1, 2);
+ struct vector { int x; int y; };
+ struct vector myvec = (struct vector){ 1, 2 };
+
+The matcher compoundLiteralExpr()
+matches (struct vector){ 1, 2 }.
Matches compound statements.
-Example matches '{}' and '{{}}' in 'for (;;) {{}}'
- for (;;) {{}}
+Given
+void foo() { for (;;) {{}} }
+
+The matcher compoundStmt() matches
+{ for (;;) {{}} }, {{}} and {}.
Matches conditional operator expressions.
-Example matches a ? b : c
- (a ? b : c) + 42
+Given
+ int f(int a, int b, int c) {
+ return (a ? b : c) + 42;
+ }
+
+The matcher conditionalOperator() matches a ? b : c.
Matches a constant expression wrapper.
-Example matches the constant in the case statement:
- (matcher = constantExpr())
- switch (a) {
- case 37: break;
+Given
+ void f(int a) {
+ switch (a) {
+ case 37: break;
+ }
}
+
+The matcher constantExpr() matches 37.
Matches continue statements.
Given
+void foo() {
while (true) { continue; }
-continueStmt()
- matches 'continue'
+}
+
+The matcher continueStmt()
+matches continue
Matches builtin function __builtin_convertvector.
+
+Given
+ typedef double vector4double __attribute__((__vector_size__(32)));
+ typedef float vector4float __attribute__((__vector_size__(16)));
+ vector4float vf;
+ void f() { (void)__builtin_convertvector(vf, vector4double); }
+
+The matcher convertVectorExpr() matches
+__builtin_convertvector(vf, vector4double).
Matches co_return statements.
Given
- while (true) { co_return; }
-coreturnStmt()
- matches 'co_return'
+ namespace std {
+ template <typename T = void>
+ struct coroutine_handle {
+ static constexpr coroutine_handle from_address(void* addr) {
+ return {};
+ }
+ };
+
+ struct always_suspend {
+ bool await_ready() const noexcept;
+ bool await_resume() const noexcept;
+ template <typename T>
+ bool await_suspend(coroutine_handle<T>) const noexcept;
+ };
+
+ template <typename T>
+ struct coroutine_traits {
+ using promise_type = T::promise_type;
+ };
+ } // namespace std
+
+ struct generator {
+ struct promise_type {
+ void return_value(int v);
+ std::always_suspend yield_value(int&&);
+ std::always_suspend initial_suspend() const noexcept;
+ std::always_suspend final_suspend() const noexcept;
+ void unhandled_exception();
+ generator get_return_object();
+ };
+ };
+
+ generator f() {
+ co_return 10;
+ }
+
+
+The matcher coreturnStmt(has(integerLiteral()))
+matches co_return 10
Matches coroutine body statements.
-coroutineBodyStmt() matches the coroutine below
- generator<int> gen() {
- co_return;
- }
+Given
+ namespace std {
+ template <typename T = void>
+ struct coroutine_handle {
+ static constexpr coroutine_handle from_address(void* addr) {
+ return {};
+ }
+ };
+
+ struct suspend_always {
+ bool await_ready() const noexcept;
+ bool await_resume() const noexcept;
+ template <typename T>
+ bool await_suspend(coroutine_handle<T>) const noexcept;
+ };
+
+ template <typename...>
+ struct coroutine_traits {
+ struct promise_type {
+ std::suspend_always initial_suspend() const noexcept;
+ std::suspend_always final_suspend() const noexcept;
+ void return_void();
+ void unhandled_exception();
+ coroutine_traits get_return_object();
+ };
+ };
+ } // namespace std
+
+ void f() { while (true) { co_return; } }
+
+
+
+The matcher coroutineBodyStmt() matches
+{ while (true) { co_return; } }.
Matches co_yield expressions.
Given
- co_yield 1;
-coyieldExpr()
- matches 'co_yield 1'
+ namespace std {
+ template <typename T = void>
+ struct coroutine_handle {
+ static constexpr coroutine_handle from_address(void* addr) {
+ return {};
+ }
+ };
+
+ struct always_suspend {
+ bool await_ready() const noexcept;
+ bool await_resume() const noexcept;
+ template <typename T>
+ bool await_suspend(coroutine_handle<T>) const noexcept;
+ };
+
+ template <typename T>
+ struct coroutine_traits {
+ using promise_type = T::promise_type;
+ };
+ } // namespace std
+
+ struct generator {
+ struct promise_type {
+ std::always_suspend yield_value(int&&);
+ std::always_suspend initial_suspend() const noexcept;
+ std::always_suspend final_suspend() const noexcept;
+ void return_void();
+ void unhandled_exception();
+ generator get_return_object();
+ };
+ };
+
+ generator f() {
+ while (true) {
+ co_yield 10;
+ }
+ }
+
+The matcher coyieldExpr()
+matches co_yield 10
Matches CUDA kernel call expression.
-Example matches,
- kernel<<<i,j>>>();
+Given
+ __global__ void kernel() {}
+ void f() {
+ kernel<<<32,32>>>();
+ }
+
+The matcher cudaKernelCallExpr()
+matches kernel<<<i, k>>>()
Matches nodes where temporaries are created.
-Example matches FunctionTakesString(GetStringByValue())
- (matcher = cxxBindTemporaryExpr())
- FunctionTakesString(GetStringByValue());
- FunctionTakesStringByPointer(GetStringPointer());
+Given
+ struct S {
+ S() { } // User defined constructor makes S non-POD.
+ ~S() { } // User defined destructor makes it non-trivial.
+ };
+ void test() {
+ const S &s_ref = S(); // Requires a CXXBindTemporaryExpr.
+ }
+
+The matcher cxxBindTemporaryExpr()
+matches the constructor call S().
Matches bool literals. Example matches true - true + bool Flag = true; + + +The matcher cxxBoolLiteral() matches true.
Matches catch statements.
+void foo() {
try {} catch(int i) {}
-cxxCatchStmt()
- matches 'catch(int i)'
+}
+
+The matcher cxxCatchStmt()
+matches catch(int i) {}
Matches a const_cast expression. -Example: Matches const_cast<int*>(&r) in +Given int n = 42; const int &r(n); int* p = const_cast<int*>(&r); + + +The matcher cxxConstCastExpr() +matches const_cast<int*>(&r).
Matches constructor call expressions (including implicit ones).
-Example matches string(ptr, n) and ptr within arguments of f
- (matcher = cxxConstructExpr())
+Given
+ struct string {
+ string(const char*);
+ string(const char*s, int n);
+ };
void f(const string &a, const string &b);
- char *ptr;
- int n;
- f(string(ptr, n), ptr);
+ void foo(char *ptr, int n) {
+ f(string(ptr, n), ptr);
+ }
+
+
+The matcher cxxConstructExpr() matches string(ptr, n)
+and ptr within arguments of f .
Matches the value of a default argument at the call site.
-Example matches the CXXDefaultArgExpr placeholder inserted for the
- default value of the second parameter in the call expression f(42)
- (matcher = cxxDefaultArgExpr())
+Given
void f(int x, int y = 0);
- f(42);
+ void g() {
+ f(42);
+ }
+
+
+The matcher callExpr(has(cxxDefaultArgExpr()))
+matches the CXXDefaultArgExpr placeholder inserted for the default value
+of the second parameter in the call expression f(42).
Matches delete expressions.
Given
- delete X;
-cxxDeleteExpr()
- matches 'delete X'.
+ void* operator new(decltype(sizeof(void*)));
+ void operator delete(void*);
+ struct X {};
+ void foo() {
+ auto* x = new X;
+ delete x;
+ }
+
+
+The matcher cxxDeleteExpr()
+matches delete x.
Matches a dynamic_cast expression.
-Example:
- cxxDynamicCastExpr()
-matches
- dynamic_cast<D*>(&b);
-in
+Given
struct B { virtual ~B() {} }; struct D : B {};
B b;
D* p = dynamic_cast<D*>(&b);
+
+
+The matcher cxxDynamicCastExpr()
+matches dynamic_cast<D*>(&b).
Matches C++17 fold expressions.
-Example matches `(0 + ... + args)`:
+Given
template <typename... Args>
auto sum(Args... args) {
return (0 + ... + args);
}
+
+
+The matcher cxxFoldExpr() matches (0 + ... + args).
Matches range-based for statements.
-cxxForRangeStmt() matches 'for (auto a : i)'
- int i[] = {1, 2, 3}; for (auto a : i);
- for(int j = 0; j < 5; ++j);
+Given
+ void foo() {
+ int i[] = {1, 2, 3}; for (auto a : i);
+ for(int j = 0; j < 5; ++j);
+ }
+
+The matcher cxxForRangeStmt()
+matches for (auto a : i);
Matches functional cast expressions
-Example: Matches Foo(bar);
- Foo f = bar;
- Foo g = (Foo) bar;
- Foo h = Foo(bar);
+Given
+ struct Foo {
+ Foo(int x);
+ };
+
+ void foo(int bar) {
+ Foo f = bar;
+ Foo g = (Foo) bar;
+ Foo h = Foo(bar);
+ }
+
+
+The matcher cxxFunctionalCastExpr()
+matches Foo(bar).
Matches member call expressions.
-Example matches x.y()
- X x;
- x.y();
+Given
+ struct X {
+ void y();
+ void m() { y(); }
+ };
+ void f();
+ void g() {
+ X x;
+ x.y();
+ f();
+ }
+
+
+The matcher cxxMemberCallExpr() matches x.y() and
+y(), but not f().
Matches new expressions.
Given
- new X;
-cxxNewExpr()
- matches 'new X'.
+ void* operator new(decltype(sizeof(void*)));
+ struct X {};
+ void foo() {
+ auto* x = new X;
+ }
+
+
+The matcher cxxNewExpr()
+matches new X.
Matches nullptr literal. + +Given + int a = 0; + int* b = 0; + int *c = nullptr; + + +The matcher cxxNullPtrLiteralExpr() matches nullptr.
Matches rewritten binary operators
Example matches use of "<":
- #include <compare>
struct HasSpaceshipMem {
int a;
- constexpr auto operator<=>(const HasSpaceshipMem&) const = default;
+ constexpr bool operator==(const HasSpaceshipMem&) const = default;
};
void compare() {
HasSpaceshipMem hs1, hs2;
- if (hs1 < hs2)
+ if (hs1 != hs2)
return;
}
+
+
+The matcher cxxRewrittenBinaryOperator() matches
+hs1 != hs2.
+
See also the binaryOperation() matcher for more-general matching
of this AST node.
Matches C++ initializer list expressions.
Given
- std::vector<int> a({ 1, 2, 3 });
- std::vector<int> b = { 4, 5 };
+ namespace std {
+ template <typename T>
+ class initializer_list {
+ const T* begin;
+ const T* end;
+ };
+ }
+ template <typename T> class vector {
+ public: vector(std::initializer_list<T>) {}
+ };
+
+ vector<int> a({ 1, 2, 3 });
+ vector<int> b = { 4, 5 };
int c[] = { 6, 7 };
- std::pair<int, int> d = { 8, 9 };
-cxxStdInitializerListExpr()
- matches "{ 1, 2, 3 }" and "{ 4, 5 }"
+ struct pair { int x; int y; };
+ pair d = { 8, 9 };
+
+The matcher cxxStdInitializerListExpr()
+matches { 1, 2, 3 } and { 4, 5 }.
Matches functional cast expressions having N != 1 arguments
-Example: Matches Foo(bar, bar)
- Foo h = Foo(bar, bar);
+Given
+ struct Foo {
+ Foo(int x, int y);
+ };
+
+ void foo(int bar) {
+ Foo h = Foo(bar, bar);
+ }
+
+
+The matcher cxxTemporaryObjectExpr()
+matches Foo(bar, bar).
Matches implicit and explicit this expressions. ++ Matcher<Stmt> cxxThisExpr Matcher<CXXThisExpr>... Matches implicit and explicit this expressions. + +Given + struct foo { + int i; + int f() { return i; } + int g() { return this->i; } + }; + -Example matches the implicit this expression in "return i". - (matcher = cxxThisExpr()) -struct foo { - int i; - int f() { return i; } -}; +The matcher cxxThisExpr() +matches this of this->i and the implicit this expression +of i.Matcher<Stmt> cxxThrowExpr Matcher<CXXThrowExpr>... Matches throw expressions. +void foo() { try { throw 5; } catch(int i) {} -cxxThrowExpr() - matches 'throw 5' +} + +The matcher cxxThrowExpr() +matches throw 5Matcher<Stmt> cxxTryStmt Matcher<CXXTryStmt>... Matches try statements. +void foo() { try {} catch(int i) {} -cxxTryStmt() - matches 'try {}' +} + +The matcher cxxTryStmt() +matches try {} catch(int i) {}Matcher<Stmt> cxxUnresolvedConstructExpr Matcher<CXXUnresolvedConstructExpr>... Matches unresolved constructor call expressions. -Example matches T(t) in return statement of f - (matcher = cxxUnresolvedConstructExpr()) +Given template <typename T> void f(const T& t) { return T(t); } + + +The matcher cxxUnresolvedConstructExpr() matches +T(t).Matcher<Stmt> declRefExpr Matcher<DeclRefExpr>... @@ -1836,9 +2396,11 @@ Matches expressions that refer to declarations. -Example matches x in if (x) - bool x; - if (x) {} +Given + void f(bool x) { + if (x) {} + } + + +The matcher declRefExpr() matches x.Node Matchers
@@ -1846,22 +2408,75 @@ Matches declaration statements. Given - int a; -declStmt() - matches 'int a'. + void foo() { + int a; + } +The matcher declStmt() +matches int a;.Node Matchers
Matches default statements inside switch statements. Given +void foo(int a) { switch(a) { case 42: break; default: break; } -defaultStmt() - matches 'default:'. +} +The matcher defaultStmt() +matches default: break.Matcher<Stmt> dependentCoawaitExpr Matcher<DependentCoawaitExpr>... Matches co_await expressions where the type of the promise is dependent + +Given + namespace std { + template <typename T = void> + struct coroutine_handle { + static constexpr coroutine_handle from_address(void* addr) { + return {}; + } + }; + + struct always_suspend { + bool await_ready() const noexcept; + bool await_resume() const noexcept; + template <typename T> + bool await_suspend(coroutine_handle<T>) const noexcept; + }; + + template <typename T> + struct coroutine_traits { + using promise_type = T::promise_type; + }; + } // namespace std + + template <typename T> + struct generator { + struct promise_type { + std::always_suspend yield_value(int&&); + std::always_suspend initial_suspend() const noexcept; + std::always_suspend final_suspend() const noexcept; + void return_void(); + void unhandled_exception(); + generator get_return_object(); + }; + }; + + template <typename T> + std::always_suspend h(); + + template <> + std::always_suspend h<void>(); + + template<typename T> + generator<T> g() { co_await h<T>(); } + +The matcher dependentCoawaitExpr() +matches co_await h<T>().Matcher<Stmt> designatedInitExpr Matcher<DesignatedInitExpr>... @@ -1869,9 +2484,12 @@ 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 }; +Example: Given + struct point2 { double x; double y; }; + struct point2 ptarray[10] = { [0].x = 1.0 }; + struct point2 pt = { .x = 2.0 }; + +The matcher designatedInitExpr() +matches [0].x = 1.0 and .x = 2.0.Node Matchers
@@ -1889,18 +2507,36 @@ Matches do statements. Given +void foo() { do {} while (true); -doStmt() - matches 'do {} while(true)' +} + +The matcher doStmt() +matches do {} while (true)Node Matchers
See also: hasDestinationType. -Example: matches all five of the casts in - int((int)(reinterpret_cast<int>(static_cast<int>(const_cast<int>(42))))) -but does not match the implicit conversion in - long ell = 42; + struct S {}; + const S* s; + S* s2 = const_cast<S*>(s); + + const int val = 0; + char val0 = val; + char val1 = (char)val; + char val2 = static_cast<char>(val); + int* val3 = reinterpret_cast<int*>(val); + char val4 = char(val); + + +The matcher explicitCastExpr() +matches (char)val, static_cast<char>(val), +reinterpret_cast<int*>(val), const_cast<S*>(s) +and char(val), but not the initialization of val0 with +val.
Matches expressions.
-Example matches x()
- void f() { x(); }
+Given
+ int f(int x, int y) { return x + y; }
+
+The matcher expr() matches x + y once,
+x twice and y twice, matching the
+DeclRefExpr , and the ImplicitCastExpr that does an l- to r-value
+cast.
Matches fixed point literals
+
+Given
+ void f() {
+ 0.0k;
+ }
+
+
+The matcher fixedPointLiteral() matches 0.0k.
Matches float literals of all sizes / encodings, e.g. 1.0, 1.0f, 1.0L and 1e10. -Does not match implicit conversions such as - float a = 10; +Given + int a = 1.0; + int b = 1.0F; + int c = 1.0L; + int d = 1e10; + int e = 1; + +The matcher floatLiteral() matches +1.0, 1.0F, 1.0L and 1e10, but does not match +1.
Matches for statements.
-Example matches 'for (;;) {}'
- for (;;) {}
- int i[] = {1, 2, 3}; for (auto a : i);
+Given
+ void foo() {
+ for (;;) {}
+ int i[] = {1, 2, 3}; for (auto a : i);
+ }
+
+
+The matcher forStmt() matches for (;;) {},
+but not for (auto a : i);.
Matches C11 _Generic expression.
+
+Given
+ double fdouble(double);
+ float ffloat(float);
+ #define GENERIC_MACRO(X) _Generic((X), double: fdouble, float: ffloat)(X)
+
+ void f() {
+ GENERIC_MACRO(0.0);
+ GENERIC_MACRO(0.0F);
+ }
+
+
+The matcher genericSelectionExpr() matches
+the generic selection expression that is expanded in
+GENERIC_MACRO(0.0) and GENERIC_MACRO(0.0F).
Matches GNU __null expression. + +Given + auto val = __null; + + +The matcher gnuNullExpr() matches __null.
Matches goto statements.
Given
+void bar();
+void foo() {
goto FOO;
FOO: bar();
-gotoStmt()
- matches 'goto FOO'
+}
+The matcher gotoStmt()
+matches goto FOO
Matches if statements.
-Example matches 'if (x) {}'
- if (x) {}
+Given
+ void foo(int x) {
+ if (x) {}
+ }
+
+The matcher ifStmt() matches if (x) {}.
Matches imaginary literals, which are based on integer and floating point literals e.g.: 1i, 1.0i + +Given + auto a = 1i; + auto b = 1.0i; + + +The matcher imaginaryLiteral() matches 1i and +1.0i.
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)
+ struct point { double x; double y; };
+ struct point pt = { .x = 42.0 };
+The matcher
+initListExpr(has(implicitValueInitExpr().bind("implicit")))
+matches { .x = 42.0 }.
Matches label statements.
Given
+void bar();
+void foo() {
goto FOO;
FOO: bar();
-labelStmt()
- matches 'FOO:'
+}
+The matcher labelStmt()
+matches FOO: bar()
Matches lambda expressions.
-Example matches [&](){return 5;}
- [&](){return 5;}
+Given
+ void f() {
+ []() { return 5; };
+ }
+
+
+The matcher lambdaExpr() matches []() { return 5; }.
Matches null statements.
+void foo() {
foo();;
-nullStmt()
- matches the second ';'
+}
+The matcher nullStmt()
+matches the second ;
Matches a reference to an ObjCIvar.
-Example: matches "a" in "init" method:
+Given
@implementation A {
NSString *a;
}
- (void) init {
a = @"hello";
}
+
+
+The matcher objcIvarRefExpr() matches a.
Matches Objective-C statements. Example matches @throw obj; +
Matches any ``#pragma omp`` executable directive.
Given
+ void foo() {
+ #pragma omp parallel
+ {}
+ #pragma omp parallel default(none)
+ {
+ #pragma omp taskyield
+ }
+ }
- #pragma omp parallel
- #pragma omp parallel default(none)
- #pragma omp taskyield
-
-``ompExecutableDirective()`` matches ``omp parallel``,
-``omp parallel default(none)`` and ``omp taskyield``.
+The matcher ompExecutableDirective()
+matches #pragma omp parallel,
+#pragma omp parallel default(none)
+and #pragma omp taskyield.
Matches parentheses used in expressions.
-Example matches (foo() + 1)
+Given
int foo() { return 1; }
- int a = (foo() + 1);
+ int bar() {
+ int a = (foo() + 1);
+ }
+
+The matcher parenExpr() matches (foo() + 1).
Matches predefined identifier expressions [C99 6.4.2.2].
Example: Matches __func__
- printf("%s", __func__);
+ void f() {
+ const char* func_name = __func__;
+ }
+
+The matcher predefinedExpr()
+matches __func__.
Matches return statements.
Given
+int foo() {
return 1;
-returnStmt()
- matches 'return 1'
+}
+The matcher returnStmt()
+matches return 1
Matches statements.
Given
- { ++a; }
-stmt()
- matches both the compound statement '{ ++a; }' and '++a'.
+ void foo(int a) { { ++a; } }
+The matcher stmt()
+matches the function body itself { { ++a; } }, the compound
+statement { ++a; }, the expression ++a and a.
Matches statement expression (GNU extension).
-Example match: ({ int X = 4; X; })
- int C = ({ int X = 4; X; });
+Given
+ void f() {
+ int C = ({ int X = 4; X; });
+ }
+
+The matcher stmtExpr() matches ({ int X = 4; X; }).
Matches string literals (also matches wide string literals). -Example matches "abcd", L"abcd" +Given char *s = "abcd"; wchar_t *ws = L"abcd"; + + +The matcher stringLiteral() matches "abcd" and +L"abcd".
Matches case and default statements inside switch statements.
Given
+void foo(int a) {
switch(a) { case 42: break; default: break; }
-switchCase()
- matches 'case 42:' and 'default:'.
+}
+The matcher switchCase()
+matches case 42: break and default: break
Matches switch statements.
Given
+void foo(int a) {
switch(a) { case 42: break; default: break; }
-switchStmt()
- matches 'switch(a)'.
+}
+The matcher switchStmt()
+matches switch(a) { case 42: break; default: break; }.
Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL) Given - Foo x = bar; + int x = 42; int y = sizeof(x) + alignof(x); -unaryExprOrTypeTraitExpr() - matches sizeof(x) and alignof(x) + +The matcher unaryExprOrTypeTraitExpr() +matches sizeof(x) and alignof(x)
Matches unary operator expressions.
Example matches !a
- !a || b
+ void foo(bool a, bool b) {
+ !a || b;
+ }
+
+
+The matcher unaryOperator() matches !a.
Matches user defined literal operator call. Example match: "foo"_suffix +Given + float operator ""_foo(long double); + float a = 1234.5_foo; + + +The matcher userDefinedLiteral() matches 1234.5_foo.
Matches while statements.
Given
+void foo() {
while (true) {}
-whileStmt()
- matches 'while (true) {}'.
+}
+
+The matcher whileStmt()
+matches while (true) {}.
Matches template name.
Given
- template <typename T> class X { };
- X<int> xi;
-templateName()
- matches 'X' in X<int>.
+ template<template <typename> class S> class X {};
+ template<typename T> class Y {};
+ X<Y> xi;
+
+The matcher
+classTemplateSpecializationDecl(hasAnyTemplateArgument(
+ refersToTemplate(templateName())))
+matches the specialization class X<Y>
Matches TypeLocs in the clang AST.
+
+That is, information about a type and where it was written.
+
+ void foo(int val);
+
+The matcher declaratorDecl(hasTypeLoc(typeLoc().bind("type")))
+matches void foo(int val) and int val, with
+typeLoc() matching void and
+int respectively.
Matches types nodes representing C++11 auto types.
-Given:
- auto n = 4;
- int v[] = { 2, 3 }
- for (auto i : v) { }
-autoType()
- matches "auto n" and "auto i"
+Given
+ void foo() {
+ auto n = 4;
+ int v[] = { 2, 3 };
+ for (auto i : v) { };
+ }
+
+The matcher autoType()
+matches the auto of n and i ,
+as well as the auto types for the implicitly generated code of the range-for
+loop (for the range, the begin iterator and the end iterator).
Matches builtin Types.
Given
- struct A {};
- A a;
+ enum E { Ok };
+ enum E e;
int b;
float c;
- bool d;
-builtinType()
- matches "int b", "float c" and "bool d"
+The matcher varDecl(hasType(builtinType()))
+matches int b and float c.
Matches C arrays with a specified constant size.
Given
- void() {
+ void foo() {
int a[2];
int b[] = { 2, 3 };
int c[b[0]];
}
-constantArrayType()
- matches "int a[2]"
+The matcher constantArrayType()
+int[2]
Matches decayed type
-Example matches i[] in declaration of f.
- (matcher = valueDecl(hasType(decayedType(hasDecayedType(pointerType())))))
-Example matches i[1].
- (matcher = expr(hasType(decayedType(hasDecayedType(pointerType())))))
void f(int i[]) {
i[1] = 0;
}
-Matches types nodes representing C++11 decltype(<expr>) types. -Given: +Given short i = 1; int j = 42; decltype(i + j) result = i + j; -decltypeType() - matches "decltype(i + j)" + +The matcher decltypeType() +decltype(i + j)
Matches injected class name types.
-Example matches S s, but not S<T> s.
- (matcher = parmVarDecl(hasType(injectedClassNameType())))
+Given
template <typename T> struct S {
void f(S s);
void g(S<T> s);
};
+
+The matcher
+parmVarDecl(hasType(elaboratedType(namesType(injectedClassNameType()))))
+matches S s, but not s}
Matches lvalue reference types. -Given: +Given int *a; int &b = *a; int &&c = 1; @@ -2655,8 +3523,11 @@Node Matchers
auto &&f = 2; int g = 5; -lValueReferenceType() matches the types of b, d, and e. e is -matched since the type is deduced as int& by reference collapsing rules. + +The matcher lValueReferenceType() matches the type +int & of b and the type auto & +of d. +FIXME: figure out why auto changechange matches twice
Matches member pointer types.
Given
- struct A { int i; }
- A::* ptr = A::i;
-memberPointerType()
- matches "A::* ptr"
+ struct A { int i; };
+ int A::* ptr = &A::i;
+
+The matcher memberPointerType()
+matches int struct A::*.
Matches rvalue reference types. -Given: +Given int *a; int &b = *a; int &&c = 1; @@ -2738,8 +3623,10 @@Node Matchers
auto &&f = 2; int g = 5; -rValueReferenceType() matches the types of c and f. e is not -matched as it is deduced to int& by reference collapsing rules. + +The matcher rValueReferenceType() matches the type +int && of c and the type +auto && of f.
Matches tag types (record and enum types).
Given
- enum E {};
+ enum E { Ok };
class C {};
E e;
C c;
-tagType() matches the type of the variable declarations of both e
-and c.
+
+The matcher tagType() matches the type
+enum E of variable e and the type
+class C three times, once for the type
+of the variable c , once for the type of the class definition and once of
+the type in the injected class name.
Matches template type parameter types. -Example matches T, but not int. - (matcher = templateTypeParmType()) +Given template <typename T> void f(int i); + +The matcher templateTypeParmType() matches T, +but does not match int.
Matches Types in the clang AST.
+
+Given
+ const int b = 1;
+
+The matcher varDecl(hasType(type().bind("type")))
+matches const int b = 1, with type()
+matching int.
Matches types nodes representing unary type transformations.
-Given:
- typedef __underlying_type(T) type;
-unaryTransformType()
- matches "__underlying_type(T)"
+Given
+ template <typename T> struct A {
+ typedef __underlying_type(T) type;
+ };
+
+The matcher unaryTransformType()
+matches __underlying_type(T)
Matches if all given matchers match.
Usable as: Any Matcher
+
+ int v0 = 0;
+ int v1 = 1;
+
+The matcher varDecl(allOf(hasName("v0"), hasType(isInteger())))
+matches int v0 = 0.
Matches if any of the given matchers matches.
Usable as: Any Matcher
+
+ char v0 = 'a';
+ int v1 = 1;
+ float v2 = 2.0;
+
+The matcher varDecl(anyOf(hasName("v0"), hasType(isInteger())))
+matches char v0 = 'a' and int v1 = 1.
Matches any of the NodeMatchers with InnerMatchers nested within
Given
- if (true);
- for (; true; );
-with the matcher
- mapAnyOf(ifStmt, forStmt).with(
- hasCondition(cxxBoolLiteralExpr(equals(true)))
- ).bind("trueCond")
-matches the if and the for. It is equivalent to:
- auto trueCond = hasCondition(cxxBoolLiteralExpr(equals(true)));
- anyOf(
- ifStmt(trueCond).bind("trueCond"),
- forStmt(trueCond).bind("trueCond")
- );
+ void f() {
+ if (true);
+ for (; true; );
+ }
+
+
+The matcher stmt(mapAnyOf(ifStmt, forStmt).with(
+ hasCondition(cxxBoolLiteral(equals(true)))
+ )),
+which is equivalent to
+stmt(anyOf(
+ ifStmt(hasCondition(cxxBoolLiteral(equals(true)))).bind("trueCond"),
+ forStmt(hasCondition(cxxBoolLiteral(equals(true)))).bind("trueCond")
+ )),
+matches if (true); and for (; true; );.
The with() chain-call accepts zero or more matchers which are combined
as-if with allOf() in each of the node matchers.
+
Usable as: Any Matcher
Matches if the provided matcher does not match.
-Example matches Y (matcher = cxxRecordDecl(unless(hasName("X"))))
+Given
class X {};
class Y {};
+The matcher cxxRecordDecl(unless(hasName("X")))
+matches Y
+
Usable as: Any Matcher
Matches an entity that has been implicitly added by the compiler (e.g.
implicit default/copy constructors).
+
+Given
+ struct S {};
+ void f(S obj) {
+ S copy = obj;
+ [&](){ return copy; };
+ }
+
+
+The matcher cxxConstructorDecl(isImplicit(), isCopyConstructor())
+matches the implicit copy constructor of S.
+The matcher lambdaExpr(forEachLambdaCapture(
+ lambdaCapture(isImplicit()))) matches [&](){ return copy; },
+because it implicitly captures copy .
Matches operator expressions (binary or unary) that have any of the
specified names.
- hasAnyOperatorName("+", "-")
- Is equivalent to
- anyOf(hasOperatorName("+"), hasOperatorName("-"))
+It provides a compact way of writing if an operator has any of the specified
+names:
+The matcher
+ hasAnyOperatorName("+", "-")
+Is equivalent to
+ hasOperatorName("-"))}
+
+Given
+void foo(bool a, bool b) {
+ !(a || b);
+ }
+
+void bar(bool a, bool b) {
+ a && b;
+ }
+
+The matcher binaryOperator(hasAnyOperatorName("||", "&&"))
+matches a || b and a && b.
+The matcher unaryOperator(hasAnyOperatorName("-", "!"))
+matches !(a || b).
Matches the operator Name of operator expressions and fold expressions
(binary or unary).
-Example matches a || b (matcher = binaryOperator(hasOperatorName("||")))
- !(a || b)
+Given
+void foo(bool a, bool b) {
+ !(a || b);
+ }
+
+The matcher binaryOperator(hasOperatorName("||"))
+matches a || b
-Example matches `(0 + ... + args)`
- (matcher = cxxFoldExpr(hasOperatorName("+")))
+Given
template <typename... Args>
auto sum(Args... args) {
return (0 + ... + args);
}
+
+The matcher cxxFoldExpr(hasOperatorName("+"))
+ matches (0 + ... + args).
Matches all kinds of assignment operators.
-Example 1: matches a += b (matcher = binaryOperator(isAssignmentOperator()))
+Given
+void foo(int a, int b) {
if (a == b)
a += b;
+}
+The matcher binaryOperator(isAssignmentOperator())
+matches a += b.
-Example 2: matches s1 = s2
- (matcher = cxxOperatorCallExpr(isAssignmentOperator()))
+Given
struct S { S& operator=(const S&); };
void x() { S s1, s2; s1 = s2; }
+
+The matcher cxxOperatorCallExpr(isAssignmentOperator())
+matches s1 = s2.
Matches comparison operators.
-Example 1: matches a == b (matcher = binaryOperator(isComparisonOperator()))
+Given
+void foo(int a, int b) {
if (a == b)
a += b;
+}
+The matcher binaryOperator(isComparisonOperator())
+matches a == b
-Example 2: matches s1 < s2
- (matcher = cxxOperatorCallExpr(isComparisonOperator()))
+Given
struct S { bool operator<(const S& other); };
void x(S s1, S s2) { bool b1 = s1 < s2; }
+
+The matcher cxxOperatorCallExpr(isComparisonOperator())
+matches s1 < s2
Matches private C++ declarations and C++ base specifers that specify private
inheritance.
-Examples:
+Given
class C {
public: int a;
protected: int b;
- private: int c; // fieldDecl(isPrivate()) matches 'c'
+ private: int c;
};
+The matcher fieldDecl(isPrivate())
+matches c.
+
struct Base {};
- struct Derived1 : private Base {}; // matches 'Base'
- class Derived2 : Base {}; // matches 'Base'
+ struct Derived1 : private Base {}; // Base
+ class Derived2 : Base {}; // Base
+
+The matcher
+cxxRecordDecl(hasAnyBase(cxxBaseSpecifier(isPrivate()).bind("base")))
+matches Derived1 and Derived2, with
+cxxBaseSpecifier(isPrivate()) matching
+Base.
Matches protected C++ declarations and C++ base specifers that specify
protected inheritance.
-Examples:
+Given
class C {
public: int a;
- protected: int b; // fieldDecl(isProtected()) matches 'b'
+ protected: int b;
private: int c;
};
+The matcher fieldDecl(isProtected())
+matches b.
+
class Base {};
- class Derived : protected Base {}; // matches 'Base'
+ class Derived : protected Base {};
+
+The matcher
+cxxRecordDecl(hasAnyBase(cxxBaseSpecifier(isProtected()).bind("base")))
+matches Derived, with
+cxxBaseSpecifier(isProtected()) matching
+Base.
Matches public C++ declarations and C++ base specifers that specify public
inheritance.
-Examples:
+Given
class C {
- public: int a; // fieldDecl(isPublic()) matches 'a'
+ public: int a;
protected: int b;
private: int c;
};
+The matcher fieldDecl(isPublic())
+matches a.
+
+Given
class Base {};
- class Derived1 : public Base {}; // matches 'Base'
- struct Derived2 : Base {}; // matches 'Base'
+ class Derived1 : public Base {};
+ struct Derived2 : Base {};
+
+The matcher
+cxxRecordDecl(hasAnyBase(cxxBaseSpecifier(isPublic()).bind("base")))
+matches Derived1 and Derived2,
+with cxxBaseSpecifier(isPublic()) matching
+public Base and Base.
Matches declarations of virtual methods and C++ base specifers that specify
virtual inheritance.
-Example:
+Given
class A {
public:
virtual void x(); // matches x
};
-Example:
- class Base {};
- class DirectlyDerived : virtual Base {}; // matches Base
- class IndirectlyDerived : DirectlyDerived, Base {}; // matches Base
+The matcher cxxMethodDecl(isVirtual())
+matches x.
+
+Given
+ struct Base {};
+ struct DirectlyDerived : virtual Base {}; // matches Base
+ struct IndirectlyDerived : DirectlyDerived, Base {}; // matches Base
+
+The matcher
+cxxRecordDecl(hasDirectBase(cxxBaseSpecifier(isVirtual())))
+matches DirectlyDerived.
Usable as: Matcher<CXXMethodDecl>, Matcher<CXXBaseSpecifier>
Matches literals that are equal to the given value of type ValueT.
Given
+void f(char, bool, double, int);
+void foo() {
f('false, 3.14, 42);
-characterLiteral(equals(0))
- matches 'cxxBoolLiteral(equals(false)) and cxxBoolLiteral(equals(0))
- match false
-floatLiteral(equals(3.14)) and floatLiteral(equals(314e-2))
- match 3.14
-integerLiteral(equals(42))
- matches 42
+}
+
+The matcher characterLiteral(equals(0U)) matches 'The matchers cxxBoolLiteral(equals(false)) and
+cxxBoolLiteral(equals(0)) match false.
+The matcher floatLiteral(equals(3.14)) matches 3.14.
+The matcher integerLiteral(equals(42)) matches 42.
Note that you cannot directly match a negative numeric literal because the
minus sign is not part of the literal: It is a unary operator whose operand
is the positive numeric literal. Instead, you must use a unaryOperator()
matcher to match the minus sign:
-unaryOperator(hasOperatorName("-"),
- hasUnaryOperand(integerLiteral(equals(13))))
+Given
+ int val = -1;
+
+The matcher unaryOperator(hasOperatorName("-"),
+ hasUnaryOperand(integerLiteral(equals(1))))
+matches -1.
Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteralExpr>,
Matcher<FloatingLiteral>, Matcher<IntegerLiteral>
@@ -3130,14 +4168,15 @@ Narrowing Matchers
Matches a C++ catch statement that has a catch-all handler.
Given
- try {
- // ...
- } catch (int) {
- // ...
- } catch (...) {
- // ...
+ void foo() {
+ try {}
+ catch (int) {}
+ catch (...) {}
}
-cxxCatchStmt(isCatchAll()) matches catch(...) but not catch(int).
+
+The matcher cxxCatchStmt(isCatchAll())
+matches catch (...) {}
+but does not match catch(int)
@@ -3145,12 +4184,15 @@ Narrowing Matchers
Checks that a call expression or a constructor call expression has at least
the specified number of arguments (including absent default arguments).
-Example matches f(0, 0) and g(0, 0, 0)
-(matcher = callExpr(argumentCountAtLeast(2)))
+Given
void f(int x, int y);
void g(int x, int y, int z);
- f(0, 0);
- g(0, 0, 0);
+ void foo() {
+ f(0, 0);
+ g(0, 0, 0);
+ }
+The matcher callExpr(argumentCountAtLeast(2))
+matches f(0, 0) and g(0, 0, 0)
@@ -3158,14 +4200,39 @@ Narrowing Matchers
Checks that a call expression or a constructor call expression has
a specific number of arguments (including absent default arguments).
-Example matches f(0, 0) (matcher = callExpr(argumentCountIs(2)))
+Given
void f(int x, int y);
- f(0, 0);
+ void foo() {
+ f(0, 0);
+ }
+The matcher callExpr(argumentCountIs(2))
+matches f(0, 0)
Matcher<CXXConstructExpr> isListInitialization
Matches a constructor call expression which uses list initialization.
+
+Given
+ namespace std {
+ template <typename T>
+ class initializer_list {
+ const T* begin;
+ const T* end;
+ };
+ }
+ template <typename T> class vector {
+ public: vector(std::initializer_list<T>) {}
+ };
+
+ vector<int> a({ 1, 2, 3 });
+ vector<int> b = { 4, 5 };
+ int c[] = { 6, 7 };
+ struct pair { int x; int y; };
+ pair d = { 8, 9 };
+
+The matcher cxxConstructExpr(isListInitialization())
+matches { 4, 5 }.
@@ -3175,11 +4242,15 @@ Narrowing Matchers
Given
void foo() {
- struct point { double x; double y; };
- point pt[2] = { { 1.0, 2.0 } };
+ struct Foo {
+ double x;
+ };
+ auto Val = Foo();
}
-initListExpr(has(cxxConstructExpr(requiresZeroInitialization()))
-will match the implicit array filler for pt[1].
+
+The matcher
+cxxConstructExpr(requiresZeroInitialization())
+matches Foo() because the x member has to be zero initialized.
Matches the operator Name of operator expressions and fold expressions
(binary or unary).
-Example matches a || b (matcher = binaryOperator(hasOperatorName("||")))
- !(a || b)
+Given
+void foo(bool a, bool b) {
+ !(a || b);
+ }
+
+The matcher binaryOperator(hasOperatorName("||"))
+matches a || b
-Example matches `(0 + ... + args)`
- (matcher = cxxFoldExpr(hasOperatorName("+")))
+Given
template <typename... Args>
auto sum(Args... args) {
return (0 + ... + args);
}
+
+The matcher cxxFoldExpr(hasOperatorName("+"))
+ matches (0 + ... + args).
Matches binary fold expressions, i.e. fold expressions with an initializer.
-Example matches `(0 + ... + args)`
- (matcher = cxxFoldExpr(isBinaryFold()))
+Given
template <typename... Args>
auto sum(Args... args) {
return (0 + ... + args);
@@ -3478,14 +4626,17 @@ Narrowing Matchers
auto multiply(Args... args) {
return (args * ...);
}
+
+
+The matcher cxxFoldExpr(isBinaryFold())
+matches (0 + ... + args).
Matches left-folding fold expressions.
-Example matches `(0 + ... + args)`
- (matcher = cxxFoldExpr(isLeftFold()))
+Given
template <typename... Args>
auto sum(Args... args) {
return (0 + ... + args);
@@ -3495,14 +4646,17 @@ Narrowing Matchers
auto multiply(Args... args) {
return (args * ... * 1);
}
+
+
+The matcher cxxFoldExpr(isLeftFold())
+matches (0 + ... + args).
Matches right-folding fold expressions.
-Example matches `(args * ... * 1)`
- (matcher = cxxFoldExpr(isRightFold()))
+Given
template <typename... Args>
auto sum(Args... args) {
return (0 + ... + args);
@@ -3512,6 +4666,10 @@ Narrowing Matchers
auto multiply(Args... args) {
return (args * ... * 1);
}
+
+
+The matcher cxxFoldExpr(isRightFold())
+matches (args * ... * 1).
Matches unary fold expressions, i.e. fold expressions without an
initializer.
-Example matches `(args * ...)`
- (matcher = cxxFoldExpr(isUnaryFold()))
+Given
template <typename... Args>
auto sum(Args... args) {
return (0 + ... + args);
@@ -3530,6 +4687,10 @@ Narrowing Matchers
auto multiply(Args... args) {
return (args * ...);
}
+
+
+The matcher cxxFoldExpr(isUnaryFold())
+matches (args * ...), but not (0 + ... + args).
Matches if the given method or class declaration is final.
-Given:
+Given
class A final {};
struct B {
@@ -3591,7 +4760,13 @@ Narrowing Matchers
struct C : B {
void f() final;
};
-matches A and C::f, but not B, C, or B::f
+
+The matcher cxxRecordDecl(isFinal())
+matches A,
+but does not match B or C.
+The matcher cxxMethodDecl(isFinal())
+matches void f() final in C ,
+but does not match virtual void f() in B .
Matches declarations of virtual methods and C++ base specifers that specify
virtual inheritance.
-Example:
+Given
class A {
public:
virtual void x(); // matches x
};
-Example:
- class Base {};
- class DirectlyDerived : virtual Base {}; // matches Base
- class IndirectlyDerived : DirectlyDerived, Base {}; // matches Base
+The matcher cxxMethodDecl(isVirtual())
+matches x.
+
+Given
+ struct Base {};
+ struct DirectlyDerived : virtual Base {}; // matches Base
+ struct IndirectlyDerived : DirectlyDerived, Base {}; // matches Base
+
+The matcher
+cxxRecordDecl(hasDirectBase(cxxBaseSpecifier(isVirtual())))
+matches DirectlyDerived.
Usable as: Matcher<CXXMethodDecl>, Matcher<CXXBaseSpecifier>
Matches array new expressions.
-Given:
+Given
+ struct MyClass { int x; };
MyClass *p1 = new MyClass[10];
-cxxNewExpr(isArray())
- matches the expression 'new MyClass[10]'.
+
+The matcher cxxNewExpr(isArray())
+matches new MyClass[10].
Matches operator expressions (binary or unary) that have any of the
specified names.
+It provides a compact way of writing if an operator has any of the specified
+names:
+The matcher
hasAnyOperatorName("+", "-")
- Is equivalent to
- anyOf(hasOperatorName("+"), hasOperatorName("-"))
+Is equivalent to
+ hasOperatorName("-"))}
+
+Given
+void foo(bool a, bool b) {
+ !(a || b);
+ }
+
+void bar(bool a, bool b) {
+ a && b;
+ }
+
+The matcher binaryOperator(hasAnyOperatorName("||", "&&"))
+matches a || b and a && b.
+The matcher unaryOperator(hasAnyOperatorName("-", "!"))
+matches !(a || b).
Matches the operator Name of operator expressions and fold expressions
(binary or unary).
-Example matches a || b (matcher = binaryOperator(hasOperatorName("||")))
- !(a || b)
+Given
+void foo(bool a, bool b) {
+ !(a || b);
+ }
+
+The matcher binaryOperator(hasOperatorName("||"))
+matches a || b
-Example matches `(0 + ... + args)`
- (matcher = cxxFoldExpr(hasOperatorName("+")))
+Given
template <typename... Args>
auto sum(Args... args) {
return (0 + ... + args);
}
+
+The matcher cxxFoldExpr(hasOperatorName("+"))
+ matches (0 + ... + args).
Matches all kinds of assignment operators.
-Example 1: matches a += b (matcher = binaryOperator(isAssignmentOperator()))
+Given
+void foo(int a, int b) {
if (a == b)
a += b;
+}
+The matcher binaryOperator(isAssignmentOperator())
+matches a += b.
-Example 2: matches s1 = s2
- (matcher = cxxOperatorCallExpr(isAssignmentOperator()))
+Given
struct S { S& operator=(const S&); };
void x() { S s1, s2; s1 = s2; }
+
+The matcher cxxOperatorCallExpr(isAssignmentOperator())
+matches s1 = s2.
Matches comparison operators.
-Example 1: matches a == b (matcher = binaryOperator(isComparisonOperator()))
+Given
+void foo(int a, int b) {
if (a == b)
a += b;
+}
+The matcher binaryOperator(isComparisonOperator())
+matches a == b
-Example 2: matches s1 < s2
- (matcher = cxxOperatorCallExpr(isComparisonOperator()))
+Given
struct S { bool operator<(const S& other); };
void x(S s1, S s2) { bool b1 = s1 < s2; }
+
+The matcher cxxOperatorCallExpr(isComparisonOperator())
+matches s1 < s2
Matches a class declaration that is defined.
-Example matches x (matcher = cxxRecordDecl(hasDefinition()))
+Given
class x {};
class y;
+
+The matcher cxxRecordDecl(hasDefinition())
+matches class x {}
Overloaded method as shortcut for isDerivedFrom(hasName(...)).
+
+Matches C++ classes that are directly or indirectly derived from a class
+matching Base, or Objective-C classes that directly or indirectly
+subclass a class matching Base.
+
+Note that a class is not considered to be derived from itself.
+
+Example matches Y, Z, C (Base == hasName("X"))
+ class X {};
+ class Y : public X {}; // directly derived
+ class Z : public Y {}; // indirectly derived
+ typedef X A;
+ typedef A B;
+ class C : public B {}; // derived from a typedef of X
+
+ class Foo {};
+ typedef Foo Alias;
+ class Bar : public Alias {}; // derived from Alias, which is a
+ // typedef of Foo
+
+
+The matcher cxxRecordDecl(isDerivedFrom("X"))
+matches Y, Z and C.
+The matcher cxxRecordDecl(isDerivedFrom("Foo"))
+matches Bar.
+
+In the following example, Bar matches isDerivedFrom(hasName("NSObject"))
+ @interface NSObject @end
+ @interface Bar : NSObject @end
+
+
+Usable as: Matcher<CXXRecordDecl>, Matcher<ObjCInterfaceDecl>
Overloaded method as shortcut for isDirectlyDerivedFrom(hasName(...)).
+
+Given
+ struct Base {};
+ struct DirectlyDerived : public Base {};
+ struct IndirectlyDerived : public DirectlyDerived {};
+
+
+The matcher cxxRecordDecl(isDirectlyDerivedFrom("Base"))
+matches DirectlyDerived, but not
+IndirectlyDerived.
Matches if the given method or class declaration is final.
-Given:
+Given
class A final {};
struct B {
@@ -3829,24 +5134,46 @@ Narrowing Matchers
struct C : B {
void f() final;
};
-matches A and C::f, but not B, C, or B::f
+
+The matcher cxxRecordDecl(isFinal())
+matches A,
+but does not match B or C.
+The matcher cxxMethodDecl(isFinal())
+matches void f() final in C ,
+but does not match virtual void f() in B .
Matches the generated class of lambda expressions.
-Given:
+Given
auto x = []{};
-cxxRecordDecl(isLambda()) matches the implicit class declaration of
-decltype(x)
+
+The matcher varDecl(hasType(cxxRecordDecl(isLambda())))
+matches auto x = []{}.
Overloaded method as shortcut for +@@ -3855,18 +5182,36 @@ Similar to isDerivedFrom(), but also matches classes that directly +match Base. +Overloaded method as shortcut for isSameOrDerivedFrom(hasName(...)). + +Given + class X {}; + class Y : public X {}; // directly derived + class Z : public Y {}; // indirectly derived + typedef X A; + typedef A B; + class C : public B {}; // derived from a typedef of X + +The matcher +cxxRecordDecl(isSameOrDerivedFrom("X"), isDefinition()) +matches class X {}, class Y : public X {}, +class Z : public Y {} and class C : public B {}.Narrowing Matchers
member variable template instantiations. Given - template <typename T> class X {}; class A {}; X<A> x; -or - template <typename T> class X {}; class A {}; template class X<A>; -or - template <typename T> class X {}; class A {}; extern template class X<A>; -cxxRecordDecl(hasName("::X"), isTemplateInstantiation()) - matches the template instantiation of X<A>. + template <typename T> class X {}; + class A {}; + X<A> x; + +The matcher cxxRecordDecl(hasName("::X"), +isTemplateInstantiation()) +matches class X<class A>. + template <typename T> class X {}; + class A {}; + template class X<A>; + +The matcher cxxRecordDecl(hasName("::X"), +isTemplateInstantiation()) +matches template class X<A> + template <typename T> class X {}; + class A {}; + extern template class X<A>; + +The matcher cxxRecordDecl(hasName("::X"), +isTemplateInstantiation()) +matches extern template class X<A> But given - template <typename T> class X {}; class A {}; - template <> class X<A> {}; X<A> x; -cxxRecordDecl(hasName("::X"), isTemplateInstantiation()) + template <typename T> class X {}; + class A {}; + template <> class X<A> {}; + X<A> x; + +The matcher cxxRecordDecl(hasName("::X"), +isTemplateInstantiation()) does not match, as X<A> is an explicit template specialization. Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl> @@ -3877,9 +5222,26 @@Narrowing Matchers
@@ -3887,43 +5249,62 @@ Matches operator expressions (binary or unary) that have any of the specified names. +It provides a compact way of writing if an operator has any of the specified +names: +The matcher hasAnyOperatorName("+", "-") - Is equivalent to - anyOf(hasOperatorName("+"), hasOperatorName("-")) +Is equivalent to + hasOperatorName("-"))} + +Given +void foo(bool a, bool b) { + !(a || b); + } + +void bar(bool a, bool b) { + a && b; + } + +The matcher binaryOperator(hasAnyOperatorName("||", "&&")) +matches a || b and a && b. +The matcher unaryOperator(hasAnyOperatorName("-", "!")) +matches !(a || b).Narrowing Matchers
Matches the operator Name of operator expressions and fold expressions (binary or unary). -Example matches a || b (matcher = binaryOperator(hasOperatorName("||"))) - !(a || b) +Given +void foo(bool a, bool b) { + !(a || b); + } + +The matcher binaryOperator(hasOperatorName("||")) +matches a || b -Example matches `(0 + ... + args)` - (matcher = cxxFoldExpr(hasOperatorName("+"))) +Given template <typename... Args> auto sum(Args... args) { return (0 + ... + args); } + +The matcher cxxFoldExpr(hasOperatorName("+")) + matches (0 + ... + args).Matcher<CXXRewrittenBinaryOperator> isAssignmentOperator Matches all kinds of assignment operators. -Example 1: matches a += b (matcher = binaryOperator(isAssignmentOperator())) +Given +void foo(int a, int b) { if (a == b) a += b; +} +The matcher binaryOperator(isAssignmentOperator()) +matches a += b. -Example 2: matches s1 = s2 - (matcher = cxxOperatorCallExpr(isAssignmentOperator())) +Given struct S { S& operator=(const S&); }; void x() { S s1, s2; s1 = s2; } + +The matcher cxxOperatorCallExpr(isAssignmentOperator()) +matches s1 = s2.Matcher<CXXRewrittenBinaryOperator> isComparisonOperator @@ -3931,12 +5312,15 @@ Matches comparison operators. -Example 1: matches a == b (matcher = binaryOperator(isComparisonOperator())) +Given +void foo(int a, int b) { if (a == b) a += b; +} +The matcher binaryOperator(isComparisonOperator()) +matches a == b -Example 2: matches s1 < s2 - (matcher = cxxOperatorCallExpr(isComparisonOperator())) +Given struct S { bool operator<(const S& other); }; void x(S s1, S s2) { bool b1 = s1 < s2; } + +The matcher cxxOperatorCallExpr(isComparisonOperator()) +matches s1 < s2Narrowing Matchers
@@ -3944,9 +5328,13 @@ Checks that a call expression or a constructor call expression has at least the specified number of arguments (including absent default arguments). -Example matches f(0, 0) and g(0, 0, 0) -(matcher = callExpr(argumentCountAtLeast(2))) +Given void f(int x, int y); void g(int x, int y, int z); - f(0, 0); - g(0, 0, 0); + void foo() { + f(0, 0); + g(0, 0, 0); + } +The matcher callExpr(argumentCountAtLeast(2)) +matches f(0, 0) and g(0, 0, 0)Narrowing Matchers
@@ -3954,12 +5342,15 @@ Checks that a call expression or a constructor call expression has a specific number of arguments (including absent default arguments). -Example matches f(0, 0) (matcher = callExpr(argumentCountIs(2))) +Given void f(int x, int y); - f(0, 0); + void foo() { + f(0, 0); + } +The matcher callExpr(argumentCountIs(2)) +matches f(0, 0)Narrowing Matchers
@@ -3967,16 +5358,20 @@ Checks that a call expression or a constructor call expression has at least the specified number of arguments (including absent default arguments). -Example matches f(0, 0) and g(0, 0, 0) -(matcher = callExpr(argumentCountAtLeast(2))) +Given void f(int x, int y); void g(int x, int y, int z); - f(0, 0); - g(0, 0, 0); + void foo() { + f(0, 0); + g(0, 0, 0); + } +The matcher callExpr(argumentCountAtLeast(2)) +matches f(0, 0) and g(0, 0, 0)Narrowing Matchers
Checks that a call expression or a constructor call expression has a specific number of arguments (including absent default arguments). -Example matches f(0, 0) (matcher = callExpr(argumentCountIs(2))) +Given void f(int x, int y); - f(0, 0); + void foo() { + f(0, 0); + } +The matcher callExpr(argumentCountIs(2)) +matches f(0, 0)Matcher<CallExpr> usesADL Matches call expressions which were resolved using ADL. -Example matches y(x) but not y(42) or NS::y(x). +Given namespace NS { struct X {}; void y(X); @@ -3992,15 +5387,20 @@Narrowing Matchers
using NS::y; y(x); // Found by both unqualified lookup and ADL, doesn't match } + + +The matcher callExpr(usesADL()) +matches y(x), but not y(42) or NS::y(x).Matcher<CastExpr> hasCastKind CastKind Kind @@ -4078,10 +5487,11 @@ Matches casts that has a given cast kind. -Example: matches the implicit cast around 0 -(matcher = castExpr(hasCastKind(CK_NullToPointer))) +Given int *p = 0; +The matcher castExpr(hasCastKind(CK_NullToPointer)) +matches the implicit cast around 0 If the matcher is use from clang-query, CastKind parameter should be passed as a quoted string. e.g., hasCastKind("CK_NullToPointer"). @@ -4015,22 +5415,27 @@Narrowing Matchers
@@ -4061,9 +5468,11 @@ Matches literals that are equal to the given value of type ValueT. Given +void f(char, bool, double, int); +void foo() { f('false, 3.14, 42); -characterLiteral(equals(0)) - matches 'cxxBoolLiteral(equals(false)) and cxxBoolLiteral(equals(0)) - match false -floatLiteral(equals(3.14)) and floatLiteral(equals(314e-2)) - match 3.14 -integerLiteral(equals(42)) - matches 42 +} + +The matcher characterLiteral(equals(0U)) matches 'The matchers cxxBoolLiteral(equals(false)) and +cxxBoolLiteral(equals(0)) match false. +The matcher floatLiteral(equals(3.14)) matches 3.14. +The matcher integerLiteral(equals(42)) matches 42. Note that you cannot directly match a negative numeric literal because the minus sign is not part of the literal: It is a unary operator whose operand is the positive numeric literal. Instead, you must use a unaryOperator() matcher to match the minus sign: -unaryOperator(hasOperatorName("-"), - hasUnaryOperand(integerLiteral(equals(13)))) +Given + int val = -1; + +The matcher unaryOperator(hasOperatorName("-"), + hasUnaryOperand(integerLiteral(equals(1)))) +matches -1. Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteralExpr>, Matcher<FloatingLiteral>, Matcher<IntegerLiteral> @@ -4051,8 +5456,10 @@Narrowing Matchers
Given template<typename T> struct C {}; C<int> c; + +The matcher classTemplateSpecializationDecl(templateArgumentCountIs(1)) - matches C<int>. +matches struct C<int>.Narrowing Matchers
child statements. Example: Given +void foo() { { for (;;) {} } -compoundStmt(statementCountIs(0))) - matches '{}' +} +The matcher compoundStmt(statementCountIs(0)) +{} but does not match the outer compound statement.Narrowing Matchers
char *s = "abcd"; wchar_t *ws = L"abcd"; char *w = "a"; -constantArrayType(hasSize(42)) - matches "int a[42]" and "int b[2 * 21]" -stringLiteral(hasSize(4)) - matches "abcd", L"abcd" + +The matcher constantArrayType(hasSize(42)) +matches int[42] twice. +The matcher stringLiteral(hasSize(4)) +matches "abcd" and L"abcd".
Matches declaration statements that contain a specific number of
declarations.
-Example: Given
- int a, b;
- int c;
- int d = 2, e;
-declCountIs(2)
- matches 'int a, b;' and 'int d = 2, e;', but not 'int c;'.
+Given
+ void foo() {
+ int a, b;
+ int c;
+ int d = 2, e;
+ }
+The matcher declStmt(declCountIs(2))
+matches int a, b; and int d = 2, e;,
+but does not match int c;
Matches declaration that has a given attribute.
Given
- __attribute__((device)) void f() { ... }
-decl(hasAttr(clang::attr::CUDADevice)) matches the function declaration of
-f. If the matcher is used from clang-query, attr::Kind parameter should be
-passed as a quoted string. e.g., hasAttr("attr::CUDADevice").
+ __attribute__((device)) void f() {}
+
+The matcher decl(hasAttr(clang::attr::CUDADevice))
+matches f.
+If the matcher is used from clang-query, attr::Kind
+parameter should be passed as a quoted string. e.g.,
+hasAttr("attr::CUDADevice").
Matches AST nodes that were expanded within files whose name is
partially matching a given regex.
-Example matches Y but not X
- (matcher = cxxRecordDecl(isExpansionInFileMatching("AST.*"))
- #include "ASTMatcher.h"
- class X {};
-ASTMatcher.h:
- class Y {};
+Given the headers Y.h
+ #pragma once
+ typedef int my_y_int;
+and X.h
+ #pragma once
+ typedef int my_x_int;
+and the source code
+ #include "X.h"
+ #include "Y.h"
+ typedef int my_main_file_int;
+ my_main_file_int a = 0;
+ my_x_int b = 1;
+ my_y_int c = 2;
+
+The matcher
+typedefDecl(isExpansionInFileMatching("Y.h"))
+matches typedef int my_y_int,
+but does not match typedef int my_main_file_int or
+typedef int my_x_int.
Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
@@ -4169,12 +5608,18 @@ Narrowing Matchers
Matcher<Decl> isExpansionInMainFile
Matches AST nodes that were expanded within the main-file.
-Example matches X but not Y
- (matcher = cxxRecordDecl(isExpansionInMainFile())
- #include <Y.h>
- class X {};
-Y.h:
- class Y {};
+Given the header Y.h
+ #pragma once
+ typedef int my_header_int;
+and the source file
+ #include "Y.h"
+ typedef int my_main_file_int;
+ my_main_file_int a = 0;
+ my_header_int b = 1;
+
+The matcher typedefDecl(isExpansionInMainFile())
+matches typedef int my_main_file_int,
+but does not match typedef int my_header_int.
Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
@@ -4183,12 +5628,17 @@ Narrowing Matchers
Matcher<Decl> isExpansionInSystemHeader
Matches AST nodes that were expanded within system-header-files.
-Example matches Y but not X
- (matcher = cxxRecordDecl(isExpansionInSystemHeader())
+Given the header SystemHeader.h
+ #pragma once
+ int header();
+and the source code
#include <SystemHeader.h>
- class X {};
-SystemHeader.h:
- class Y {};
+ static int main_file();
+
+
+The matcher functionDecl(isExpansionInSystemHeader())
+matches int header(),
+but does not match static int main_file().
Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
@@ -4197,6 +5647,20 @@ Narrowing Matchers
Matcher<Decl> isImplicit
Matches an entity that has been implicitly added by the compiler (e.g.
implicit default/copy constructors).
+
+Given
+ struct S {};
+ void f(S obj) {
+ S copy = obj;
+ [&](){ return copy; };
+ }
+
+
+The matcher cxxConstructorDecl(isImplicit(), isCopyConstructor())
+matches the implicit copy constructor of S.
+The matcher lambdaExpr(forEachLambdaCapture(
+ lambdaCapture(isImplicit()))) matches [&](){ return copy; },
+because it implicitly captures copy .
@@ -4214,11 +5678,14 @@ Narrowing Matchers
namespace {
class vector {}; // #2
namespace foo {
- class vector{}; // #3
+ class vector {}; // #3
}
}
-cxxRecordDecl(hasName("vector"), isInAnonymousNamespace()) will match
-#1, #2 and #3.
+
+The matcher cxxRecordDecl(hasName("vector"),
+ isInAnonymousNamespace())
+matches vector,
+twice per declaration at #1, #2 and #3.
Matches private C++ declarations and C++ base specifers that specify private
inheritance.
-Examples:
+Given
class C {
public: int a;
protected: int b;
- private: int c; // fieldDecl(isPrivate()) matches 'c'
+ private: int c;
};
+The matcher fieldDecl(isPrivate())
+matches c.
+
struct Base {};
- struct Derived1 : private Base {}; // matches 'Base'
- class Derived2 : Base {}; // matches 'Base'
+ struct Derived1 : private Base {}; // Base
+ class Derived2 : Base {}; // Base
+
+The matcher
+cxxRecordDecl(hasAnyBase(cxxBaseSpecifier(isPrivate()).bind("base")))
+matches Derived1 and Derived2, with
+cxxBaseSpecifier(isPrivate()) matching
+Base.
Matches protected C++ declarations and C++ base specifers that specify
protected inheritance.
-Examples:
+Given
class C {
public: int a;
- protected: int b; // fieldDecl(isProtected()) matches 'b'
+ protected: int b;
private: int c;
};
+The matcher fieldDecl(isProtected())
+matches b.
+
class Base {};
- class Derived : protected Base {}; // matches 'Base'
+ class Derived : protected Base {};
+
+The matcher
+cxxRecordDecl(hasAnyBase(cxxBaseSpecifier(isProtected()).bind("base")))
+matches Derived, with
+cxxBaseSpecifier(isProtected()) matching
+Base.
Matches public C++ declarations and C++ base specifers that specify public
inheritance.
-Examples:
+Given
class C {
- public: int a; // fieldDecl(isPublic()) matches 'a'
+ public: int a;
protected: int b;
private: int c;
};
+The matcher fieldDecl(isPublic())
+matches a.
+
+Given
class Base {};
- class Derived1 : public Base {}; // matches 'Base'
- struct Derived2 : Base {}; // matches 'Base'
+ class Derived1 : public Base {};
+ struct Derived2 : Base {};
+
+The matcher
+cxxRecordDecl(hasAnyBase(cxxBaseSpecifier(isPublic()).bind("base")))
+matches Derived1 and Derived2,
+with cxxBaseSpecifier(isPublic()) matching
+public Base and Base.
Matches C++11 scoped enum declaration.
-Example matches Y (matcher = enumDecl(isScoped()))
+Given
enum X {};
enum class Y {};
+
+The matcher enumDecl(isScoped())
+matches enum class Y {}
Matches expressions that resolve to a null pointer constant, such as GNU's __null, C++11's nullptr, or C's NULL macro. -Given: +Given + #define NULL 0 void *v1 = NULL; void *v2 = nullptr; void *v3 = __null; // GNU extension char *cp = (char *)0; int *ip = 0; int i = 0; -expr(nullPointerConstant()) - matches the initializer for v1, v2, v3, cp, and ip. Does not match the - initializer for i. + +The matcher expr(nullPointerConstant()) +matches the initializer NULL of v1, +matches the initializer nullptr of v2, +matches the initializer __null of v3, +matches the initializer 0 of cp and +matches the initializer 0 of ip, +but does not match the initializer i of i.
Matches literals that are equal to the given value of type ValueT.
Given
+void f(char, bool, double, int);
+void foo() {
f('false, 3.14, 42);
-characterLiteral(equals(0))
- matches 'cxxBoolLiteral(equals(false)) and cxxBoolLiteral(equals(0))
- match false
-floatLiteral(equals(3.14)) and floatLiteral(equals(314e-2))
- match 3.14
-integerLiteral(equals(42))
- matches 42
+}
+
+The matcher characterLiteral(equals(0U)) matches 'The matchers cxxBoolLiteral(equals(false)) and
+cxxBoolLiteral(equals(0)) match false.
+The matcher floatLiteral(equals(3.14)) matches 3.14.
+The matcher integerLiteral(equals(42)) matches 42.
Note that you cannot directly match a negative numeric literal because the
minus sign is not part of the literal: It is a unary operator whose operand
is the positive numeric literal. Instead, you must use a unaryOperator()
matcher to match the minus sign:
-unaryOperator(hasOperatorName("-"),
- hasUnaryOperand(integerLiteral(equals(13))))
+Given
+ int val = -1;
+
+The matcher unaryOperator(hasOperatorName("-"),
+ hasUnaryOperand(integerLiteral(equals(1))))
+matches -1.
Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteralExpr>,
Matcher<FloatingLiteral>, Matcher<IntegerLiteral>
@@ -4452,6 +5980,30 @@ Narrowing Matchers
"operator" prefix: e.g. "<<".
hasAnyOverloadedOperatorName("+", "-")
+
+Given
+ struct Point { double x; double y; };
+ Point operator+(const Point&, const Point&);
+ Point operator-(const Point&, const Point&);
+
+ Point sub(Point a, Point b) {
+ return b - a;
+ }
+
+
+The matcher functionDecl(hasAnyOverloadedOperatorName("+", "-")),
+which is equivalent to
+functionDecl(anyOf(hasAnyOverloadedOperatorName("+"),
+hasOverloadedOperatorName("-"))),
+matches Point operator+(const Point&, const Point&) and
+Point operator-(const Point&, const Point&).
+The matcher
+cxxOperatorCallExpr(hasAnyOverloadedOperatorName("+", "-")),
+which is equivalent to
+cxxOperatorCallExpr(anyOf(hasOverloadedOperatorName("+"),
+hasOverloadedOperatorName("-"))),
+matches b - a.
+
Is equivalent to
anyOf(hasOverloadedOperatorName("+"), hasOverloadedOperatorName("-"))
Matches functions that have a dynamic exception specification. -Given: - void f(); - void g() noexcept; - void h() noexcept(true); - void i() noexcept(false); - void j() throw(); - void k() throw(int); - void l() throw(...); -functionDecl(hasDynamicExceptionSpec()) and - functionProtoType(hasDynamicExceptionSpec()) - match the declarations of j, k, and l, but not f, g, h, or i. +Given + void f(int); + void g(int) noexcept; + void h(int) noexcept(true); + void i(int) noexcept(false); + void j(int) throw(); + void k(int) throw(int); + void l(int) throw(...); + +The matcher functionDecl(hasDynamicExceptionSpec()) +matches the declarations void j(int) throw(), +void k(int) throw(int) +and void l(int) throw(...), +but does not match void f(int), void g(int) noexcept, +void h(int) noexcept(true) +or void i(int) noexcept(true). +The matcher +functionProtoType(hasDynamicExceptionSpec()) matches +the type void (int) throw() of j , +the type void (int) throw(int) of k and +the type void (int) throw(...) of l . +It does not match +the type void (int) noexcept of f , +the type void (int) noexcept of g , +the type void (int) noexcept(int) of h or +the type void (int) noexcept(...) of i .
Matches a function declared with a trailing return type.
-Example matches Y (matcher = functionDecl(hasTrailingReturn()))
+Given
int X() {}
auto Y() -> int {}
+
+The matcher functionDecl(hasTrailingReturn())
+matches auto Y() -> int {}.
Matches consteval function declarations and if consteval/if ! consteval
statements.
-Given:
+Given
consteval int a();
void b() { if consteval {} }
void c() { if ! consteval {} }
void d() { if ! consteval {} else {} }
-functionDecl(isConsteval())
- matches the declaration of "int a()".
-ifStmt(isConsteval())
- matches the if statement in "void b()", "void c()", "void d()".
+
+The matcher functionDecl(isConsteval())
+matches a.
+The matcher ifStmt(isConsteval())
+matches the if statements
+if consteval {}, if ! consteval {} and
+if ! consteval {} else {}.
Matches constexpr variable and function declarations,
and if constexpr.
-Given:
+Given
constexpr int foo = 42;
constexpr int bar();
void baz() { if constexpr(1 > 0) {} }
-varDecl(isConstexpr())
- matches the declaration of foo.
-functionDecl(isConstexpr())
- matches the declaration of bar.
-ifStmt(isConstexpr())
- matches the if statement in baz.
+
+The matcher varDecl(isConstexpr())
+matches foo.
+The matcher functionDecl(isConstexpr())
+matches bar.
+The matcher ifStmt(isConstexpr())
+matches if constexpr(1 > 0) {}.
Matches defaulted function declarations.
-Given:
+Given
class A { ~A(); };
class B { ~B() = default; };
-functionDecl(isDefaulted())
- matches the declaration of ~B, but not ~A.
+
+The matcher functionDecl(isDefaulted())
+ matches ~B() = default,
+but does not match ~A().
Matches deleted function declarations. -Given: +Given void Func(); void DeletedFunc() = delete; -functionDecl(isDeleted()) - matches the declaration of DeletedFunc, but not Func. + +The matcher functionDecl(isDeleted()) +matches DeletedFunc, +but does not match Func.
Matches extern "C" function or variable declarations.
-Given:
+Given
extern "C" void f() {}
extern "C" { void g() {} }
void h() {}
extern "C" int x = 1;
extern "C" int y = 2;
int z = 3;
-functionDecl(isExternC())
- matches the declaration of f and g, but not the declaration of h.
-varDecl(isExternC())
- matches the declaration of x and y, but not the declaration of z.
+
+The matcher functionDecl(isExternC())
+matches f
+and g.
+The matcher varDecl(isExternC())
+matches x
+and y,
+but does not match z.
Determines whether the function is "main", which is the entry point
into an executable program.
+
+Given
+ void f();
+ int main() {}
+
+The matcher functionDecl(isMain()) matches int main() {}.
Matches functions that have a non-throwing exception specification. -Given: - void f(); - void g() noexcept; - void h() throw(); - void i() throw(int); - void j() noexcept(false); -functionDecl(isNoThrow()) and functionProtoType(isNoThrow()) - match the declarations of g, and h, but not f, i or j. +Given + void f(int); + void g(int) noexcept; + void h(int) noexcept(false); + void i(int) throw(); + void j(int) throw(int); + +The matcher functionDecl(isNoThrow()) +matches the declaration void g(int) noexcept +and void i(int) throw(), +but does not match void f(int), +void h(int) noexcept(false) +or void j(int) throw(int). +The matcher +functionProtoType(isNoThrow()) +matches the type void (int) throw() of i +and the type void (int) noexcept of g, +but does not match +the type void (int) of f , +the type void (int) noexcept(false) of h or +the type void (int) throw(int) of j .
Matches variable/function declarations that have "static" storage
class specifier ("static" keyword) written in the source.
-Given:
+Given
static void f() {}
static int i = 0;
extern int j;
int k;
-functionDecl(isStaticStorageClass())
- matches the function declaration f.
-varDecl(isStaticStorageClass())
- matches the variable declaration i.
+The matcher functionDecl(isStaticStorageClass())
+ matches f
+The matcher varDecl(isStaticStorageClass())
+ matches i
Matches weak function declarations.
-Given:
- void foo() __attribute__((__weakref__("__foo")));
- void bar();
-functionDecl(isWeak())
- matches the weak declaration "foo", but not "bar".
+Given
+ static void f();
+ void g() __attribute__((weak));
+The matcher functionDecl(isWeak())
+ matches the weak declaration
+void g() __attribute__((weak)),
+but does not match static void foo_v1().
Matches functions that have a dynamic exception specification. -Given: - void f(); - void g() noexcept; - void h() noexcept(true); - void i() noexcept(false); - void j() throw(); - void k() throw(int); - void l() throw(...); -functionDecl(hasDynamicExceptionSpec()) and - functionProtoType(hasDynamicExceptionSpec()) - match the declarations of j, k, and l, but not f, g, h, or i. +Given + void f(int); + void g(int) noexcept; + void h(int) noexcept(true); + void i(int) noexcept(false); + void j(int) throw(); + void k(int) throw(int); + void l(int) throw(...); + +The matcher functionDecl(hasDynamicExceptionSpec()) +matches the declarations void j(int) throw(), +void k(int) throw(int) +and void l(int) throw(...), +but does not match void f(int), void g(int) noexcept, +void h(int) noexcept(true) +or void i(int) noexcept(true). +The matcher +functionProtoType(hasDynamicExceptionSpec()) matches +the type void (int) throw() of j , +the type void (int) throw(int) of k and +the type void (int) throw(...) of l . +It does not match +the type void (int) noexcept of f , +the type void (int) noexcept of g , +the type void (int) noexcept(int) of h or +the type void (int) noexcept(...) of i .
Matches functions that have a non-throwing exception specification. -Given: - void f(); - void g() noexcept; - void h() throw(); - void i() throw(int); - void j() noexcept(false); -functionDecl(isNoThrow()) and functionProtoType(isNoThrow()) - match the declarations of g, and h, but not f, i or j. +Given + void f(int); + void g(int) noexcept; + void h(int) noexcept(false); + void i(int) throw(); + void j(int) throw(int); + +The matcher functionDecl(isNoThrow()) +matches the declaration void g(int) noexcept +and void i(int) throw(), +but does not match void f(int), +void h(int) noexcept(false) +or void j(int) throw(int). +The matcher +functionProtoType(isNoThrow()) +matches the type void (int) throw() of i +and the type void (int) noexcept of g, +but does not match +the type void (int) of f , +the type void (int) noexcept(false) of h or +the type void (int) throw(int) of j .
Matches consteval function declarations and if consteval/if ! consteval
statements.
-Given:
+Given
consteval int a();
void b() { if consteval {} }
void c() { if ! consteval {} }
void d() { if ! consteval {} else {} }
-functionDecl(isConsteval())
- matches the declaration of "int a()".
-ifStmt(isConsteval())
- matches the if statement in "void b()", "void c()", "void d()".
+
+The matcher functionDecl(isConsteval())
+matches a.
+The matcher ifStmt(isConsteval())
+matches the if statements
+if consteval {}, if ! consteval {} and
+if ! consteval {} else {}.
Matches constexpr variable and function declarations,
and if constexpr.
-Given:
+Given
constexpr int foo = 42;
constexpr int bar();
void baz() { if constexpr(1 > 0) {} }
-varDecl(isConstexpr())
- matches the declaration of foo.
-functionDecl(isConstexpr())
- matches the declaration of bar.
-ifStmt(isConstexpr())
- matches the if statement in baz.
+
+The matcher varDecl(isConstexpr())
+matches foo.
+The matcher functionDecl(isConstexpr())
+matches bar.
+The matcher ifStmt(isConstexpr())
+matches if constexpr(1 > 0) {}.
Matches literals that are equal to the given value of type ValueT.
Given
+void f(char, bool, double, int);
+void foo() {
f('false, 3.14, 42);
-characterLiteral(equals(0))
- matches 'cxxBoolLiteral(equals(false)) and cxxBoolLiteral(equals(0))
- match false
-floatLiteral(equals(3.14)) and floatLiteral(equals(314e-2))
- match 3.14
-integerLiteral(equals(42))
- matches 42
+}
+
+The matcher characterLiteral(equals(0U)) matches 'The matchers cxxBoolLiteral(equals(false)) and
+cxxBoolLiteral(equals(0)) match false.
+The matcher floatLiteral(equals(3.14)) matches 3.14.
+The matcher integerLiteral(equals(42)) matches 42.
Note that you cannot directly match a negative numeric literal because the
minus sign is not part of the literal: It is a unary operator whose operand
is the positive numeric literal. Instead, you must use a unaryOperator()
matcher to match the minus sign:
-unaryOperator(hasOperatorName("-"),
- hasUnaryOperand(integerLiteral(equals(13))))
+Given
+ int val = -1;
+
+The matcher unaryOperator(hasOperatorName("-"),
+ hasUnaryOperand(integerLiteral(equals(1))))
+matches -1.
Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteralExpr>,
Matcher<FloatingLiteral>, Matcher<IntegerLiteral>
@@ -4876,14 +6558,30 @@ Narrowing Matchers
return l();
}
};
+
+The matcher
lambdaExpr(hasAnyCapture(lambdaCapture(capturesThis())))
- matches `[this]() { return cc; }`.
+matches [this]() { return cc; }.
Matches an entity that has been implicitly added by the compiler (e.g.
implicit default/copy constructors).
+
+Given
+ struct S {};
+ void f(S obj) {
+ S copy = obj;
+ [&](){ return copy; };
+ }
+
+
+The matcher cxxConstructorDecl(isImplicit(), isCopyConstructor())
+matches the implicit copy constructor of S.
+The matcher lambdaExpr(forEachLambdaCapture(
+ lambdaCapture(isImplicit()))) matches [&](){ return copy; },
+because it implicitly captures copy .
Matches NamedDecl nodes that have any of the specified names.
This matcher is only provided as a performance optimization of hasName.
- hasAnyName(a, b, c)
- is equivalent to, but faster than
- anyOf(hasName(a), hasName(b), hasName(c))
+
+Given
+ void f(int a, int b);
+
+The matcher namedDecl(hasAnyName("a", "b")),
+which is equivalent to the matcher
+namedDecl(hasAnyName("a", "b")),
+matches int a and int b, but not
+void f(int a, int b).
Matches a declaration that has external formal linkage.
-Example matches only z (matcher = varDecl(hasExternalFormalLinkage()))
+Given
void f() {
- int x;
- static int y;
+ int a;
+ static int b;
}
-int z;
+int c;
+static int d;
+The matcher varDecl(hasExternalFormalLinkage())
+matches int c,
+but not int a, static int b or int d.
-Example matches f() because it has external formal linkage despite being
-unique to the translation unit as though it has internal likage
-(matcher = functionDecl(hasExternalFormalLinkage()))
+Given
+ namespace {
+ void f() {}
+ }
+ void g() {}
+ static void h() {}
-namespace {
-void f() {}
-}
+
+The matcher functionDecl(hasExternalFormalLinkage())
+matches void g() {}, but not void f() {} or
+static void h() {}.
Matches if the OpenMP ``default`` clause has ``none`` kind specified.
Given
+ void foo() {
+ #pragma omp parallel
+ ;
+ #pragma omp parallel default(none)
+ ;
+ #pragma omp parallel default(shared)
+ ;
+ #pragma omp parallel default(private)
+ ;
+ #pragma omp parallel default(firstprivate)
+ ;
+ }
- #pragma omp parallel
- #pragma omp parallel default(none)
- #pragma omp parallel default(shared)
- #pragma omp parallel default(private)
- #pragma omp parallel default(firstprivate)
-``ompDefaultClause(isNoneKind())`` matches only ``default(none)``.
+The matcher
+ompExecutableDirective(hasAnyClause(ompDefaultClause(isNoneKind())))
+matches only #pragma omp parallel default(none).
Matches if the OpenMP ``default`` clause has ``shared`` kind specified.
Given
-
- #pragma omp parallel
- #pragma omp parallel default(none)
+ void foo() {
+ #pragma omp parallel
+ ;
+ #pragma omp parallel default(none)
+ ;
#pragma omp parallel default(shared)
+ ;
#pragma omp parallel default(private)
+ ;
#pragma omp parallel default(firstprivate)
+ ;
+ }
-``ompDefaultClause(isSharedKind())`` matches only ``default(shared)``.
+
+The matcher
+ompExecutableDirective(hasAnyClause(ompDefaultClause(isSharedKind())))
+matches #pragma omp parallel default(shared).
Overloaded method as shortcut for isDerivedFrom(hasName(...)).
+
+Matches C++ classes that are directly or indirectly derived from a class
+matching Base, or Objective-C classes that directly or indirectly
+subclass a class matching Base.
+
+Note that a class is not considered to be derived from itself.
+
+Example matches Y, Z, C (Base == hasName("X"))
+ class X {};
+ class Y : public X {}; // directly derived
+ class Z : public Y {}; // indirectly derived
+ typedef X A;
+ typedef A B;
+ class C : public B {}; // derived from a typedef of X
+
+ class Foo {};
+ typedef Foo Alias;
+ class Bar : public Alias {}; // derived from Alias, which is a
+ // typedef of Foo
+
+
+The matcher cxxRecordDecl(isDerivedFrom("X"))
+matches Y, Z and C.
+The matcher cxxRecordDecl(isDerivedFrom("Foo"))
+matches Bar.
+
+In the following example, Bar matches isDerivedFrom(hasName("NSObject"))
+ @interface NSObject @end
+ @interface Bar : NSObject @end
+
+
+Usable as: Matcher<CXXRecordDecl>, Matcher<ObjCInterfaceDecl>
Overloaded method as shortcut for isDirectlyDerivedFrom(hasName(...)).
+
+Given
+ struct Base {};
+ struct DirectlyDerived : public Base {};
+ struct IndirectlyDerived : public DirectlyDerived {};
+
+
+The matcher cxxRecordDecl(isDirectlyDerivedFrom("Base"))
+matches DirectlyDerived, but not
+IndirectlyDerived.
Overloaded method as shortcut for +@@ -5124,12 +6964,15 @@ Similar to isDerivedFrom(), but also matches classes that directly +match Base. +Overloaded method as shortcut for isSameOrDerivedFrom(hasName(...)). + +Given + class X {}; + class Y : public X {}; // directly derived + class Z : public Y {}; // indirectly derived + typedef X A; + typedef A B; + class C : public B {}; // derived from a typedef of X + +The matcher +cxxRecordDecl(isSameOrDerivedFrom("X"), isDefinition()) +matches class X {}, class Y : public X {}, +class Z : public Y {} and class C : public B {}.Narrowing Matchers
@@ -5137,9 +6980,13 @@ Checks that a call expression or a constructor call expression has at least the specified number of arguments (including absent default arguments). -Example matches f(0, 0) and g(0, 0, 0) -(matcher = callExpr(argumentCountAtLeast(2))) +Given void f(int x, int y); void g(int x, int y, int z); - f(0, 0); - g(0, 0, 0); + void foo() { + f(0, 0); + g(0, 0, 0); + } +The matcher callExpr(argumentCountAtLeast(2)) +matches f(0, 0) and g(0, 0, 0)Narrowing Matchers
@@ -5147,24 +6994,27 @@ Checks that a call expression or a constructor call expression has a specific number of arguments (including absent default arguments). -Example matches f(0, 0) (matcher = callExpr(argumentCountIs(2))) +Given void f(int x, int y); - f(0, 0); + void foo() { + f(0, 0); + } +The matcher callExpr(argumentCountIs(2)) +matches f(0, 0)Narrowing Matchers
Matches when at least one of the supplied string equals to the Selector.getAsString() - matcher = objCMessageExpr(hasSelector("methodA:", "methodB:")); - matches both of the expressions below: [myObj methodA:argA]; [myObj methodB:argB]; + + The matcher objCMessageExpr(hasSelector("methodA:", "methodB:")); + matches [myObj methodA:argA]; and [myObj methodB:argB];Matcher<ObjCMessageExpr> hasKeywordSelector @@ -5179,56 +7029,68 @@ Matches when the selector is a keyword selector -objCMessageExpr(hasKeywordSelector()) matches the generated setFrame -message expression in - +Given UIWebView *webView = ...; CGRect bodyFrame = webView.frame; bodyFrame.size.height = self.bodyContentHeight; webView.frame = bodyFrame; // ^---- matches here + + +The matcher objCMessageExpr(hasKeywordSelector()) matches the +generated setFrame message expression inNarrowing Matchers
Matcher<ObjCMessageExpr> hasSelector std::string BaseName Matches when BaseName == Selector.getAsString() - matcher = objCMessageExpr(hasSelector("loadHTMLString:baseURL:")); - matches the outer message expr in the code below, but NOT the message - invocation for self.bodyView. [self.bodyView loadHTMLString:html baseURL:NULL]; + +The matcher +objCMessageExpr(hasSelector("loadHTMLString:baseURL:")); matches +the outer message expr in the code below, but NOT the message invocation +for self.bodyView.Matcher<ObjCMessageExpr> hasUnarySelector Matches when the selector is a Unary Selector - matcher = objCMessageExpr(matchesSelector(hasUnarySelector()); - matches self.bodyView in the code below, but NOT the outer message - invocation of "loadHTMLString:baseURL:". +Given [self.bodyView loadHTMLString:html baseURL:NULL]; + + + The matcher objCMessageExpr(matchesSelector(hasUnarySelector()); + matches self.bodyView, but does not match the outer message + invocation of "loadHTMLString:baseURL:".Matcher<ObjCMessageExpr> isClassMessage Returns true when the Objective-C message is sent to a class. -Example -matcher = objcMessageExpr(isClassMessage()) -matches +Given [NSString stringWithFormat:@"format"]; -but not NSString *x = @"hello"; [x containsString:@"h"]; + +The matcher objcMessageExpr(isClassMessage()) +matches [NSString stringWithFormat:@"format"]; +but does not match [[x containsString:@"h"]Matcher<ObjCMessageExpr> isInstanceMessage Returns true when the Objective-C message is sent to an instance. -Example -matcher = objcMessageExpr(isInstanceMessage()) -matches +Given NSString *x = @"hello"; [x containsString:@"h"]; -but not [NSString stringWithFormat:@"format"]; + +The matcher objcMessageExpr(isInstanceMessage()) +matches [x containsString:@"h"]; +but does not match [NSString stringWithFormat:@"format"];Matcher<ObjCMessageExpr> matchesSelector StringRef RegExp, Regex::RegexFlags Flags = NoFlags @@ -5285,33 +7159,39 @@ Matches ObjC selectors whose name contains a substring matched by the given RegExp. - matcher = objCMessageExpr(matchesSelector("loadHTMLStringmatches the outer message expr in the code below, but NOT the message - invocation for self.bodyView. + +Given [self.bodyView loadHTMLString:html baseURL:NULL]; + +The matcher +objCMessageExpr(matchesSelector("loadHTMLStringmatches the outer message expr in the code below, but NOT the message +invocation for self.bodyView. + If the matcher is used in clang-query, RegexFlags parameter should be passed as a quoted string. e.g: "NoFlags". Flags can be combined with '|' example "IgnoreCase | BasicRegex" @@ -5238,25 +7100,26 @@Narrowing Matchers
Matcher<ObjCMessageExpr> numSelectorArgs unsigned N Matches when the selector has the specified number of arguments - matcher = objCMessageExpr(numSelectorArgs(0)); - matches self.bodyView in the code below - - matcher = objCMessageExpr(numSelectorArgs(2)); - matches the invocation of "loadHTMLString:baseURL:" but not that - of self.bodyView [self.bodyView loadHTMLString:html baseURL:NULL]; + +The matcher objCMessageExpr(numSelectorArgs(0)) +matches self.bodyView. +The matcher objCMessageExpr(numSelectorArgs(2)) +matches the invocation of loadHTMLString:baseURL: +but does not match self.bodyViewMatcher<ObjCMethodDecl> isClassMethod @@ -5270,6 +7133,14 @@ Returns true when the Objective-C method declaration is a class method. -Example -matcher = objcMethodDecl(isClassMethod()) -matches +Given @interface I + (void)foo; @end -but not @interface I - (void)bar; @end + +The matcher objcMethodDecl(isClassMethod()) +matches @interface I + (void)foo; @end +but does not match interface I + (void)foo; @endNarrowing Matchers
extern int vb; // Doesn't match, as it doesn't define the variable. void fa() {} void fb(); // Doesn't match, as it has no body. + +The matcher tagDecl(isDefinition()) +matches A +The matcher varDecl(isDefinition()) +matches va +The matcher functionDecl(isDefinition()) +matches fa + @interface X - (void)ma; // Doesn't match, interface is declaration. @end @@ -5277,6 +7148,9 @@Narrowing Matchers
- (void)ma {} @end +The matcher objcMethodDecl(isDefinition()) +matches - (void)ma {} + Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>, Matcher<ObjCMethodDecl>Narrowing Matchers
Matcher<ObjCMethodDecl> isInstanceMethod Returns true when the Objective-C method declaration is an instance method. -Example -matcher = objcMethodDecl(isInstanceMethod()) -matches +Given @interface I - (void)bar; @end -but not @interface I + (void)foo; @end + +The matcher objcMethodDecl(isInstanceMethod()) +matches @interface I - (void)bar; @end +but does not match @interface I - (void)foo; @end +Matcher<ParmVarDecl> hasDefaultArgument @@ -5326,9 +7206,9 @@ Matches a declaration that has default arguments. -Example matches y (matcher = parmVarDecl(hasDefaultArgument())) -void x(int val) {} -void y(int val = 0) {} +Given + void x(int val) {} + void y(int val = 0) {} + + +The matcher parmVarDecl(hasDefaultArgument()) +matches int val = 0. Deprecated. Use hasInitializer() instead to be able to match on the contents of the default argument. For example: -void x(int val = 7) {} -void y(int val = 42) {} -parmVarDecl(hasInitializer(integerLiteral(equals(42)))) - matches the parameter of y +Given + void x(int val = 7) {} + void y(int val = 42) {} + -A matcher such as - parmVarDecl(hasInitializer(anything())) -is equivalent to parmVarDecl(hasDefaultArgument()). +The matcher +parmVarDecl(hasInitializer(integerLiteral(equals(42)))), +matches int val = 42.Narrowing Matchers
void f(int a, int b, int c) { } -``parmVarDecl(isAtPosition(0))`` matches ``int a``. - -``parmVarDecl(isAtPosition(1))`` matches ``int b``. +The matcher parmVarDecl(isAtPosition(0)) matches +a. The matcher parmVarDecl(isAtPosition(1)) +matches b.
Matches AST nodes that were expanded within files whose name is
partially matching a given regex.
-Example matches Y but not X
- (matcher = cxxRecordDecl(isExpansionInFileMatching("AST.*"))
- #include "ASTMatcher.h"
- class X {};
-ASTMatcher.h:
- class Y {};
+Given the headers Y.h
+ #pragma once
+ typedef int my_y_int;
+and X.h
+ #pragma once
+ typedef int my_x_int;
+and the source code
+ #include "X.h"
+ #include "Y.h"
+ typedef int my_main_file_int;
+ my_main_file_int a = 0;
+ my_x_int b = 1;
+ my_y_int c = 2;
+
+The matcher
+typedefDecl(isExpansionInFileMatching("Y.h"))
+matches typedef int my_y_int,
+but does not match typedef int my_main_file_int or
+typedef int my_x_int.
Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
@@ -5541,12 +7459,18 @@ Narrowing Matchers
Matcher<Stmt> isExpansionInMainFile
Matches AST nodes that were expanded within the main-file.
-Example matches X but not Y
- (matcher = cxxRecordDecl(isExpansionInMainFile())
- #include <Y.h>
- class X {};
-Y.h:
- class Y {};
+Given the header Y.h
+ #pragma once
+ typedef int my_header_int;
+and the source file
+ #include "Y.h"
+ typedef int my_main_file_int;
+ my_main_file_int a = 0;
+ my_header_int b = 1;
+
+The matcher typedefDecl(isExpansionInMainFile())
+matches typedef int my_main_file_int,
+but does not match typedef int my_header_int.
Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
@@ -5555,12 +7479,17 @@ Narrowing Matchers
Matcher<Stmt> isExpansionInSystemHeader
Matches AST nodes that were expanded within system-header-files.
-Example matches Y but not X
- (matcher = cxxRecordDecl(isExpansionInSystemHeader())
+Given the header SystemHeader.h
+ #pragma once
+ int header();
+and the source code
#include <SystemHeader.h>
- class X {};
-SystemHeader.h:
- class Y {};
+ static int main_file();
+
+
+The matcher functionDecl(isExpansionInSystemHeader())
+matches int header(),
+but does not match static int main_file().
Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
@@ -5571,14 +7500,18 @@ Narrowing Matchers
Given
int j;
- template<typename T> void A(T t) { T i; j += 42;}
- A(0);
- A(0U);
-declStmt(isInTemplateInstantiation())
- matches 'int i;' and 'unsigned i'.
-unless(stmt(isInTemplateInstantiation()))
- will NOT match j += 42; as it's shared between the template definition and
- instantiation.
+ template<typename T> void A(T t) { T i; }
+ void foo() {
+ A(0);
+ A(0U);
+ }
+
+The matcher declStmt(isInTemplateInstantiation())
+matches T i; twice, once for int and once for
+int}.
+The matcher declStmt(unless(isInTemplateInstantiation())) will
+match T i; once inside the template definition, but not for any of
+the instantiated bodies.
Matches TagDecl object that are spelled with "class."
-Example matches C, but not S, U or E.
+Given
struct S {};
class C {};
union U {};
- enum E {};
+ enum E { Ok };
+
+The matcher tagDecl(isClass())
+matches class C,
+but does not match struct S,
+union U
+or enum E.
Matches TagDecl object that are spelled with "enum."
-Example matches E, but not C, S or U.
+Given
struct S {};
class C {};
union U {};
- enum E {};
+ enum E { Ok };
+
+The matcher tagDecl(isEnum())
+matches enum E { Ok },
+but does not match struct S {},
+class C {} or union U {}.
Matches TagDecl object that are spelled with "union."
-Example matches U, but not C, S or E.
+Given
struct S {};
class C {};
union U {};
- enum E {};
+ enum E { Ok };
+
+The matcher tagDecl(isUnion())
+matches union U,
+does not match struct S,
+class C
+or enum E.
Matches AST nodes that were expanded within files whose name is
partially matching a given regex.
-Example matches Y but not X
- (matcher = cxxRecordDecl(isExpansionInFileMatching("AST.*"))
- #include "ASTMatcher.h"
- class X {};
-ASTMatcher.h:
- class Y {};
+Given the headers Y.h
+ #pragma once
+ typedef int my_y_int;
+and X.h
+ #pragma once
+ typedef int my_x_int;
+and the source code
+ #include "X.h"
+ #include "Y.h"
+ typedef int my_main_file_int;
+ my_main_file_int a = 0;
+ my_x_int b = 1;
+ my_y_int c = 2;
+
+The matcher
+typedefDecl(isExpansionInFileMatching("Y.h"))
+matches typedef int my_y_int,
+but does not match typedef int my_main_file_int or
+typedef int my_x_int.
Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
@@ -5735,12 +7732,18 @@ Narrowing Matchers
Matcher<TypeLoc> isExpansionInMainFile
Matches AST nodes that were expanded within the main-file.
-Example matches X but not Y
- (matcher = cxxRecordDecl(isExpansionInMainFile())
- #include <Y.h>
- class X {};
-Y.h:
- class Y {};
+Given the header Y.h
+ #pragma once
+ typedef int my_header_int;
+and the source file
+ #include "Y.h"
+ typedef int my_main_file_int;
+ my_main_file_int a = 0;
+ my_header_int b = 1;
+
+The matcher typedefDecl(isExpansionInMainFile())
+matches typedef int my_main_file_int,
+but does not match typedef int my_header_int.
Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
@@ -5749,12 +7752,17 @@ Narrowing Matchers
Matcher<TypeLoc> isExpansionInSystemHeader
Matches AST nodes that were expanded within system-header-files.
-Example matches Y but not X
- (matcher = cxxRecordDecl(isExpansionInSystemHeader())
+Given the header SystemHeader.h
+ #pragma once
+ int header();
+and the source code
#include <SystemHeader.h>
- class X {};
-SystemHeader.h:
- class Y {};
+ static int main_file();
+
+
+The matcher functionDecl(isExpansionInSystemHeader())
+matches int header(),
+but does not match static int main_file().
Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
@@ -5765,8 +7773,9 @@ Narrowing Matchers
Given
struct S { bool func(); };
-functionDecl(returns(booleanType()))
- matches "bool func();"
+
+The matcher functionDecl(returns(booleanType()))
+func
Matches operator expressions (binary or unary) that have any of the
specified names.
+It provides a compact way of writing if an operator has any of the specified
+names:
+The matcher
hasAnyOperatorName("+", "-")
- Is equivalent to
- anyOf(hasOperatorName("+"), hasOperatorName("-"))
+Is equivalent to
+ hasOperatorName("-"))}
+
+Given
+void foo(bool a, bool b) {
+ !(a || b);
+ }
+
+void bar(bool a, bool b) {
+ a && b;
+ }
+
+The matcher binaryOperator(hasAnyOperatorName("||", "&&"))
+matches a || b and a && b.
+The matcher unaryOperator(hasAnyOperatorName("-", "!"))
+matches !(a || b).
Matches the operator Name of operator expressions and fold expressions
(binary or unary).
-Example matches a || b (matcher = binaryOperator(hasOperatorName("||")))
- !(a || b)
+Given
+void foo(bool a, bool b) {
+ !(a || b);
+ }
+
+The matcher binaryOperator(hasOperatorName("||"))
+matches a || b
-Example matches `(0 + ... + args)`
- (matcher = cxxFoldExpr(hasOperatorName("+")))
+Given
template <typename... Args>
auto sum(Args... args) {
return (0 + ... + args);
}
+
+The matcher cxxFoldExpr(hasOperatorName("+"))
+ matches (0 + ... + args).
Matches a variable declaration that has automatic storage duration.
-Example matches x, but not y, z, or a.
-(matcher = varDecl(hasAutomaticStorageDuration())
+Given
void f() {
int x;
static int y;
thread_local int z;
}
int a;
+
+The matcher varDecl(hasAutomaticStorageDuration())
+matches x
+but does not match y, z or
+a
Matches a variable declaration that does not have local storage.
-Example matches y and z (matcher = varDecl(hasGlobalStorage())
+Given
void f() {
int x;
static int y;
}
int z;
+The matcher varDecl(hasGlobalStorage())
+matches y and z
Matches a variable declaration that has function scope and is a
non-static local variable.
-Example matches x (matcher = varDecl(hasLocalStorage())
+Given
void f() {
int x;
static int y;
}
int z;
+The matcher varDecl(hasLocalStorage())
+matches x
Matches a variable declaration that has thread storage duration.
-Example matches z, but not x, z, or a.
-(matcher = varDecl(hasThreadStorageDuration())
+Given
void f() {
int x;
static int y;
thread_local int z;
}
int a;
+
+The matcher varDecl(hasThreadStorageDuration())
+matches z
+but does not match x, z or
+a
Matches constexpr variable and function declarations,
and if constexpr.
-Given:
+Given
constexpr int foo = 42;
constexpr int bar();
void baz() { if constexpr(1 > 0) {} }
-varDecl(isConstexpr())
- matches the declaration of foo.
-functionDecl(isConstexpr())
- matches the declaration of bar.
-ifStmt(isConstexpr())
- matches the if statement in baz.
+
+The matcher varDecl(isConstexpr())
+matches foo.
+The matcher functionDecl(isConstexpr())
+matches bar.
+The matcher ifStmt(isConstexpr())
+matches if constexpr(1 > 0) {}.
Matches constinit variable declarations. -Given: +Given constinit int foo = 42; constinit const char* bar = "bar"; int baz = 42; [[clang::require_constant_initialization]] int xyz = 42; -varDecl(isConstinit()) - matches the declaration of `foo` and `bar`, but not `baz` and `xyz`. + +The matcher varDecl(isConstinit()) +matches the declaration of foo +and bar, +but does not match baz or +xyz.
Matches a variable declaration that is an exception variable from
a C++ catch block, or an Objective-C statement.
-Example matches x (matcher = varDecl(isExceptionVariable())
+Given
void f(int y) {
try {
} catch (int x) {
}
}
+
+The matcher varDecl(isExceptionVariable())
+matches x
Matches extern "C" function or variable declarations.
-Given:
+Given
extern "C" void f() {}
extern "C" { void g() {} }
void h() {}
extern "C" int x = 1;
extern "C" int y = 2;
int z = 3;
-functionDecl(isExternC())
- matches the declaration of f and g, but not the declaration of h.
-varDecl(isExternC())
- matches the declaration of x and y, but not the declaration of z.
+
+The matcher functionDecl(isExternC())
+matches f
+and g.
+The matcher varDecl(isExternC())
+matches x
+and y,
+but does not match z.
Matches a variable serving as the implicit variable for a lambda init-
capture.
-Example matches x (matcher = varDecl(isInitCapture()))
-auto f = [x=3]() { return x; };
+Given
+auto f = [x = 3]() { return x; };
+
+The matcher varDecl(isInitCapture())
+matches x = 3.
Matches a static variable with local scope.
-Example matches y (matcher = varDecl(isStaticLocal()))
+Given
void f() {
int x;
static int y;
}
static int z;
+The matcher varDecl(isStaticLocal())
+matches y
Matches variable/function declarations that have "static" storage
class specifier ("static" keyword) written in the source.
-Given:
+Given
static void f() {}
static int i = 0;
extern int j;
int k;
-functionDecl(isStaticStorageClass())
- matches the function declaration f.
-varDecl(isStaticStorageClass())
- matches the variable declaration i.
+The matcher functionDecl(isStaticStorageClass())
+ matches f
+The matcher varDecl(isStaticStorageClass())
+ matches i
Matches nodes which can be used with binary operators. -The code - var1 != var2; -might be represented in the clang AST as a binaryOperator, a -cxxOperatorCallExpr or a cxxRewrittenBinaryOperator, depending on +A comparison of two expressions might be represented in the clang AST as a +binaryOperator, a cxxOperatorCallExpr or a +cxxRewrittenBinaryOperator, depending on * whether the types of var1 and var2 are fundamental (binaryOperator) or at least one is a class type (cxxOperatorCallExpr) @@ -6168,12 +8278,6 @@AST Traversal Matchers
compatible. Given - binaryOperation( - hasOperatorName("!="), - hasLHS(expr().bind("lhs")), - hasRHS(expr().bind("rhs")) - ) -matches each use of "!=" in: struct S{ bool operator!=(const S&) const; }; @@ -6187,25 +8291,28 @@AST Traversal Matchers
template<typename T> void templ() { - 1 != 2; + 3 != 4; T() != S(); } struct HasOpEq { - bool operator==(const HasOpEq &) const; + friend bool + operator==(const HasOpEq &, const HasOpEq&) noexcept = default; }; void inverse() { - HasOpEq s1; - HasOpEq s2; - if (s1 != s2) + HasOpEq e1; + HasOpEq e2; + if (e1 != e2) return; } struct HasSpaceship { - bool operator<=>(const HasOpEq &) const; + friend bool + operator<=>(const HasSpaceship &, + const HasSpaceship&) noexcept = default; }; void use_spaceship() @@ -6215,6 +8322,15 @@AST Traversal Matchers
if (s1 != s2) return; } + + +The matcher binaryOperation( + hasOperatorName("!="), + hasLHS(expr().bind("lhs")), + hasRHS(expr().bind("rhs")) + ) +matches 1 != 2, S() != S(), 3 != 4, +T() != S(), e1 != e2 and s1 != s2.
Matches AST nodes that have descendant AST nodes that match the
provided matcher.
-Example matches X, A, A::X, B, B::C, B::C::X
- (matcher = cxxRecordDecl(forEachDescendant(cxxRecordDecl(hasName("X")))))
+Given
class X {};
class A { class X {}; }; // Matches A, because A::X is a class of name
// X inside A.
class B { class C { class X {}; }; };
+The matcher
+cxxRecordDecl(forEachDescendant(cxxRecordDecl(hasName("X"))))
+matches X, A,
+B, class B::C
+and class B::C::X
+
DescendantT must be an AST base type.
As opposed to 'hasDescendant', 'forEachDescendant' will cause a match for
each result that matches instead of only on the first one.
Note: Recursively combined ForEachDescendant can cause many matches:
- cxxRecordDecl(forEachDescendant(cxxRecordDecl(
- forEachDescendant(cxxRecordDecl())
- )))
-will match 10 times (plus injected class name matches) on:
- class A { class B { class C { class D { class E {}; }; }; }; };
+ struct A {
+ struct B {
+ struct C {};
+ struct D {};
+ };
+ };
+
+
+The matcher cxxRecordDecl(forEachDescendant(cxxRecordDecl(
+ forEachDescendant(cxxRecordDecl().bind("inner"))
+ ).bind("middle")))
+will match 9 times:
+It matches the definition of A with the definition of
+B in the middle and the injected class name of
+B as the innermost cxxRecordDecl.
+
+It matches the definition of A with the definition of
+C in the middle and the definition of
+B as the innermost cxxRecordDecl.
+
+It matches the definition of A with the definition of
+C in the middle and the injected class name of
+B as the innermost cxxRecordDecl.
+
+It matches the definition of A with the definition of
+B in the middle and the definition of
+D as the innermost cxxRecordDecl.
+
+It matches the definition of A with the definition of
+B in the middle and the injected class name of
+D as the innermost cxxRecordDecl.
+
+It matches the definition of A with the definition of
+C in the middle and the injected class name of
+C as the innermost cxxRecordDecl.
+
+It matches the definition of A with the definition of
+D in the middle and the injected class name of
+D as the innermost cxxRecordDecl.
+
+It matches the definition of B with the definition of
+C in the middle and the injected class name of
+C as the innermost cxxRecordDecl.
+
+It matches the definition of B with the definition of
+D in the middle and the injected class name of
+D as the innermost cxxRecordDecl.
Usable as: Any Matcher
Matches AST nodes that have child AST nodes that match the
provided matcher.
-Example matches X, Y, Y::X, Z::Y, Z::Y::X
- (matcher = cxxRecordDecl(forEach(cxxRecordDecl(hasName("X")))
+Given
class X {};
class Y { class X {}; }; // Matches Y, because Y::X is a class of name X
// inside Y.
class Z { class Y { class X {}; }; }; // Does not match Z.
+The matcher cxxRecordDecl(forEach(cxxRecordDecl(hasName("X"))))
+matches class X,
+class Y,
+class Y::X,
+class Z::Y::X and class Z::Y
+
ChildT must be an AST base type.
As opposed to 'has', 'forEach' will cause a match for each result that
-matches instead of only on the first one.
+ matches instead of only on the first one.
Usable as: Any Matcher
Matches AST nodes that have descendant AST nodes that match the
provided matcher.
-Example matches X, Y, Z
- (matcher = cxxRecordDecl(hasDescendant(cxxRecordDecl(hasName("X")))))
+Given
class X {}; // Matches X, because X::X is a class of name X inside X.
class Y { class X {}; };
class Z { class Y { class X {}; }; };
+The matcher
+cxxRecordDecl(hasDescendant(cxxRecordDecl(hasName("X"))))
+matches class X {}, class Y { class X {}; }
+and class Z { class Y { class X {}; }; }.
+
DescendantT must be an AST base type.
Usable as: Any Matcher
@@ -6333,19 +8516,29 @@ AST Traversal Matchers
Matches AST nodes that have child AST nodes that match the
provided matcher.
-Example matches X, Y
- (matcher = cxxRecordDecl(has(cxxRecordDecl(hasName("X")))
+Given
class X {}; // Matches X, because X::X is a class of name X inside X.
class Y { class X {}; };
class Z { class Y { class X {}; }; }; // Does not match Z.
+The matcher cxxRecordDecl(has(cxxRecordDecl(hasName("X"))))
+matches class X {} three times,
+and class Y { class X {}; } two times.
+
ChildT must be an AST base type.
Usable as: Any Matcher
Note that has is direct matcher, so it also matches things like implicit
casts and paren casts. If you are matching with expr then you should
-probably consider using ignoringParenImpCasts like:
-has(ignoringParenImpCasts(expr())).
+probably consider using ignoringParenImpCasts:
+
+Given
+ int x =0;
+ double y = static_cast<double>(x);
+
+The matcher
+cxxStaticCastExpr(has(ignoringParenImpCasts(declRefExpr()))).
+matches static_cast<double>(x)
@@ -6355,7 +8548,9 @@ AST Traversal Matchers
Given
void f() { for (;;) { int x = 42; if (true) { int x = 43; } } }
-compoundStmt(hasParent(ifStmt())) matches "{ int x = 43; }".
+
+The matcher compoundStmt(hasParent(ifStmt()))
+matches { int x = 43; }
Usable as: Any Matcher
Matches the condition expression of an if statement, for loop,
switch statement or conditional operator.
-Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
+Given
+void foo() {
if (true) {}
+}
+
+The matcher ifStmt(hasCondition(cxxBoolLiteral(equals(true))))
+if (true) {}
Matches the true branch expression of a conditional operator.
Example 1 (conditional ternary operator): matches a
- condition ? a : b
+Given
+ void foo(bool condition, int a, int b) {
+ condition ? a : b;
+ }
+
+The matcher
+conditionalOperator(hasTrueExpression(expr().bind("true")))
+matches condition ? a : b,
+with expr() matching a.
Example 2 (conditional binary operator): matches opaqueValueExpr(condition)
- condition ?: b
+Given
+ void foo(bool condition, int a, int b) {
+ condition ?: b;
+ }
+
+The matcher binaryConditionalOperator(hasTrueExpression(expr()))
+matches condition ?: b,
+with expr() matching conditoin.
Matches a node if the declaration associated with that node -matches the given matcher. + matches the given matcher. The associated declaration is: - for type nodes, the declaration of the underlying type @@ -6477,17 +8699,25 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -For type nodes, hasDeclaration will generally match the declaration of the -sugared type. Given +Given class X {}; typedef X Y; Y y; -in varDecl(hasType(hasDeclaration(decl()))) the decl will match the -typedefDecl. A common use case is to match the underlying, desugared type. + +For type nodes, hasDeclaration will generally match the declaration of the +sugared type, i.e., the matcher +varDecl(hasType(qualType(hasDeclaration(decl().bind("d"))))), +matches Y y, with +the matcher decl() matching +typedef X Y;. +A common use case is to match the underlying, desugared type. This can be achieved by using the hasUnqualifiedDesugaredType matcher: - varDecl(hasType(hasUnqualifiedDesugaredType( - recordType(hasDeclaration(decl()))))) -In this matcher, the decl will match the CXXRecordDecl of class X. +varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl().bind("d")))))) +matches Y y. +In this matcher, the matcher decl() will match the +CXXRecordDecl +class X {};. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -6505,7 +8735,7 @@AST Traversal Matchers
Given int i[5]; void f() { i[1] = 42; } -arraySubscriptExpression(hasBase(implicitCastExpr( +The matcher arraySubscriptExpr(hasBase(implicitCastExpr( hasSourceExpression(declRefExpr())))) matches i[1] with the declRefExpr() matching i
Matches the left hand side of binary operator expressions.
-Example matches a (matcher = binaryOperator(hasLHS()))
- a || b
+Given
+void foo(bool a, bool b) {
+ a || b;
+}
+
+The matcher binaryOperator(hasLHS(expr().bind("lhs")))
+matches a || b,
+with expr()
+matching a.
Matches the right hand side of binary operator expressions.
-Example matches b (matcher = binaryOperator(hasRHS()))
- a || b
+Given
+void foo(bool a, bool b) {
+ a || b;
+}
+
+The matcher binaryOperator(hasRHS(expr().bind("rhs")))
+matches a || b,
+with expr()
+matching b.
Matches if either the left hand side or the right hand side of a
binary operator or fold expression matches.
+
+Given
+ struct S {};
+ bool operator ==(const S&, const S&);
+
+ void f(int a, const S&lhs, const S&rhs) {
+ a + 0;
+ lhs == rhs;
+ lhs != rhs;
+ }
+
+ template <typename ...Ts>
+ auto sum(Ts... args) {
+ return (0 + ... + args);
+ }
+
+
+The matcher binaryOperator(hasEitherOperand(integerLiteral()))
+matches a + 0.
+The matcher cxxOperatorCallExpr(hasEitherOperand(declRefExpr(to(
+parmVarDecl(hasName("lhs")))))) matches lhs == rhs and
+lhs != rhs.
+The matcher cxxFoldExpr(hasEitherOperand(integerLiteral()))
+matches (0 + ... + args).
Matches the left hand side of binary operator expressions.
-Example matches a (matcher = binaryOperator(hasLHS()))
- a || b
+Given
+void foo(bool a, bool b) {
+ a || b;
+}
+
+The matcher binaryOperator(hasLHS(expr().bind("lhs")))
+matches a || b,
+with expr()
+matching a.
Matches if both matchers match with opposite sides of the binary operator
or fold expression.
-Example matcher = binaryOperator(hasOperands(integerLiteral(equals(1),
- integerLiteral(equals(2)))
- 1 + 2 // Match
- 2 + 1 // Match
- 1 + 1 // No match
- 2 + 2 // No match
+Given
+void foo() {
+ 1 + 2; // Match
+ 2 + 1; // Match
+ 1 + 1; // No match
+ 2 + 2; // No match
+}
+The matcher binaryOperator(hasOperands(integerLiteral(equals(1)),
+ integerLiteral(equals(2))))
+matches 1 + 2 and 2 + 1,
+but does not match 1 + 1
+or 2 + 2.
Matches the right hand side of binary operator expressions.
-Example matches b (matcher = binaryOperator(hasRHS()))
- a || b
+Given
+void foo(bool a, bool b) {
+ a || b;
+}
+
+The matcher binaryOperator(hasRHS(expr().bind("rhs")))
+matches a || b,
+with expr()
+matching b.
Matches the DecompositionDecl the binding belongs to.
-For example, in:
+Given
void foo()
{
int arr[3];
@@ -6638,10 +8932,10 @@ AST Traversal Matchers
f = 42;
}
-The matcher:
- bindingDecl(hasName("f"),
- forDecomposition(decompositionDecl())
-matches 'f' in 'auto &[f, s, t]'.
+
+The matcher bindingDecl(hasName("f"),
+ forDecomposition(decompositionDecl()))
+matches f in 'auto &[f, s, t]'.
Matches if the type location of a node matches the inner matcher.
-Examples:
+Given
int x;
-declaratorDecl(hasTypeLoc(loc(asString("int"))))
- matches int x
+The matcher declaratorDecl(hasTypeLoc(loc(asString("int"))))
+matches int x.
+
+Given
+struct point { point(double, double); };
+point p = point(1.0, -1.0);
-auto x = int(3);
-cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int"))))
- matches int(3)
+The matcher
+cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point"))))
+matches point(1.0, -1.0).
+Given
struct Foo { Foo(int, int); };
-auto x = Foo(1, 2);
-cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo"))))
- matches Foo(1, 2)
+Foo x = Foo(1, 2);
+
+The matcher cxxTemporaryObjectExpr(hasTypeLoc(
+ loc(asString("Foo"))))
+matches Foo(1, 2).
Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>,
Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>,
@@ -6728,10 +9035,14 @@ AST Traversal Matchers
Given
int *a;
- int const *b;
- float const *f;
-pointerType(pointee(isConstQualified(), isInteger()))
- matches "int const *b"
+ const int *b;
+ int * const c = nullptr;
+ const float *f;
+
+The matcher pointerType(pointee(isConstQualified(), isInteger()))
+matches const int *,
+but does not match int * const
+or const float *.
Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>,
Matcher<PointerType>, Matcher<ReferenceType>
@@ -6741,19 +9052,26 @@ AST Traversal Matchers
Matcher<CXXBaseSpecifier> hasTypeLoc Matcher<TypeLoc> Inner
Matches if the type location of a node matches the inner matcher.
-Examples:
+Given
int x;
-declaratorDecl(hasTypeLoc(loc(asString("int"))))
- matches int x
+The matcher declaratorDecl(hasTypeLoc(loc(asString("int"))))
+matches int x.
+
+Given
+struct point { point(double, double); };
+point p = point(1.0, -1.0);
-auto x = int(3);
-cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int"))))
- matches int(3)
+The matcher
+cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point"))))
+matches point(1.0, -1.0).
+Given
struct Foo { Foo(int, int); };
-auto x = Foo(1, 2);
-cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo"))))
- matches Foo(1, 2)
+Foo x = Foo(1, 2);
+
+The matcher cxxTemporaryObjectExpr(hasTypeLoc(
+ loc(asString("Foo"))))
+matches Foo(1, 2).
Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>,
Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>,
@@ -6776,21 +9094,31 @@ AST Traversal Matchers
X, while varDecl(hasType(cxxRecordDecl(hasName("X")))) matches the
declaration of x.
-Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
- and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
- and friend class X (matcher = friendDecl(hasType("X"))
- and public virtual X (matcher = cxxBaseSpecifier(hasType(
- cxxRecordDecl(hasName("X"))))
class X {};
void y(X &x) { x; X z; }
class Y { friend class X; };
class Z : public virtual X {};
-Example matches class Derived
-(matcher = cxxRecordDecl(hasAnyBase(hasType(cxxRecordDecl(hasName("Base"))))))
+The matcher expr(hasType(cxxRecordDecl(hasName("X"))))
+matches x and z.
+The matcher varDecl(hasType(cxxRecordDecl(hasName("X"))))
+matches z.
+The matcher friendDecl(hasType(asString("class X")))
+matches friend class X.
+The matcher cxxRecordDecl(hasAnyBase(cxxBaseSpecifier(hasType(
+asString("X"))).bind("b"))) matches
+class Z : public virtual X {},
+with cxxBaseSpecifier(...)
+matching public virtual X.
+
+Given
class Base {};
class Derived : Base {};
+The matcher
+cxxRecordDecl(hasAnyBase(hasType(cxxRecordDecl(hasName("Base")))))
+matches class Derived : Base {}.
+
Usable as: Matcher<Expr>, Matcher<FriendDecl>, Matcher<ValueDecl>,
Matcher<CXXBaseSpecifier>
@@ -6800,17 +9128,25 @@ AST Traversal Matchers
Matches if the expression's or declaration's type matches a type
matcher.
-Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
- and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
- and U (matcher = typedefDecl(hasType(asString("int")))
- and friend class X (matcher = friendDecl(hasType("X"))
- and public virtual X (matcher = cxxBaseSpecifier(hasType(
- asString("class X")))
+Exmaple
class X {};
void y(X &x) { x; X z; }
typedef int U;
class Y { friend class X; };
class Z : public virtual X {};
+
+The matcher expr(hasType(cxxRecordDecl(hasName("X"))))
+matches x and z.
+The matcher varDecl(hasType(cxxRecordDecl(hasName("X"))))
+matches z
+The matcher typedefDecl(hasType(asString("int")))
+matches typedef int U
+The matcher friendDecl(hasType(asString("class X")))
+matches friend class X
+The matcher cxxRecordDecl(hasAnyBase(cxxBaseSpecifier(hasType(
+asString("X"))).bind("b"))) matches class Z : public virtual X {},
+with cxxBaseSpecifier(...)
+matching public virtual X.
@@ -6820,8 +9156,10 @@ AST Traversal Matchers
Given
void f(int i);
int y;
- f(y);
-callExpr(
+ void foo() {
+ f(y);
+ }
+The matcher callExpr(
forEachArgumentWithParam(
declRefExpr(to(varDecl(hasName("y")))),
parmVarDecl(hasType(isInteger()))
@@ -6844,14 +9182,15 @@ AST Traversal Matchers
Given
void f(int i);
- int y;
- f(y);
- void (*f_ptr)(int) = f;
- f_ptr(y);
-callExpr(
+ void foo(int y) {
+ f(y);
+ void (*f_ptr)(int) = f;
+ f_ptr(y);
+ }
+The matcher callExpr(
forEachArgumentWithParamType(
declRefExpr(to(varDecl(hasName("y")))),
- qualType(isInteger()).bind("type)
+ qualType(isInteger()).bind("type")
))
matches f(y) and f_ptr(y)
with declRefExpr(...)
@@ -6866,17 +9205,19 @@ AST Traversal Matchers
expression, or an ObjC-message-send expression.
Given
- void x(int, int, int) { int y; x(1, y, 42); }
-callExpr(hasAnyArgument(declRefExpr()))
- matches x(1, y, 42)
-with hasAnyArgument(...)
+ void x(int, int, int) { int y = 42; x(1, y, 42); }
+The matcher
+callExpr(hasAnyArgument(ignoringImplicit(declRefExpr()))) matches
+x(1, y, 42) with hasAnyArgument(...)
matching y
For ObjectiveC, given
@interface I - (void) f:(int) y; @end
void foo(I *i) { [i f:12]; }
+
+The matcher
objcMessageExpr(hasAnyArgument(integerLiteral(equals(12))))
- matches [i f:12]
+matches [i f:12]
Matches the n'th argument of a call expression or a constructor
call expression.
-Example matches y in x(y)
- (matcher = callExpr(hasArgument(0, declRefExpr())))
+Given
void x(int) { int y; x(y); }
+The matcher callExpr(hasArgument(0, declRefExpr().bind("arg")))
+matches x(y),
+with declRefExpr() matching y.
Matches a node if the declaration associated with that node -matches the given matcher. + matches the given matcher. The associated declaration is: - for type nodes, the declaration of the underlying type @@ -6902,17 +9245,25 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -For type nodes, hasDeclaration will generally match the declaration of the -sugared type. Given +Given class X {}; typedef X Y; Y y; -in varDecl(hasType(hasDeclaration(decl()))) the decl will match the -typedefDecl. A common use case is to match the underlying, desugared type. + +For type nodes, hasDeclaration will generally match the declaration of the +sugared type, i.e., the matcher +varDecl(hasType(qualType(hasDeclaration(decl().bind("d"))))), +matches Y y, with +the matcher decl() matching +typedef X Y;. +A common use case is to match the underlying, desugared type. This can be achieved by using the hasUnqualifiedDesugaredType matcher: - varDecl(hasType(hasUnqualifiedDesugaredType( - recordType(hasDeclaration(decl()))))) -In this matcher, the decl will match the CXXRecordDecl of class X. +varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl().bind("d")))))) +matches Y y. +In this matcher, the matcher decl() will match the +CXXRecordDecl +class X {};. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -6929,10 +9280,12 @@AST Traversal Matchers
Given class A { A() : i(42), j(42) {} int i; int j; }; -cxxConstructorDecl(forEachConstructorInitializer( - forField(decl().bind("x")) -)) - will trigger two matches, binding for 'i' and 'j' respectively. + +The matcher cxxConstructorDecl(forEachConstructorInitializer( + forField(fieldDecl().bind("x")))) +matches the constructor of A twice, with +fieldDecl() matching i and +j respectively.
Matches if the type location of a node matches the inner matcher.
-Examples:
+Given
int x;
-declaratorDecl(hasTypeLoc(loc(asString("int"))))
- matches int x
+The matcher declaratorDecl(hasTypeLoc(loc(asString("int"))))
+matches int x.
+
+Given
+struct point { point(double, double); };
+point p = point(1.0, -1.0);
-auto x = int(3);
-cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int"))))
- matches int(3)
+The matcher
+cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point"))))
+matches point(1.0, -1.0).
+Given
struct Foo { Foo(int, int); };
-auto x = Foo(1, 2);
-cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo"))))
- matches Foo(1, 2)
+Foo x = Foo(1, 2);
+
+The matcher cxxTemporaryObjectExpr(hasTypeLoc(
+ loc(asString("Foo"))))
+matches Foo(1, 2).
Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>,
Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>,
@@ -7002,9 +9365,11 @@ AST Traversal Matchers
Foo() : foo_(1) { }
int foo_;
};
+
+The matcher
cxxRecordDecl(has(cxxConstructorDecl(hasAnyConstructorInitializer(
withInitializer(integerLiteral(equals(1)))))))
- matches Foo
+matches Foo
with withInitializer matching (1)
Matches if either the left hand side or the right hand side of a
binary operator or fold expression matches.
+
+Given
+ struct S {};
+ bool operator ==(const S&, const S&);
+
+ void f(int a, const S&lhs, const S&rhs) {
+ a + 0;
+ lhs == rhs;
+ lhs != rhs;
+ }
+
+ template <typename ...Ts>
+ auto sum(Ts... args) {
+ return (0 + ... + args);
+ }
+
+
+The matcher binaryOperator(hasEitherOperand(integerLiteral()))
+matches a + 0.
+The matcher cxxOperatorCallExpr(hasEitherOperand(declRefExpr(to(
+parmVarDecl(hasName("lhs")))))) matches lhs == rhs and
+lhs != rhs.
+The matcher cxxFoldExpr(hasEitherOperand(integerLiteral()))
+matches (0 + ... + args).
Matches the operand that does not contain the parameter pack.
-Example matches `(0 + ... + args)` and `(args * ... * 1)`
- (matcher = cxxFoldExpr(hasFoldInit(expr())))
- with hasFoldInit(...)
- matching `0` and `1` respectively
+Given
template <typename... Args>
auto sum(Args... args) {
return (0 + ... + args);
@@ -7082,14 +9483,27 @@ AST Traversal Matchers
auto multiply(Args... args) {
return (args * ... * 1);
}
+
+
+The matcher cxxFoldExpr(hasFoldInit(expr().bind("init")))
+matches (0 + ... + args) and (args * ... * 1)
+with hasFoldInit(expr().bind("init")) matching
+0 and 1.
Matches the left hand side of binary operator expressions.
-Example matches a (matcher = binaryOperator(hasLHS()))
- a || b
+Given
+void foo(bool a, bool b) {
+ a || b;
+}
+
+The matcher binaryOperator(hasLHS(expr().bind("lhs")))
+matches a || b,
+with expr()
+matching a.
Matches if both matchers match with opposite sides of the binary operator
or fold expression.
-Example matcher = binaryOperator(hasOperands(integerLiteral(equals(1),
- integerLiteral(equals(2)))
- 1 + 2 // Match
- 2 + 1 // Match
- 1 + 1 // No match
- 2 + 2 // No match
+Given
+void foo() {
+ 1 + 2; // Match
+ 2 + 1; // Match
+ 1 + 1; // No match
+ 2 + 2; // No match
+}
+The matcher binaryOperator(hasOperands(integerLiteral(equals(1)),
+ integerLiteral(equals(2))))
+matches 1 + 2 and 2 + 1,
+but does not match 1 + 1
+or 2 + 2.
Matches the operand that contains the parameter pack.
-Example matches `(0 + ... + args)`
- (matcher = cxxFoldExpr(hasPattern(expr())))
- with hasPattern(...)
- matching `args`
+Given
template <typename... Args>
auto sum(Args... args) {
return (0 + ... + args);
@@ -7122,14 +9539,27 @@ AST Traversal Matchers
auto multiply(Args... args) {
return (args * ... * 1);
}
+
+
+The matcher cxxFoldExpr(hasPattern(expr().bind("pattern")))
+matches (0 + ... + args) and (args * ... * 1),
+with hasPattern(expr().bind("pattern")) matching
+args two times.
Matches the right hand side of binary operator expressions.
-Example matches b (matcher = binaryOperator(hasRHS()))
- a || b
+Given
+void foo(bool a, bool b) {
+ a || b;
+}
+
+The matcher binaryOperator(hasRHS(expr().bind("rhs")))
+matches a || b,
+with expr()
+matching b.
Matches selection statements with initializer.
-Given:
+Given
+ struct vec { int* begin(); int* end(); };
+ int foobar();
+ vec& get_range();
void foo() {
if (int i = foobar(); i > 0) {}
switch (int i = foobar(); i) {}
@@ -7171,51 +9606,71 @@ AST Traversal Matchers
switch (foobar()) {}
for (auto& x : get_range()) {}
}
-ifStmt(hasInitStatement(anything()))
- matches the if statement in foo but not in bar.
-switchStmt(hasInitStatement(anything()))
- matches the switch statement in foo but not in bar.
-cxxForRangeStmt(hasInitStatement(anything()))
- matches the range for statement in foo but not in bar.
+
+The matcher ifStmt(hasInitStatement(anything()))
+ matches the if statement if (int i = foobar(); i > 0) {}
+ in foo but not if (foobar() > 0) {} in bar.
+The matcher switchStmt(hasInitStatement(anything()))
+ matches the switch statement switch (int i = foobar(); i) {}
+ in foo but not switch (foobar()) {} in bar.
+The matcher cxxForRangeStmt(hasInitStatement(anything()))
+ matches the range for statement
+ for (auto& a = get_range(); auto& x : a) {} in foo
+ but not for (auto& x : get_range()) {} in bar.
Matches the initialization statement of a for loop.
-Example:
- forStmt(hasLoopVariable(anything()))
-matches 'int x' in
+Given
+ void foo() {
+ int a[42] = {};
for (int x : a) { }
+ }
+
+The matcher cxxForRangeStmt(hasLoopVariable(anything()))
+matches for (int x : a) { }
Matches the range initialization statement of a for loop.
-Example:
- forStmt(hasRangeInit(anything()))
-matches 'a' in
+Given
+ void foo() {
+ int a[42] = {};
for (int x : a) { }
+ }
+
+The matcher cxxForRangeStmt(hasRangeInit(anything()))
+matches for (int x : a) { }
Matches if the type location of a node matches the inner matcher.
-Examples:
+Given
int x;
-declaratorDecl(hasTypeLoc(loc(asString("int"))))
- matches int x
+The matcher declaratorDecl(hasTypeLoc(loc(asString("int"))))
+matches int x.
+
+Given
+struct point { point(double, double); };
+point p = point(1.0, -1.0);
-auto x = int(3);
-cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int"))))
- matches int(3)
+The matcher
+cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point"))))
+matches point(1.0, -1.0).
+Given
struct Foo { Foo(int, int); };
-auto x = Foo(1, 2);
-cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo"))))
- matches Foo(1, 2)
+Foo x = Foo(1, 2);
+
+The matcher cxxTemporaryObjectExpr(hasTypeLoc(
+ loc(asString("Foo"))))
+matches Foo(1, 2).
Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>,
Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>,
@@ -7235,13 +9690,16 @@ AST Traversal Matchers
Given
class Y { public: void m(); };
Y g();
- class X : public Y { void g(); };
+ class X : public Y { public: void g(); };
void z(Y y, X x) { y.m(); x.m(); x.g(); (g()).m(); }
-cxxMemberCallExpr(onImplicitObjectArgument(hasType(
+
+The matcher cxxMemberCallExpr(onImplicitObjectArgument(hasType(
cxxRecordDecl(hasName("Y")))))
- matches `y.m()`, `x.m()` and (`g()).m()`, but not `x.g()`).
-cxxMemberCallExpr(on(callExpr()))
- only matches `(g()).m()` (the parens are ignored).
+matches y.m(), x.m() and (g()).m()
+but does not match x.g().
+The matcher cxxMemberCallExpr(on(callExpr()))
+only matches (g()).m(), because the parens are ignored.
+FIXME: should they be ignored? (ignored bc of `on`)
FIXME: Overload to allow directly matching types?
Overloaded to match the type's declaration.
+
+Given
+ class Y { public: void m(); };
+ class X : public Y { public: void g(); };
+ void z() { Y y; y.m(); Y *p; p->m(); X x; x.m(); x.g(); }
+
+The matcher cxxMemberCallExpr(thisPointerType(
+ cxxRecordDecl(hasName("Y"))))
+ matches y.m(), p->m() and x.m().
+The matcher cxxMemberCallExpr(thisPointerType(
+ cxxRecordDecl(hasName("X"))))
+ matches x.g().
Matches if the type of the expression's implicit object argument either
-matches the InnerMatcher, or is a pointer to a type that matches the
+ matches the InnerMatcher, or is a pointer to a type that matches the
InnerMatcher.
Given
- class Y { public: void m(); };
- class X : public Y { void g(); };
- void z() { Y y; y.m(); Y *p; p->m(); X x; x.m(); x.g(); }
-cxxMemberCallExpr(thisPointerType(hasDeclaration(
- cxxRecordDecl(hasName("Y")))))
- matches `y.m()`, `p->m()` and `x.m()`.
-cxxMemberCallExpr(thisPointerType(hasDeclaration(
- cxxRecordDecl(hasName("X")))))
- matches `x.g()`.
+ class Y { public: void m() const; };
+ class X : public Y { public: void g(); };
+ void z() { const Y y; y.m(); const Y *p; p->m(); X x; x.m(); x.g(); }
+
+The matcher
+cxxMemberCallExpr(thisPointerType(isConstQualified()))
+matches y.m(), x.m() and p->m(),
+but not x.g().
Matches any placement new expression arguments.
-Given:
+Given
+ void* operator new(decltype(sizeof(void*)), void*);
+ struct MyClass { int x; };
+ unsigned char Storage[sizeof(MyClass) * 10];
MyClass *p1 = new (Storage) MyClass();
-cxxNewExpr(hasAnyPlacementArg(anything()))
- matches the expression 'new (Storage, 16) MyClass()'.
+
+
+The matcher cxxNewExpr(hasAnyPlacementArg(anything()))
+matches new (Storage) MyClass().
Matches array new expressions with a given array size.
-Given:
+Given
+ void* operator new(decltype(sizeof(void*)));
+ struct MyClass { int x; };
MyClass *p1 = new MyClass[10];
-cxxNewExpr(hasArraySize(integerLiteral(equals(10))))
- matches the expression 'new MyClass[10]'.
+
+
+The matcher
+cxxNewExpr(hasArraySize(
+ ignoringImplicit(integerLiteral(equals(10)))))
+matches new MyClass[10].
Matches a node if the declaration associated with that node -matches the given matcher. + matches the given matcher. The associated declaration is: - for type nodes, the declaration of the underlying type @@ -7365,17 +9857,25 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -For type nodes, hasDeclaration will generally match the declaration of the -sugared type. Given +Given class X {}; typedef X Y; Y y; -in varDecl(hasType(hasDeclaration(decl()))) the decl will match the -typedefDecl. A common use case is to match the underlying, desugared type. + +For type nodes, hasDeclaration will generally match the declaration of the +sugared type, i.e., the matcher +varDecl(hasType(qualType(hasDeclaration(decl().bind("d"))))), +matches Y y, with +the matcher decl() matching +typedef X Y;. +A common use case is to match the underlying, desugared type. This can be achieved by using the hasUnqualifiedDesugaredType matcher: - varDecl(hasType(hasUnqualifiedDesugaredType( - recordType(hasDeclaration(decl()))))) -In this matcher, the decl will match the CXXRecordDecl of class X. +varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl().bind("d")))))) +matches Y y. +In this matcher, the matcher decl() will match the +CXXRecordDecl +class X {};. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -7390,29 +9890,42 @@AST Traversal Matchers
Matcher<CXXNewExpr> hasPlacementArg unsigned Index, Matcher<Expr> InnerMatcher Matches placement new expression arguments. -Given: - MyClass *p1 = new (Storage, 16) MyClass(); -cxxNewExpr(hasPlacementArg(1, integerLiteral(equals(16)))) - matches the expression 'new (Storage, 16) MyClass()'. +Given + void *operator new(decltype(sizeof(void*)), int, void*); + struct MyClass { int x; }; + unsigned char Storage[sizeof(MyClass) * 10]; + MyClass *p1 = new (16, Storage) MyClass(); + + +The matcher cxxNewExpr(hasPlacementArg(0, + integerLiteral(equals(16)))) +matches new (16, Storage) MyClass().Matcher<CXXNewExpr> hasTypeLoc Matcher<TypeLoc> Inner @@ -7545,38 +10121,90 @@ Matches if the type location of a node matches the inner matcher. -Examples: +Given int x; -declaratorDecl(hasTypeLoc(loc(asString("int")))) - matches int x +The matcher declaratorDecl(hasTypeLoc(loc(asString("int")))) +matches int x. + +Given +struct point { point(double, double); }; +point p = point(1.0, -1.0); -auto x = int(3); -cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) - matches int(3) +The matcher +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point")))) +matches point(1.0, -1.0). +Given struct Foo { Foo(int, int); }; -auto x = Foo(1, 2); -cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) - matches Foo(1, 2) +Foo x = Foo(1, 2); + +The matcher cxxTemporaryObjectExpr(hasTypeLoc( + loc(asString("Foo")))) +matches Foo(1, 2). Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, @@ -7428,14 +9941,45 @@AST Traversal Matchers
Matcher<CXXOperatorCallExpr> hasEitherOperand Matcher<Expr> InnerMatcher Matches if either the left hand side or the right hand side of a binary operator or fold expression matches. + +Given + struct S {}; + bool operator ==(const S&, const S&); + + void f(int a, const S&lhs, const S&rhs) { + a + 0; + lhs == rhs; + lhs != rhs; + } + + template <typename ...Ts> + auto sum(Ts... args) { + return (0 + ... + args); + } + + +The matcher binaryOperator(hasEitherOperand(integerLiteral())) +matches a + 0. +The matcher cxxOperatorCallExpr(hasEitherOperand(declRefExpr(to( +parmVarDecl(hasName("lhs")))))) matches lhs == rhs and +lhs != rhs. +The matcher cxxFoldExpr(hasEitherOperand(integerLiteral())) +matches (0 + ... + args).Matcher<CXXOperatorCallExpr> hasLHS Matcher<Expr> InnerMatcher @@ -7443,44 +9987,64 @@ Matches the left hand side of binary operator expressions. -Example matches a (matcher = binaryOperator(hasLHS())) - a || b +Given +void foo(bool a, bool b) { + a || b; +} + +The matcher binaryOperator(hasLHS(expr().bind("lhs"))) +matches a || b, +with expr() +matching a.AST Traversal Matchers
Matches if both matchers match with opposite sides of the binary operator or fold expression. -Example matcher = binaryOperator(hasOperands(integerLiteral(equals(1), - integerLiteral(equals(2))) - 1 + 2 // Match - 2 + 1 // Match - 1 + 1 // No match - 2 + 2 // No match +Given +void foo() { + 1 + 2; // Match + 2 + 1; // Match + 1 + 1; // No match + 2 + 2; // No match +} +The matcher binaryOperator(hasOperands(integerLiteral(equals(1)), + integerLiteral(equals(2)))) +matches 1 + 2 and 2 + 1, +but does not match 1 + 1 +or 2 + 2.Matcher<CXXOperatorCallExpr> hasRHS Matcher<Expr> InnerMatcher Matches the right hand side of binary operator expressions. -Example matches b (matcher = binaryOperator(hasRHS())) - a || b +Given +void foo(bool a, bool b) { + a || b; +} + +The matcher binaryOperator(hasRHS(expr().bind("rhs"))) +matches a || b, +with expr() +matching b.Matcher<CXXOperatorCallExpr> hasUnaryOperand Matcher<Expr> InnerMatcher Matches if the operand of a unary operator matches. -Example matches true (matcher = hasUnaryOperand( - cxxBoolLiteral(equals(true)))) - !true +void foo() { + !true; +} + +The matcher +unaryOperator(hasUnaryOperand(cxxBoolLiteral(equals(true)))) +matches !true.Matcher<CXXRecordDecl> hasAnyBase Matcher<CXXBaseSpecifier> BaseSpecMatcher @@ -7488,26 +10052,31 @@ Matches C++ classes that have a direct or indirect base matching BaseSpecMatcher. -Example: -matcher hasAnyBase(hasType(cxxRecordDecl(hasName("SpecialBase")))) - class Foo; +Given + class Foo {}; class Bar : Foo {}; class Baz : Bar {}; - class SpecialBase; + class SpecialBase {}; class Proxy : SpecialBase {}; // matches Proxy class IndirectlyDerived : Proxy {}; //matches IndirectlyDerived + +The matcher +cxxRecordDecl(hasAnyBase(hasType(cxxRecordDecl(hasName("SpecialBase"))))) +matches Proxy and IndirectlyDerived FIXME: Refactor this and isDerivedFrom to reuse implementation.AST Traversal Matchers
Matcher<CXXRecordDecl> hasDirectBase Matcher<CXXBaseSpecifier> BaseSpecMatcher Matches C++ classes that have a direct base matching BaseSpecMatcher. -Example: -matcher hasDirectBase(hasType(cxxRecordDecl(hasName("SpecialBase")))) - class Foo; +Given + class Foo {}; class Bar : Foo {}; class Baz : Bar {}; - class SpecialBase; + class SpecialBase {}; class Proxy : SpecialBase {}; // matches Proxy class IndirectlyDerived : Proxy {}; // doesn't match + +The matcher +cxxRecordDecl(hasDirectBase(hasType(cxxRecordDecl(hasName("SpecialBase"))))) +matches ProxyMatcher<CXXRecordDecl> hasMethod Matcher<CXXMethodDecl> InnerMatcher @@ -7519,22 +10088,29 @@ Matches the first method of a class or struct that satisfies InnerMatcher. -Given: +Given class A { void func(); }; class B { void member(); }; -cxxRecordDecl(hasMethod(hasName("func"))) matches the declaration of -A but not B. + +The matcher cxxRecordDecl(hasMethod(hasName("func"))) +matches the declaration of class A { void func(); } +but does not match class B { void member(); }AST Traversal Matchers
Note that a class is not considered to be derived from itself. Example matches Y, Z, C (Base == hasName("X")) - class X; + class X {}; class Y : public X {}; // directly derived class Z : public Y {}; // indirectly derived typedef X A; typedef A B; class C : public B {}; // derived from a typedef of X -In the following example, Bar matches isDerivedFrom(hasName("X")): - class Foo; - typedef Foo X; - class Bar : public Foo {}; // derived from a type that X is a typedef of + class Foo {}; + typedef Foo Alias; + class Bar : public Alias {}; + // derived from a type that Alias is a typedef of Foo + + +The matcher cxxRecordDecl(isDerivedFrom(hasName("X"))) +matches Y, Z and C. +The matcher cxxRecordDecl(isDerivedFrom(hasName("Foo"))) +matches Bar. In the following example, Bar matches isDerivedFrom(hasName("NSObject")) @interface NSObject @end @interface Bar : NSObject @end + Usable as: Matcher<CXXRecordDecl>, Matcher<ObjCInterfaceDecl>AST Traversal Matchers
Note that a class is not considered to be derived from itself. -Example matches Y, C (Base == hasName("X")) - class X; +Given + class X {}; class Y : public X {}; // directly derived class Z : public Y {}; // indirectly derived typedef X A; typedef A B; class C : public B {}; // derived from a typedef of X +The matcher +cxxRecordDecl(isDirectlyDerivedFrom(namedDecl(hasName("X")))) +matches Y and C (Base == hasName("X") + In the following example, Bar matches isDerivedFrom(hasName("X")): - class Foo; + class Foo {}; typedef Foo X; class Bar : public Foo {}; // derived from a type that X is a typedef of + +The matcher cxxRecordDecl(isDerivedFrom(hasName("X"))) +matches Bar
Similar to isDerivedFrom(), but also matches classes that directly
match Base.
+
+Given
+ class X {};
+ class Y : public X {}; // directly derived
+ class Z : public Y {}; // indirectly derived
+ typedef X A;
+ typedef A B;
+ class C : public B {}; // derived from a typedef of X
+
+The matcher
+cxxRecordDecl(isSameOrDerivedFrom(cxxRecordDecl(hasName("X"))),
+isDefinition())
+matches class X {}, class Y : public X {},
+class Z : public Y {} and class C : public B {}.
Matches if either the left hand side or the right hand side of a
binary operator or fold expression matches.
+
+Given
+ struct S {};
+ bool operator ==(const S&, const S&);
+
+ void f(int a, const S&lhs, const S&rhs) {
+ a + 0;
+ lhs == rhs;
+ lhs != rhs;
+ }
+
+ template <typename ...Ts>
+ auto sum(Ts... args) {
+ return (0 + ... + args);
+ }
+
+
+The matcher binaryOperator(hasEitherOperand(integerLiteral()))
+matches a + 0.
+The matcher cxxOperatorCallExpr(hasEitherOperand(declRefExpr(to(
+parmVarDecl(hasName("lhs")))))) matches lhs == rhs and
+lhs != rhs.
+The matcher cxxFoldExpr(hasEitherOperand(integerLiteral()))
+matches (0 + ... + args).
Matches the left hand side of binary operator expressions.
-Example matches a (matcher = binaryOperator(hasLHS()))
- a || b
+Given
+void foo(bool a, bool b) {
+ a || b;
+}
+
+The matcher binaryOperator(hasLHS(expr().bind("lhs")))
+matches a || b,
+with expr()
+matching a.
Matches if both matchers match with opposite sides of the binary operator
or fold expression.
-Example matcher = binaryOperator(hasOperands(integerLiteral(equals(1),
- integerLiteral(equals(2)))
- 1 + 2 // Match
- 2 + 1 // Match
- 1 + 1 // No match
- 2 + 2 // No match
+Given
+void foo() {
+ 1 + 2; // Match
+ 2 + 1; // Match
+ 1 + 1; // No match
+ 2 + 2; // No match
+}
+The matcher binaryOperator(hasOperands(integerLiteral(equals(1)),
+ integerLiteral(equals(2))))
+matches 1 + 2 and 2 + 1,
+but does not match 1 + 1
+or 2 + 2.
Matches the right hand side of binary operator expressions.
-Example matches b (matcher = binaryOperator(hasRHS()))
- a || b
+Given
+void foo(bool a, bool b) {
+ a || b;
+}
+
+The matcher binaryOperator(hasRHS(expr().bind("rhs")))
+matches a || b,
+with expr()
+matching b.
Matches if the type location of a node matches the inner matcher.
-Examples:
+Given
int x;
-declaratorDecl(hasTypeLoc(loc(asString("int"))))
- matches int x
+The matcher declaratorDecl(hasTypeLoc(loc(asString("int"))))
+matches int x.
+
+Given
+struct point { point(double, double); };
+point p = point(1.0, -1.0);
-auto x = int(3);
-cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int"))))
- matches int(3)
+The matcher
+cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point"))))
+matches point(1.0, -1.0).
+Given
struct Foo { Foo(int, int); };
-auto x = Foo(1, 2);
-cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo"))))
- matches Foo(1, 2)
+Foo x = Foo(1, 2);
+
+The matcher cxxTemporaryObjectExpr(hasTypeLoc(
+ loc(asString("Foo"))))
+matches Foo(1, 2).
Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>,
Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>,
@@ -7634,17 +10282,19 @@ AST Traversal Matchers
expression, or an ObjC-message-send expression.
Given
- void x(int, int, int) { int y; x(1, y, 42); }
-callExpr(hasAnyArgument(declRefExpr()))
- matches x(1, y, 42)
-with hasAnyArgument(...)
+ void x(int, int, int) { int y = 42; x(1, y, 42); }
+The matcher
+callExpr(hasAnyArgument(ignoringImplicit(declRefExpr()))) matches
+x(1, y, 42) with hasAnyArgument(...)
matching y
For ObjectiveC, given
@interface I - (void) f:(int) y; @end
void foo(I *i) { [i f:12]; }
+
+The matcher
objcMessageExpr(hasAnyArgument(integerLiteral(equals(12))))
- matches [i f:12]
+matches [i f:12]
Matches the n'th argument of a call expression or a constructor
call expression.
-Example matches y in x(y)
- (matcher = callExpr(hasArgument(0, declRefExpr())))
+Given
void x(int) { int y; x(y); }
+The matcher callExpr(hasArgument(0, declRefExpr().bind("arg")))
+matches x(y),
+with declRefExpr() matching y.
Matches if the type location of a node matches the inner matcher.
-Examples:
+Given
int x;
-declaratorDecl(hasTypeLoc(loc(asString("int"))))
- matches int x
+The matcher declaratorDecl(hasTypeLoc(loc(asString("int"))))
+matches int x.
+
+Given
+struct point { point(double, double); };
+point p = point(1.0, -1.0);
-auto x = int(3);
-cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int"))))
- matches int(3)
+The matcher
+cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point"))))
+matches point(1.0, -1.0).
+Given
struct Foo { Foo(int, int); };
-auto x = Foo(1, 2);
-cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo"))))
- matches Foo(1, 2)
+Foo x = Foo(1, 2);
+
+The matcher cxxTemporaryObjectExpr(hasTypeLoc(
+ loc(asString("Foo"))))
+matches Foo(1, 2).
Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>,
Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>,
@@ -7691,19 +10350,23 @@ AST Traversal Matchers
given matcher; or 2) if the Obj-C message expression's callee's method
declaration matches the given matcher.
-Example matches y.x() (matcher = callExpr(callee(
- cxxMethodDecl(hasName("x")))))
+Example 1
class Y { public: void x(); };
void z() { Y y; y.x(); }
-Example 2. Matches [I foo] with
-objcMessageExpr(callee(objcMethodDecl(hasName("foo"))))
+The matcher callExpr(callee(cxxMethodDecl(hasName("x"))))
+matches y.x()
+Example 2
@interface I: NSObject
+(void)foo;
@end
...
[I foo]
+
+The matcher
+objcMessageExpr(callee(objcMethodDecl(hasName("foo"))))
+matches [I foo]
Matches the n'th argument of a call expression or a constructor
call expression.
-Example matches y in x(y)
- (matcher = callExpr(hasArgument(0, declRefExpr())))
+Given
void x(int) { int y; x(y); }
+The matcher callExpr(hasArgument(0, declRefExpr().bind("arg")))
+matches x(y),
+with declRefExpr() matching y.
Matches a node if the declaration associated with that node -matches the given matcher. + matches the given matcher. The associated declaration is: - for type nodes, the declaration of the underlying type @@ -7828,17 +10510,25 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -For type nodes, hasDeclaration will generally match the declaration of the -sugared type. Given +Given class X {}; typedef X Y; Y y; -in varDecl(hasType(hasDeclaration(decl()))) the decl will match the -typedefDecl. A common use case is to match the underlying, desugared type. + +For type nodes, hasDeclaration will generally match the declaration of the +sugared type, i.e., the matcher +varDecl(hasType(qualType(hasDeclaration(decl().bind("d"))))), +matches Y y, with +the matcher decl() matching +typedef X Y;. +A common use case is to match the underlying, desugared type. This can be achieved by using the hasUnqualifiedDesugaredType matcher: - varDecl(hasType(hasUnqualifiedDesugaredType( - recordType(hasDeclaration(decl()))))) -In this matcher, the decl will match the CXXRecordDecl of class X. +varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl().bind("d")))))) +matches Y y. +In this matcher, the matcher decl() will match the +CXXRecordDecl +class X {};. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -7855,9 +10545,12 @@AST Traversal Matchers
extension, matches the constant given in the statement. Given - switch (1) { case 1: case 1+1: case 3 ... 4: ; } -caseStmt(hasCaseConstant(integerLiteral())) - matches "case 1:" + void foo() { + switch (1) { case 1: break; case 1+1: break; case 3 ... 4: break; } + } +The matcher +caseStmt(hasCaseConstant(constantExpr(has(integerLiteral())))) +matches case 1: break.
Matches if the cast's source expression
or opaque value's source expression matches the given matcher.
-Example 1: matches "a string"
-(matcher = castExpr(hasSourceExpression(cxxConstructExpr())))
-class URL { URL(string); };
-URL url = "a string";
+Given
+ struct URL { URL(const char*); };
+ URL url = "a string";
+
+The matcher castExpr(hasSourceExpression(cxxConstructExpr()))
+matches "a string".
+
+Given
+void foo(bool b) {
+ int a = b ?: 1;
+}
-Example 2: matches 'b' (matcher =
-opaqueValueExpr(hasSourceExpression(implicitCastExpr(declRefExpr())))
-int a = b ?: 1;
+The matcher
+opaqueValueExpr(hasSourceExpression(
+ implicitCastExpr(has(
+ implicitCastExpr(has(declRefExpr()))))))
+matches b twice, for the conditiona and the true expression.
Matches the specialized template of a specialization declaration.
Given
- template<typename T> class A {}; #1
- template<> class A<int> {}; #2
-classTemplateSpecializationDecl(hasSpecializedTemplate(classTemplateDecl()))
- matches '#2' with classTemplateDecl() matching the class template
- declaration of 'A' at #1.
+ template<typename T> class A {}; // #1
+ template<> class A<int> {}; // #2
+
+The matcher
+classTemplateSpecializationDecl(hasSpecializedTemplate(classTemplateDecl().bind("ctd")))
+matches template<> class A<int> {},
+with classTemplateDecl() matching the class template
+declaration template <typename T> class A {}.
Matches if the type location of a node matches the inner matcher.
-Examples:
+Given
int x;
-declaratorDecl(hasTypeLoc(loc(asString("int"))))
- matches int x
+The matcher declaratorDecl(hasTypeLoc(loc(asString("int"))))
+matches int x.
+
+Given
+struct point { point(double, double); };
+point p = point(1.0, -1.0);
-auto x = int(3);
-cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int"))))
- matches int(3)
+The matcher
+cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point"))))
+matches point(1.0, -1.0).
+Given
struct Foo { Foo(int, int); };
-auto x = Foo(1, 2);
-cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo"))))
- matches Foo(1, 2)
+Foo x = Foo(1, 2);
+
+The matcher cxxTemporaryObjectExpr(hasTypeLoc(
+ loc(asString("Foo"))))
+matches Foo(1, 2).
Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>,
Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>,
@@ -8035,11 +10770,12 @@ AST Traversal Matchers
a given matcher. Also matches StmtExprs that have CompoundStmt as children.
Given
- { {}; 1+2; }
-hasAnySubstatement(compoundStmt())
- matches '{ {}; 1+2; }'
+void foo() { { {}; 1+2; } }
+The matcher
+compoundStmt(hasAnySubstatement(compoundStmt().bind("compound")))
+{ {}; 1+2; } and { { {}; 1+2; } }
with compoundStmt()
- matching '{}'
+matching {} and { {}; 1+2; }.
Matches the decayed type, whoes decayed type matches InnerMatcher
+
+Given
+ void f(int i[]) {
+ i[1] = 0;
+ }
+
+The matcher parmVarDecl(hasType(decayedType()))
+matches int i[].
Matches a node if the declaration associated with that node -matches the given matcher. + matches the given matcher. The associated declaration is: - for type nodes, the declaration of the underlying type @@ -8099,17 +10847,25 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -For type nodes, hasDeclaration will generally match the declaration of the -sugared type. Given +Given class X {}; typedef X Y; Y y; -in varDecl(hasType(hasDeclaration(decl()))) the decl will match the -typedefDecl. A common use case is to match the underlying, desugared type. + +For type nodes, hasDeclaration will generally match the declaration of the +sugared type, i.e., the matcher +varDecl(hasType(qualType(hasDeclaration(decl().bind("d"))))), +matches Y y, with +the matcher decl() matching +typedef X Y;. +A common use case is to match the underlying, desugared type. This can be achieved by using the hasUnqualifiedDesugaredType matcher: - varDecl(hasType(hasUnqualifiedDesugaredType( - recordType(hasDeclaration(decl()))))) -In this matcher, the decl will match the CXXRecordDecl of class X. +varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl().bind("d")))))) +matches Y y. +In this matcher, the matcher decl() will match the +CXXRecordDecl +class X {};. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -8130,9 +10886,12 @@AST Traversal Matchers
template<typename T, typename U> class A {}; A<double, int> b; A<int, double> c; -varDecl(hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(0, - hasTypeLoc(loc(asString("double"))))))) - matches `A<double, int> b`, but not `A<int, double> c`. + +The matcher +varDecl(hasTypeLoc(elaboratedTypeLoc(hasNamedTypeLoc( +templateSpecializationTypeLoc(hasTemplateArgumentLoc(0, +hasTypeLoc(loc(asString("double"))))))))) +matches A<double, int> b, but not double> c}.
Matches if a node refers to a declaration through a specific
using shadow declaration.
-Examples:
+Given
namespace a { int f(); }
using a::f;
int x = f();
-declRefExpr(throughUsingDecl(anything()))
- matches f
+
+The matcher declRefExpr(throughUsingDecl(anything()))
+matches f
namespace a { class X{}; }
using a::X;
X x;
-typeLoc(loc(usingType(throughUsingDecl(anything()))))
- matches X
+
+The matcher typeLoc(loc(usingType(throughUsingDecl(anything()))))
+matches X
Usable as: Matcher<DeclRefExpr>, Matcher<UsingType>
Matches a DeclRefExpr that refers to a declaration that matches the
specified matcher.
-Example matches x in if(x)
- (matcher = declRefExpr(to(varDecl(hasName("x")))))
- bool x;
- if (x) {}
+Given
+ void foo() {
+ bool x;
+ if (x) {}
+ }
+
+The matcher declRefExpr(to(varDecl(hasName("x"))))
+matches x inside the condition of the if-stmt.
Matches the Decl of a DeclStmt which has a single declaration.
Given
- int a, b;
- int c;
-declStmt(hasSingleDecl(anything()))
- matches 'int c;' but not 'int a, b;'.
+ void foo() {
+ int a, b;
+ int c;
+ }
+The matcher declStmt(hasSingleDecl(anything()))
+matches int c;
+but does not match int a, b;
Matches if the type location of a node matches the inner matcher.
-Examples:
+Given
int x;
-declaratorDecl(hasTypeLoc(loc(asString("int"))))
- matches int x
+The matcher declaratorDecl(hasTypeLoc(loc(asString("int"))))
+matches int x.
+
+Given
+struct point { point(double, double); };
+point p = point(1.0, -1.0);
-auto x = int(3);
-cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int"))))
- matches int(3)
+The matcher
+cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point"))))
+matches point(1.0, -1.0).
+Given
struct Foo { Foo(int, int); };
-auto x = Foo(1, 2);
-cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo"))))
- matches Foo(1, 2)
+Foo x = Foo(1, 2);
+
+The matcher cxxTemporaryObjectExpr(hasTypeLoc(
+ loc(asString("Foo"))))
+matches Foo(1, 2).
Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>,
Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>,
@@ -8237,8 +11015,9 @@ AST Traversal Matchers
}
}
-cxxRcordDecl(hasDeclContext(namedDecl(hasName("M")))) matches the
-declaration of class D.
+
+The matcher cxxRecordDecl(hasDeclContext(namedDecl(hasName("M"))))
+ matches the declaration of D.
Matches the Nth binding of a DecompositionDecl.
-For example, in:
+Given
void foo()
{
int arr[3];
@@ -8283,10 +11066,10 @@ AST Traversal Matchers
f = 42;
}
-The matcher:
- decompositionDecl(hasBinding(0,
- bindingDecl(hasName("f").bind("fBinding"))))
-matches the decomposition decl with 'f' bound to "fBinding".
+
+The matcher decompositionDecl(hasBinding(0,
+ bindingDecl(hasName("f")).bind("fBinding")))
+matches auto &[f, s, t] = arr with 'f' bound to "fBinding".
Matches the condition expression of an if statement, for loop,
switch statement or conditional operator.
-Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
+Given
+void foo() {
if (true) {}
+}
+
+The matcher ifStmt(hasCondition(cxxBoolLiteral(equals(true))))
+if (true) {}
Matches ElaboratedTypes whose qualifier, a NestedNameSpecifier,
-matches InnerMatcher if the qualifier exists.
+ matches InnerMatcher if the qualifier exists.
Given
namespace N {
@@ -8351,8 +11143,11 @@ AST Traversal Matchers
}
N::M::D d;
-elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N"))))
-matches the type of the variable declaration of d.
+
+The matcher
+elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))
+ matches the type N::M::D of the variable declaration
+ of d.
Matches a node if the declaration associated with that node -matches the given matcher. + matches the given matcher. The associated declaration is: - for type nodes, the declaration of the underlying type @@ -8385,17 +11180,25 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -For type nodes, hasDeclaration will generally match the declaration of the -sugared type. Given +Given class X {}; typedef X Y; Y y; -in varDecl(hasType(hasDeclaration(decl()))) the decl will match the -typedefDecl. A common use case is to match the underlying, desugared type. + +For type nodes, hasDeclaration will generally match the declaration of the +sugared type, i.e., the matcher +varDecl(hasType(qualType(hasDeclaration(decl().bind("d"))))), +matches Y y, with +the matcher decl() matching +typedef X Y;. +A common use case is to match the underlying, desugared type. This can be achieved by using the hasUnqualifiedDesugaredType matcher: - varDecl(hasType(hasUnqualifiedDesugaredType( - recordType(hasDeclaration(decl()))))) -In this matcher, the decl will match the CXXRecordDecl of class X. +varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl().bind("d")))))) +matches Y y. +In this matcher, the matcher decl() will match the +CXXRecordDecl +class X {};. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -8412,25 +11215,37 @@AST Traversal Matchers
(Note: Clang's AST refers to other conversions as "casts" too, and calls actual casts "explicit" casts.) + + unsigned int a = (unsigned int)0; + +The matcher explicitCastExpr(hasDestinationType( +qualType(isUnsignedInteger()))) matches (unsigned int)0.
Matches if the type location of a node matches the inner matcher.
-Examples:
+Given
int x;
-declaratorDecl(hasTypeLoc(loc(asString("int"))))
- matches int x
+The matcher declaratorDecl(hasTypeLoc(loc(asString("int"))))
+matches int x.
+
+Given
+struct point { point(double, double); };
+point p = point(1.0, -1.0);
-auto x = int(3);
-cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int"))))
- matches int(3)
+The matcher
+cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point"))))
+matches point(1.0, -1.0).
+Given
struct Foo { Foo(int, int); };
-auto x = Foo(1, 2);
-cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo"))))
- matches Foo(1, 2)
+Foo x = Foo(1, 2);
+
+The matcher cxxTemporaryObjectExpr(hasTypeLoc(
+ loc(asString("Foo"))))
+matches Foo(1, 2).
Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>,
Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>,
@@ -8453,21 +11268,31 @@ AST Traversal Matchers
X, while varDecl(hasType(cxxRecordDecl(hasName("X")))) matches the
declaration of x.
-Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
- and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
- and friend class X (matcher = friendDecl(hasType("X"))
- and public virtual X (matcher = cxxBaseSpecifier(hasType(
- cxxRecordDecl(hasName("X"))))
class X {};
void y(X &x) { x; X z; }
class Y { friend class X; };
class Z : public virtual X {};
-Example matches class Derived
-(matcher = cxxRecordDecl(hasAnyBase(hasType(cxxRecordDecl(hasName("Base"))))))
+The matcher expr(hasType(cxxRecordDecl(hasName("X"))))
+matches x and z.
+The matcher varDecl(hasType(cxxRecordDecl(hasName("X"))))
+matches z.
+The matcher friendDecl(hasType(asString("class X")))
+matches friend class X.
+The matcher cxxRecordDecl(hasAnyBase(cxxBaseSpecifier(hasType(
+asString("X"))).bind("b"))) matches
+class Z : public virtual X {},
+with cxxBaseSpecifier(...)
+matching public virtual X.
+
+Given
class Base {};
class Derived : Base {};
+The matcher
+cxxRecordDecl(hasAnyBase(hasType(cxxRecordDecl(hasName("Base")))))
+matches class Derived : Base {}.
+
Usable as: Matcher<Expr>, Matcher<FriendDecl>, Matcher<ValueDecl>,
Matcher<CXXBaseSpecifier>
Matches if the expression's or declaration's type matches a type
matcher.
-Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
- and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
- and U (matcher = typedefDecl(hasType(asString("int")))
- and friend class X (matcher = friendDecl(hasType("X"))
- and public virtual X (matcher = cxxBaseSpecifier(hasType(
- asString("class X")))
+Exmaple
class X {};
void y(X &x) { x; X z; }
typedef int U;
class Y { friend class X; };
class Z : public virtual X {};
+
+The matcher expr(hasType(cxxRecordDecl(hasName("X"))))
+matches x and z.
+The matcher varDecl(hasType(cxxRecordDecl(hasName("X"))))
+matches z
+The matcher typedefDecl(hasType(asString("int")))
+matches typedef int U
+The matcher friendDecl(hasType(asString("class X")))
+matches friend class X
+The matcher cxxRecordDecl(hasAnyBase(cxxBaseSpecifier(hasType(
+asString("X"))).bind("b"))) matches class Z : public virtual X {},
+with cxxBaseSpecifier(...)
+matching public virtual X.
Matches the condition expression of an if statement, for loop,
switch statement or conditional operator.
-Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
+Given
+void foo() {
if (true) {}
+}
+
+The matcher ifStmt(hasCondition(cxxBoolLiteral(equals(true))))
+if (true) {}
Matches the increment statement of a for loop.
-Example:
- forStmt(hasIncrement(unaryOperator(hasOperatorName("++"))))
-matches '++x' in
- for (x; x < N; ++x) { }
+Given
+void foo(int N) {
+ for (int x = 0; x < N; ++x) { }
+}
+The matcher
+forStmt(hasIncrement(unaryOperator(hasOperatorName("++"))))
+matches for (int x = 0; x < N; ++x) { }
Matches the initialization statement of a for loop.
-Example:
- forStmt(hasLoopInit(declStmt()))
-matches 'int x = 0' in
+Given
+void foo(int N) {
for (int x = 0; x < N; ++x) { }
+}
+The matcher forStmt(hasLoopInit(declStmt()))
+matches for (int x = 0; x < N; ++x) { }
Matches if the expression's or declaration's type matches a type
matcher.
-Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
- and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
- and U (matcher = typedefDecl(hasType(asString("int")))
- and friend class X (matcher = friendDecl(hasType("X"))
- and public virtual X (matcher = cxxBaseSpecifier(hasType(
- asString("class X")))
+Exmaple
class X {};
void y(X &x) { x; X z; }
typedef int U;
class Y { friend class X; };
class Z : public virtual X {};
+
+The matcher expr(hasType(cxxRecordDecl(hasName("X"))))
+matches x and z.
+The matcher varDecl(hasType(cxxRecordDecl(hasName("X"))))
+matches z
+The matcher typedefDecl(hasType(asString("int")))
+matches typedef int U
+The matcher friendDecl(hasType(asString("class X")))
+matches friend class X
+The matcher cxxRecordDecl(hasAnyBase(cxxBaseSpecifier(hasType(
+asString("X"))).bind("b"))) matches class Z : public virtual X {},
+with cxxBaseSpecifier(...)
+matching public virtual X.
Matches the return type of a function declaration.
-Given:
+Given
class X { int f() { return 1; } };
-cxxMethodDecl(returns(asString("int")))
- matches int f() { return 1; }
+
+The matcher cxxMethodDecl(returns(asString("int")))
+ matches f
Matches the condition expression of an if statement, for loop,
switch statement or conditional operator.
-Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
+Given
+void foo() {
if (true) {}
+}
+
+The matcher ifStmt(hasCondition(cxxBoolLiteral(equals(true))))
+if (true) {}
Matches the condition variable statement in an if statement.
Given
+struct A {};
+A* GetAPointer();
+void foo() {
if (A* a = GetAPointer()) {}
-hasConditionVariableStatement(...)
- matches 'A* a = GetAPointer()'.
+}
+
+The matcher ifStmt(hasConditionVariableStatement(declStmt()))
+if (A* a = GetAPointer()) {}
Matches the else-statement of an if statement.
-Examples matches the if statement
- (matcher = ifStmt(hasElse(cxxBoolLiteral(equals(true)))))
+Given
+void foo() {
if (false) false; else true;
+}
+
+The matcher ifStmt(hasElse(cxxBoolLiteral(equals(true))))
+if (false) false; else true
Matches selection statements with initializer.
-Given:
+Given
+ struct vec { int* begin(); int* end(); };
+ int foobar();
+ vec& get_range();
void foo() {
if (int i = foobar(); i > 0) {}
switch (int i = foobar(); i) {}
@@ -9004,48 +11964,77 @@ AST Traversal Matchers
switch (foobar()) {}
for (auto& x : get_range()) {}
}
-ifStmt(hasInitStatement(anything()))
- matches the if statement in foo but not in bar.
-switchStmt(hasInitStatement(anything()))
- matches the switch statement in foo but not in bar.
-cxxForRangeStmt(hasInitStatement(anything()))
- matches the range for statement in foo but not in bar.
+
+The matcher ifStmt(hasInitStatement(anything()))
+ matches the if statement if (int i = foobar(); i > 0) {}
+ in foo but not if (foobar() > 0) {} in bar.
+The matcher switchStmt(hasInitStatement(anything()))
+ matches the switch statement switch (int i = foobar(); i) {}
+ in foo but not switch (foobar()) {} in bar.
+The matcher cxxForRangeStmt(hasInitStatement(anything()))
+ matches the range for statement
+ for (auto& a = get_range(); auto& x : a) {} in foo
+ but not for (auto& x : get_range()) {} in bar.
Matches the then-statement of an if statement.
-Examples matches the if statement
- (matcher = ifStmt(hasThen(cxxBoolLiteral(equals(true)))))
+Given
+void foo() {
if (false) true; else false;
+}
+
+The matcher ifStmt(hasThen(cxxBoolLiteral(equals(true))))
+if (false) true; else false
Matches implicit casts whose destination type matches a given matcher. + +Given + unsigned int a = 0; + +The matcher +implicitCastExpr(hasImplicitDestinationType( +qualType(isUnsignedInteger()))) matches 0.
Matches the n'th item of an initializer list expression.
-Example matches y.
- (matcher = initListExpr(hasInit(0, expr())))
- int x{y}.
+Given
+ int y = 42;
+ int x{y};
+
+The matcher initListExpr(hasInit(0, expr()))
+matches {y}.
Matches the syntactic form of init list expressions
(if expression have it).
+
+Given
+ int a[] = { 1, 2 };
+ struct B { int x, y; };
+ struct B b = { 5, 6 };
+
+
+The matcher
+initListExpr(hasSyntacticForm(expr().bind("syntactic")))
+matches { 1, 2 } and { 5, 6 }.
Matches a node if the declaration associated with that node -matches the given matcher. + matches the given matcher. The associated declaration is: - for type nodes, the declaration of the underlying type @@ -9055,17 +12044,25 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -For type nodes, hasDeclaration will generally match the declaration of the -sugared type. Given +Given class X {}; typedef X Y; Y y; -in varDecl(hasType(hasDeclaration(decl()))) the decl will match the -typedefDecl. A common use case is to match the underlying, desugared type. + +For type nodes, hasDeclaration will generally match the declaration of the +sugared type, i.e., the matcher +varDecl(hasType(qualType(hasDeclaration(decl().bind("d"))))), +matches Y y, with +the matcher decl() matching +typedef X Y;. +A common use case is to match the underlying, desugared type. This can be achieved by using the hasUnqualifiedDesugaredType matcher: - varDecl(hasType(hasUnqualifiedDesugaredType( - recordType(hasDeclaration(decl()))))) -In this matcher, the decl will match the CXXRecordDecl of class X. +varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl().bind("d")))))) +matches Y y. +In this matcher, the matcher decl() will match the +CXXRecordDecl +class X {};. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -9079,7 +12076,7 @@AST Traversal Matchers
Matcher<LabelStmt> hasDeclaration Matcher<Decl> InnerMatcher @@ -9133,13 +12142,18 @@ Matches a node if the declaration associated with that node -matches the given matcher. + matches the given matcher. The associated declaration is: - for type nodes, the declaration of the underlying type @@ -9089,17 +12086,25 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -For type nodes, hasDeclaration will generally match the declaration of the -sugared type. Given +Given class X {}; typedef X Y; Y y; -in varDecl(hasType(hasDeclaration(decl()))) the decl will match the -typedefDecl. A common use case is to match the underlying, desugared type. + +For type nodes, hasDeclaration will generally match the declaration of the +sugared type, i.e., the matcher +varDecl(hasType(qualType(hasDeclaration(decl().bind("d"))))), +matches Y y, with +the matcher decl() matching +typedef X Y;. +A common use case is to match the underlying, desugared type. This can be achieved by using the hasUnqualifiedDesugaredType matcher: - varDecl(hasType(hasUnqualifiedDesugaredType( - recordType(hasDeclaration(decl()))))) -In this matcher, the decl will match the CXXRecordDecl of class X. +varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl().bind("d")))))) +matches Y y. +In this matcher, the matcher decl() will match the +CXXRecordDecl +class X {};. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -9122,9 +12127,13 @@AST Traversal Matchers
auto f = [x](){}; auto g = [x = 1](){}; } -In the matcher -lambdaExpr(hasAnyCapture(lambdaCapture(capturesVar(hasName("x")))), -capturesVar(hasName("x")) matches `x` and `x = 1`. + +The matcher +lambdaExpr(hasAnyCapture( + lambdaCapture(capturesVar(hasName("x"))).bind("capture"))) +matches [x](){} and [x = 1](){}, with +lambdaCapture(capturesVar(hasName("x"))).bind("capture") +matching x and x = 1.AST Traversal Matchers
Given int main() { - int x, y; + int x; + int y; float z; auto f = [=]() { return x + y + z; }; } -lambdaExpr(forEachLambdaCapture( - lambdaCapture(capturesVar(varDecl(hasType(isInteger())))))) -will trigger two matches, binding for 'x' and 'y' respectively. + +The matcher lambdaExpr(forEachLambdaCapture( + lambdaCapture(capturesVar( + varDecl(hasType(isInteger())).bind("captured"))))) +matches [=]() { return x + y + z; } two times, +with varDecl(hasType(isInteger())) matching +int x and int y.
Matches a node if the declaration associated with that node -matches the given matcher. + matches the given matcher. The associated declaration is: - for type nodes, the declaration of the underlying type @@ -9169,17 +12184,25 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -For type nodes, hasDeclaration will generally match the declaration of the -sugared type. Given +Given class X {}; typedef X Y; Y y; -in varDecl(hasType(hasDeclaration(decl()))) the decl will match the -typedefDecl. A common use case is to match the underlying, desugared type. + +For type nodes, hasDeclaration will generally match the declaration of the +sugared type, i.e., the matcher +varDecl(hasType(qualType(hasDeclaration(decl().bind("d"))))), +matches Y y, with +the matcher decl() matching +typedef X Y;. +A common use case is to match the underlying, desugared type. This can be achieved by using the hasUnqualifiedDesugaredType matcher: - varDecl(hasType(hasUnqualifiedDesugaredType( - recordType(hasDeclaration(decl()))))) -In this matcher, the decl will match the CXXRecordDecl of class X. +varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl().bind("d")))))) +matches Y y. +In this matcher, the matcher decl() will match the +CXXRecordDecl +class X {};. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -9201,11 +12224,14 @@AST Traversal Matchers
int m; int f(X x) { x.m; return m; } }; + + +The matcher memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X"))))) - matches `x.m`, but not `m`; however, -memberExpr(hasObjectExpression(hasType(pointsTo( - cxxRecordDecl(hasName("X")))))) - matches `m` (aka. `this->m`), but not `x.m`. +matches x.m, but not m; however, +The matcher memberExpr(hasObjectExpression(hasType(pointsTo( +cxxRecordDecl(hasName("X")))))) +matches m (aka. this->m), but not x.m.
Matches NestedNameSpecifierLocs for which the given inner -NestedNameSpecifier-matcher matches. ++ Matcher<NestedNameSpecifierLoc> loc Matcher<NestedNameSpecifier> InnerMatcher @@ -9276,9 +12323,10 @@ Matches NestedNameSpecifierLocs for which the given inner +NestedNameSpecifier-matcher matches. + +Given + namespace ns { + struct A { static void f(); }; + void A::f() {} + void g() { A::f(); } + } + ns::A a; + + +The matcher nestedNameSpecifierLoc(loc(specifiesType( +hasDeclaration(namedDecl(hasName("A")))))) matches A:: +twice.AST Traversal Matchers
Given struct A { struct B { struct C {}; }; }; A::B::C c; -nestedNameSpecifierLoc(specifiesTypeLoc(loc(type( + +The matcher nestedNameSpecifierLoc(specifiesTypeLoc(loc(qualType( hasDeclaration(cxxRecordDecl(hasName("A"))))))) - matches "A::" +matches A::
Matches any clause in an OpenMP directive.
Given
-
+ void foo() {
#pragma omp parallel
+ ;
#pragma omp parallel default(none)
+ ;
+ }
-``ompExecutableDirective(hasAnyClause(anything()))`` matches
-``omp parallel default(none)``.
+
+The matcher ompExecutableDirective(hasAnyClause(anything()))
+matches #pragma omp parallel default(none).
Similar to isDerivedFrom(), but also matches classes that directly
match Base.
+
+Given
+ class X {};
+ class Y : public X {}; // directly derived
+ class Z : public Y {}; // indirectly derived
+ typedef X A;
+ typedef A B;
+ class C : public B {}; // derived from a typedef of X
+
+The matcher
+cxxRecordDecl(isSameOrDerivedFrom(cxxRecordDecl(hasName("X"))),
+isDefinition())
+matches class X {}, class Y : public X {},
+class Z : public Y {} and class C : public B {}.
Matches the n'th argument of a call expression or a constructor
call expression.
-Example matches y in x(y)
- (matcher = callExpr(hasArgument(0, declRefExpr())))
+Given
void x(int) { int y; x(y); }
+The matcher callExpr(hasArgument(0, declRefExpr().bind("arg")))
+matches x(y),
+with declRefExpr() matching y.
Matches if the Objective-C message is sent to an instance,
and the inner matcher matches on that instance.
-For example the method call in
+Given
NSString *x = @"hello";
[x containsString:@"h"];
-is matched by
+
+The matcher
objcMessageExpr(hasReceiver(declRefExpr(to(varDecl(hasName("x"))))))
+matches [x containsString:@"h"];
Matches on the receiver of an ObjectiveC Message expression.
-Example
-matcher = objCMessageExpr(hasReceiverType(asString("UIWebView *")));
-matches the [webView ...] message invocation.
NSString *webViewJavaScript = ...
UIWebView *webView = ...
[webView stringByEvaluatingJavaScriptFromString:webViewJavascript];
+
+The matcher objCMessageExpr(hasReceiverType(asString("UIWebView
+*"))) matches
+[webViewstringByEvaluatingJavaScriptFromString:webViewJavascript];
Matches if the type location of a node matches the inner matcher.
-Examples:
+Given
int x;
-declaratorDecl(hasTypeLoc(loc(asString("int"))))
- matches int x
+The matcher declaratorDecl(hasTypeLoc(loc(asString("int"))))
+matches int x.
+
+Given
+struct point { point(double, double); };
+point p = point(1.0, -1.0);
-auto x = int(3);
-cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int"))))
- matches int(3)
+The matcher
+cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point"))))
+matches point(1.0, -1.0).
+Given
struct Foo { Foo(int, int); };
-auto x = Foo(1, 2);
-cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo"))))
- matches Foo(1, 2)
+Foo x = Foo(1, 2);
+
+The matcher cxxTemporaryObjectExpr(hasTypeLoc(
+ loc(asString("Foo"))))
+matches Foo(1, 2).
Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>,
Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>,
@@ -9559,14 +12673,23 @@ AST Traversal Matchers
Matches if the cast's source expression
or opaque value's source expression matches the given matcher.
-Example 1: matches "a string"
-(matcher = castExpr(hasSourceExpression(cxxConstructExpr())))
-class URL { URL(string); };
-URL url = "a string";
+Given
+ struct URL { URL(const char*); };
+ URL url = "a string";
+
+The matcher castExpr(hasSourceExpression(cxxConstructExpr()))
+matches "a string".
-Example 2: matches 'b' (matcher =
-opaqueValueExpr(hasSourceExpression(implicitCastExpr(declRefExpr())))
-int a = b ?: 1;
+Given
+void foo(bool b) {
+ int a = b ?: 1;
+}
+
+The matcher
+opaqueValueExpr(hasSourceExpression(
+ implicitCastExpr(has(
+ implicitCastExpr(has(declRefExpr()))))))
+matches b twice, for the conditiona and the true expression.
@@ -9581,9 +12704,11 @@ AST Traversal Matchers
foo(t);
bar(t);
}
-unresolvedLookupExpr(hasAnyDeclaration(
+
+The matcher unresolvedLookupExpr(hasAnyDeclaration(
functionTemplateDecl(hasName("foo"))))
- matches foo in foo(t); but not bar in bar(t);
+matches foo in foo(t);
+but does not match bar in bar(t);
Matches QualTypes whose canonical type matches InnerMatcher. -Given: +Given typedef int &int_ref; int a; int_ref b = a; -varDecl(hasType(qualType(referenceType()))))) will not match the -declaration of b but varDecl(hasType(qualType(hasCanonicalType(referenceType())))))) does. +The matcher varDecl(hasType(qualType(referenceType()))) +does not match int_ref b = a, +but the matcher +varDecl(hasType(qualType(hasCanonicalType(referenceType())))) +does match int_ref b = a.
Matches a node if the declaration associated with that node -matches the given matcher. + matches the given matcher. The associated declaration is: - for type nodes, the declaration of the underlying type @@ -9653,17 +12787,25 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -For type nodes, hasDeclaration will generally match the declaration of the -sugared type. Given +Given class X {}; typedef X Y; Y y; -in varDecl(hasType(hasDeclaration(decl()))) the decl will match the -typedefDecl. A common use case is to match the underlying, desugared type. + +For type nodes, hasDeclaration will generally match the declaration of the +sugared type, i.e., the matcher +varDecl(hasType(qualType(hasDeclaration(decl().bind("d"))))), +matches Y y, with +the matcher decl() matching +typedef X Y;. +A common use case is to match the underlying, desugared type. This can be achieved by using the hasUnqualifiedDesugaredType matcher: - varDecl(hasType(hasUnqualifiedDesugaredType( - recordType(hasDeclaration(decl()))))) -In this matcher, the decl will match the CXXRecordDecl of class X. +varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl().bind("d")))))) +matches Y y. +In this matcher, the matcher decl() will match the +CXXRecordDecl +class X {};. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -9681,30 +12823,56 @@AST Traversal Matchers
Given void (*fp)(void); The matcher - varDecl(hasType(pointerType(pointee(ignoringParens(functionType()))))) -would match the declaration for fp. +varDecl(hasType(pointerType(pointee(ignoringParens(functionType()))))) +matches fp.
Overloaded to match the pointee type's declaration. +Matches if the matched type is a pointer type and the pointee type + matches the specified matcher. +Overloaded to match the pointee type's declaration. + +Given + class Y { public: void x(); }; + void z() { Y *y; y->x(); } + +The matcher cxxMemberCallExpr(on(hasType(pointsTo( + cxxRecordDecl(hasName("Y")))))) +matches y->x()Matcher<QualType> pointsTo Matcher<QualType> InnerMatcher Matches if the matched type is a pointer type and the pointee type -matches the specified matcher. + matches the specified matcher. -Example matches y->x() - (matcher = cxxMemberCallExpr(on(hasType(pointsTo - cxxRecordDecl(hasName("Y"))))))) +Given class Y { public: void x(); }; void z() { Y *y; y->x(); } + +The matcher cxxMemberCallExpr(on(hasType(pointsTo( + qualType())))) +matches y->x()- Matcher<QualType> references Matcher<Decl> InnerMatcher + int* const x = nullptr; + const int y = 0; + + +The matcher qualifiedTypeLoc(hasUnqualifiedLoc(pointerTypeLoc())) +matches the type int* of the variable declaration but +not Overloaded to match the referenced type's declaration. +@@ -9712,14 +12880,17 @@ Matches if the matched type is a reference type and the referenced +type matches the specified matcher. +Overloaded to match the referenced type's declaration. + +Given + class X { + void a(X b) { + X &x = b; + const X &y = b; + } + }; + +The matcher +varDecl(hasType(references(cxxRecordDecl(hasName("X"))))) matches +X &x = b and const X &y = b.AST Traversal Matchers
@@ -9728,16 +12899,18 @@ Matches if the matched type is a reference type and the referenced type matches the specified matcher. -Example matches X &x and const X &y - (matcher = varDecl(hasType(references(cxxRecordDecl(hasName("X")))))) +Given class X { void a(X b) { X &x = b; const X &y = b; } }; + +The matcher +varDecl(hasType(references(qualType()))) matches +X &x = b and const X &y = b.AST Traversal Matchers
`InnerMatcher`. Given - int* const x; - const int y; -qualifiedTypeLoc(hasUnqualifiedLoc(pointerTypeLoc())) - matches the `TypeLoc` of the variable declaration of `x`, but not `y`. -
Matches a node if the declaration associated with that node -matches the given matcher. + matches the given matcher. The associated declaration is: - for type nodes, the declaration of the underlying type @@ -9747,17 +12920,25 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -For type nodes, hasDeclaration will generally match the declaration of the -sugared type. Given +Given class X {}; typedef X Y; Y y; -in varDecl(hasType(hasDeclaration(decl()))) the decl will match the -typedefDecl. A common use case is to match the underlying, desugared type. + +For type nodes, hasDeclaration will generally match the declaration of the +sugared type, i.e., the matcher +varDecl(hasType(qualType(hasDeclaration(decl().bind("d"))))), +matches Y y, with +the matcher decl() matching +typedef X Y;. +A common use case is to match the underlying, desugared type. This can be achieved by using the hasUnqualifiedDesugaredType matcher: - varDecl(hasType(hasUnqualifiedDesugaredType( - recordType(hasDeclaration(decl()))))) -In this matcher, the decl will match the CXXRecordDecl of class X. +varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl().bind("d")))))) +matches Y y. +In this matcher, the matcher decl() will match the +CXXRecordDecl +class X {};. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -9776,8 +12957,10 @@AST Traversal Matchers
Given int x = 3; int& xx = x; -referenceTypeLoc(hasReferentLoc(loc(asString("int")))) - matches `int&`. + + +The matcher referenceTypeLoc(hasReferentLoc(loc(asString("int")))) + matches int&.
Matches the return value expression of a return statement
Given
- return a + b;
-hasReturnValue(binaryOperator())
- matches 'return a + b'
-with binaryOperator()
- matching 'a + b'
+ int foo(int a, int b) {
+ return a + b;
+ }
+The matcher
+returnStmt(hasReturnValue(binaryOperator().bind("op"))) matches
+return a + b, with binaryOperator() matching
+a + b.
Same as unaryExprOrTypeTraitExpr, but only matching alignof. + +Given + int align = alignof(int); + + +The matcher alignOfExpr(expr()) +matches alignof(int).
Matches declaration of the function, method, or block the statement
belongs to.
-Given:
-F& operator=(const F& o) {
- std::copy_if(o.begin(), o.end(), begin(), [](V v) { return v > 0; });
- return *this;
-}
-returnStmt(forCallable(functionDecl(hasName("operator="))))
- matches 'return *this'
- but does not match 'return v > 0'
+Given
+struct F {
+ F& operator=(const F& other) {
+ []() { return 42 == 42; };
+ return *this;
+ }
+};
-Given:
--(void) foo {
+The matcher returnStmt(forFunction(hasName("operator=")))
+matches return *this
+but does not match return 42 == 42.
+
+Given
+void foo {
int x = 1;
dispatch_sync(queue, ^{ int y = 2; });
}
-declStmt(forCallable(objcMethodDecl()))
- matches 'int x = 1'
- but does not match 'int y = 2'.
-whereas declStmt(forCallable(blockDecl()))
- matches 'int y = 2'
- but does not match 'int x = 1'.
+
+The matcher declStmt(forCallable(objcMethodDecl()))
+matches int x = 1
+but does not match int y = 2.
+The matcher declStmt(forCallable(blockDecl()))
+matches int y = 2
+but does not match int x = 1.
Same as unaryExprOrTypeTraitExpr, but only matching
sizeof.
+
+Given
+ struct S { double x; double y; };
+ int size = sizeof(struct S);
+
+The matcher sizeOfExpr(expr())
+matches sizeof(struct S).
Matches the condition expression of an if statement, for loop,
switch statement or conditional operator.
-Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
+Given
+void foo() {
if (true) {}
+}
+
+The matcher ifStmt(hasCondition(cxxBoolLiteral(equals(true))))
+if (true) {}
Matches selection statements with initializer.
-Given:
+Given
+ struct vec { int* begin(); int* end(); };
+ int foobar();
+ vec& get_range();
void foo() {
if (int i = foobar(); i > 0) {}
switch (int i = foobar(); i) {}
@@ -9930,18 +13159,23 @@ AST Traversal Matchers
switch (foobar()) {}
for (auto& x : get_range()) {}
}
-ifStmt(hasInitStatement(anything()))
- matches the if statement in foo but not in bar.
-switchStmt(hasInitStatement(anything()))
- matches the switch statement in foo but not in bar.
-cxxForRangeStmt(hasInitStatement(anything()))
- matches the range for statement in foo but not in bar.
+
+The matcher ifStmt(hasInitStatement(anything()))
+ matches the if statement if (int i = foobar(); i > 0) {}
+ in foo but not if (foobar() > 0) {} in bar.
+The matcher switchStmt(hasInitStatement(anything()))
+ matches the switch statement switch (int i = foobar(); i) {}
+ in foo but not switch (foobar()) {} in bar.
+The matcher cxxForRangeStmt(hasInitStatement(anything()))
+ matches the range for statement
+ for (auto& a = get_range(); auto& x : a) {} in foo
+ but not for (auto& x : get_range()) {} in bar.
Matches a node if the declaration associated with that node -matches the given matcher. + matches the given matcher. The associated declaration is: - for type nodes, the declaration of the underlying type @@ -9951,17 +13185,25 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -For type nodes, hasDeclaration will generally match the declaration of the -sugared type. Given +Given class X {}; typedef X Y; Y y; -in varDecl(hasType(hasDeclaration(decl()))) the decl will match the -typedefDecl. A common use case is to match the underlying, desugared type. + +For type nodes, hasDeclaration will generally match the declaration of the +sugared type, i.e., the matcher +varDecl(hasType(qualType(hasDeclaration(decl().bind("d"))))), +matches Y y, with +the matcher decl() matching +typedef X Y;. +A common use case is to match the underlying, desugared type. This can be achieved by using the hasUnqualifiedDesugaredType matcher: - varDecl(hasType(hasUnqualifiedDesugaredType( - recordType(hasDeclaration(decl()))))) -In this matcher, the decl will match the CXXRecordDecl of class X. +varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl().bind("d")))))) +matches Y y. +In this matcher, the matcher decl() will match the +CXXRecordDecl +class X {};. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -9976,19 +13218,26 @@AST Traversal Matchers
Matcher<TemplateArgumentLoc> hasTypeLoc Matcher<TypeLoc> Inner @@ -10023,10 +13275,13 @@ Matches if the type location of a node matches the inner matcher. -Examples: +Given int x; -declaratorDecl(hasTypeLoc(loc(asString("int")))) - matches int x +The matcher declaratorDecl(hasTypeLoc(loc(asString("int")))) +matches int x. + +Given +struct point { point(double, double); }; +point p = point(1.0, -1.0); -auto x = int(3); -cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) - matches int(3) +The matcher +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point")))) +matches point(1.0, -1.0). +Given struct Foo { Foo(int, int); }; -auto x = Foo(1, 2); -cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) - matches Foo(1, 2) +Foo x = Foo(1, 2); + +The matcher cxxTemporaryObjectExpr(hasTypeLoc( + loc(asString("Foo")))) +matches Foo(1, 2). Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, @@ -10008,10 +13257,13 @@AST Traversal Matchers
struct B { int next; }; template<int(B::*next_ptr)> struct A {}; A<&B::next> a; + +The matcher templateSpecializationType(hasAnyTemplateArgument( - isExpr(hasDescendant(declRefExpr(to(fieldDecl(hasName("next")))))))) - matches the specialization A<&B::next> with fieldDecl(...) matching - B::next + isExpr(hasDescendant(declRefExpr(to(fieldDecl(hasName("next")).bind("next"))))))) +matches the specialization A<&struct B::next> +with fieldDecl(hasName("next")) matching +B::next.AST Traversal Matchers
struct B { int next; }; template<int(B::*next_ptr)> struct A {}; A<&B::next> a; + +The matcher classTemplateSpecializationDecl(hasAnyTemplateArgument( - refersToDeclaration(fieldDecl(hasName("next"))))) - matches the specialization A<&B::next> with fieldDecl(...) matching - B::next + refersToDeclaration(fieldDecl(hasName("next")).bind("next")))) +matches the specialization struct A<&B::next> +with fieldDecl(hasName("next")) matching +B::next.
Matches a node if the declaration associated with that node -matches the given matcher. + matches the given matcher. The associated declaration is: - for type nodes, the declaration of the underlying type @@ -10158,17 +13438,25 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -For type nodes, hasDeclaration will generally match the declaration of the -sugared type. Given +Given class X {}; typedef X Y; Y y; -in varDecl(hasType(hasDeclaration(decl()))) the decl will match the -typedefDecl. A common use case is to match the underlying, desugared type. + +For type nodes, hasDeclaration will generally match the declaration of the +sugared type, i.e., the matcher +varDecl(hasType(qualType(hasDeclaration(decl().bind("d"))))), +matches Y y, with +the matcher decl() matching +typedef X Y;. +A common use case is to match the underlying, desugared type. This can be achieved by using the hasUnqualifiedDesugaredType matcher: - varDecl(hasType(hasUnqualifiedDesugaredType( - recordType(hasDeclaration(decl()))))) -In this matcher, the decl will match the CXXRecordDecl of class X. +varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl().bind("d")))))) +matches Y y. +In this matcher, the matcher decl() will match the +CXXRecordDecl +class X {};. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -10187,23 +13475,26 @@AST Traversal Matchers
Given template<typename T, typename U> class A {}; - A<bool, int> b; - A<int, bool> c; + A<double, int> b; + A<int, double> c; template<typename T> void f() {} void func() { f<int>(); }; + +The matcher classTemplateSpecializationDecl(hasTemplateArgument( 1, refersToType(asString("int")))) - matches the specialization A<bool, int> +matches the specialization class A<double, int>. -functionDecl(hasTemplateArgument(0, refersToType(asString("int")))) - matches the specialization f<int> +The matcher functionDecl(hasTemplateArgument(0, + refersToType(asString("int")))) +matches the specialization of f.
Matches a node if the declaration associated with that node -matches the given matcher. + matches the given matcher. The associated declaration is: - for type nodes, the declaration of the underlying type @@ -10213,17 +13504,25 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -For type nodes, hasDeclaration will generally match the declaration of the -sugared type. Given +Given class X {}; typedef X Y; Y y; -in varDecl(hasType(hasDeclaration(decl()))) the decl will match the -typedefDecl. A common use case is to match the underlying, desugared type. + +For type nodes, hasDeclaration will generally match the declaration of the +sugared type, i.e., the matcher +varDecl(hasType(qualType(hasDeclaration(decl().bind("d"))))), +matches Y y, with +the matcher decl() matching +typedef X Y;. +A common use case is to match the underlying, desugared type. This can be achieved by using the hasUnqualifiedDesugaredType matcher: - varDecl(hasType(hasUnqualifiedDesugaredType( - recordType(hasDeclaration(decl()))))) -In this matcher, the decl will match the CXXRecordDecl of class X. +varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl().bind("d")))))) +matches Y y. +In this matcher, the matcher decl() will match the +CXXRecordDecl +class X {};. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -10238,25 +13537,37 @@AST Traversal Matchers
Matcher<TypeLoc> loc Matcher<QualType> InnerMatcher Matches TypeLocs for which the given inner QualType-matcher matches. + + int a = 10; + +The matcher typeLoc(loc(qualType(isInteger()))) +matches the int of a .Matcher<TypedefNameDecl> hasTypeLoc Matcher<TypeLoc> Inner Matches if the type location of a node matches the inner matcher. -Examples: +Given int x; -declaratorDecl(hasTypeLoc(loc(asString("int")))) - matches int x +The matcher declaratorDecl(hasTypeLoc(loc(asString("int")))) +matches int x. + +Given +struct point { point(double, double); }; +point p = point(1.0, -1.0); -auto x = int(3); -cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) - matches int(3) +The matcher +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point")))) +matches point(1.0, -1.0). +Given struct Foo { Foo(int, int); }; -auto x = Foo(1, 2); -cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) - matches Foo(1, 2) +Foo x = Foo(1, 2); + +The matcher cxxTemporaryObjectExpr(hasTypeLoc( + loc(asString("Foo")))) +matches Foo(1, 2). Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, @@ -10273,23 +13584,31 @@AST Traversal Matchers
Matches if the expression's or declaration's type matches a type matcher. -Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X"))))) - and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X"))))) - and U (matcher = typedefDecl(hasType(asString("int"))) - and friend class X (matcher = friendDecl(hasType("X")) - and public virtual X (matcher = cxxBaseSpecifier(hasType( - asString("class X"))) +Exmaple class X {}; void y(X &x) { x; X z; } typedef int U; class Y { friend class X; }; class Z : public virtual X {}; + +The matcher expr(hasType(cxxRecordDecl(hasName("X")))) +matches x and z. +The matcher varDecl(hasType(cxxRecordDecl(hasName("X")))) +matches z +The matcher typedefDecl(hasType(asString("int"))) +matches typedef int U +The matcher friendDecl(hasType(asString("class X"))) +matches friend class X +The matcher cxxRecordDecl(hasAnyBase(cxxBaseSpecifier(hasType( +asString("X"))).bind("b"))) matches class Z : public virtual X {}, +with cxxBaseSpecifier(...) +matching public virtual X.Matcher<TypedefType> hasDeclaration Matcher<Decl> InnerMatcher @@ -10338,17 +13668,23 @@ Matches a node if the declaration associated with that node -matches the given matcher. + matches the given matcher. The associated declaration is: - for type nodes, the declaration of the underlying type @@ -10299,17 +13618,25 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -For type nodes, hasDeclaration will generally match the declaration of the -sugared type. Given +Given class X {}; typedef X Y; Y y; -in varDecl(hasType(hasDeclaration(decl()))) the decl will match the -typedefDecl. A common use case is to match the underlying, desugared type. + +For type nodes, hasDeclaration will generally match the declaration of the +sugared type, i.e., the matcher +varDecl(hasType(qualType(hasDeclaration(decl().bind("d"))))), +matches Y y, with +the matcher decl() matching +typedef X Y;. +A common use case is to match the underlying, desugared type. This can be achieved by using the hasUnqualifiedDesugaredType matcher: - varDecl(hasType(hasUnqualifiedDesugaredType( - recordType(hasDeclaration(decl()))))) -In this matcher, the decl will match the CXXRecordDecl of class X. +varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl().bind("d")))))) +matches Y y. +In this matcher, the matcher decl() will match the +CXXRecordDecl +class X {};. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -10328,8 +13655,11 @@AST Traversal Matchers
For example, in: class A {}; using B = A; -The matcher type(hasUnqualifiedDesugaredType(recordType())) matches -both B and A. + B b; + +The matcher +varDecl(hasType(hasUnqualifiedDesugaredType(recordType()))) +matches B b.AST Traversal Matchers
Given int a, c; float b; int s = sizeof(a) + sizeof(b) + alignof(c); -unaryExprOrTypeTraitExpr(hasArgumentOfType(asString("int")) - matches sizeof(a) and alignof(c) + +The matcher +unaryExprOrTypeTraitExpr(hasArgumentOfType(asString("int"))) +matches sizeof(a) and alignof(c)Matcher<UnaryOperator> hasUnaryOperand Matcher<Expr> InnerMatcher @@ -10362,17 +13698,20 @@ Matches if the operand of a unary operator matches. -Example matches true (matcher = hasUnaryOperand( - cxxBoolLiteral(equals(true)))) - !true +void foo() { + !true; +} + +The matcher +unaryOperator(hasUnaryOperand(cxxBoolLiteral(equals(true)))) +matches !true.AST Traversal Matchers
int m; int f(X x) { x.m; return m; } }; + + +The matcher memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X"))))) - matches `x.m`, but not `m`; however, -memberExpr(hasObjectExpression(hasType(pointsTo( - cxxRecordDecl(hasName("X")))))) - matches `m` (aka. `this->m`), but not `x.m`. +matches x.m, but not m; however, +The matcher memberExpr(hasObjectExpression(hasType(pointsTo( +cxxRecordDecl(hasName("X")))))) +matches m (aka. this->m), but not x.m.
Matches a node if the declaration associated with that node -matches the given matcher. + matches the given matcher. The associated declaration is: - for type nodes, the declaration of the underlying type @@ -10382,17 +13721,25 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -For type nodes, hasDeclaration will generally match the declaration of the -sugared type. Given +Given class X {}; typedef X Y; Y y; -in varDecl(hasType(hasDeclaration(decl()))) the decl will match the -typedefDecl. A common use case is to match the underlying, desugared type. + +For type nodes, hasDeclaration will generally match the declaration of the +sugared type, i.e., the matcher +varDecl(hasType(qualType(hasDeclaration(decl().bind("d"))))), +matches Y y, with +the matcher decl() matching +typedef X Y;. +A common use case is to match the underlying, desugared type. This can be achieved by using the hasUnqualifiedDesugaredType matcher: - varDecl(hasType(hasUnqualifiedDesugaredType( - recordType(hasDeclaration(decl()))))) -In this matcher, the decl will match the CXXRecordDecl of class X. +varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl().bind("d")))))) +matches Y y. +In this matcher, the matcher decl() will match the +CXXRecordDecl +class X {};. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -10412,8 +13759,12 @@AST Traversal Matchers
namespace X { int a; void b(); } using X::a; using X::b; + +The matcher usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(functionDecl()))) - matches using X::b but not using X::a
Matches if a node refers to a declaration through a specific
using shadow declaration.
-Examples:
+Given
namespace a { int f(); }
using a::f;
int x = f();
-declRefExpr(throughUsingDecl(anything()))
- matches f
+
+The matcher declRefExpr(throughUsingDecl(anything()))
+matches f
namespace a { class X{}; }
using a::X;
X x;
-typeLoc(loc(usingType(throughUsingDecl(anything()))))
- matches X
+
+The matcher typeLoc(loc(usingType(throughUsingDecl(anything()))))
+matches X
Usable as: Matcher<DeclRefExpr>, Matcher<UsingType>
Matches if the expression's or declaration's type matches a type
matcher.
-Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
- and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
- and U (matcher = typedefDecl(hasType(asString("int")))
- and friend class X (matcher = friendDecl(hasType("X"))
- and public virtual X (matcher = cxxBaseSpecifier(hasType(
- asString("class X")))
+Exmaple
class X {};
void y(X &x) { x; X z; }
typedef int U;
class Y { friend class X; };
class Z : public virtual X {};
+
+The matcher expr(hasType(cxxRecordDecl(hasName("X"))))
+matches x and z.
+The matcher varDecl(hasType(cxxRecordDecl(hasName("X"))))
+matches z
+The matcher typedefDecl(hasType(asString("int")))
+matches typedef int U
+The matcher friendDecl(hasType(asString("class X")))
+matches friend class X
+The matcher cxxRecordDecl(hasAnyBase(cxxBaseSpecifier(hasType(
+asString("X"))).bind("b"))) matches class Z : public virtual X {},
+with cxxBaseSpecifier(...)
+matching public virtual X.
Matches a variable declaration that has an initializer expression
that matches the given matcher.
-Example matches x (matcher = varDecl(hasInitializer(callExpr())))
- bool y() { return true; }
- bool x = y();
+Given
+ int y() { return 0; }
+ void foo() {
+ int x = y();
+ }
+The matcher varDecl(hasInitializer(callExpr()))
+matches x
Matches the condition expression of an if statement, for loop,
switch statement or conditional operator.
-Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
+Given
+void foo() {
if (true) {}
+}
+
+The matcher ifStmt(hasCondition(cxxBoolLiteral(equals(true))))
+if (true) {}
\endheader
+// code-block ::= \code \endcode
+// testcase ::= code-block [compile_args] cases
+//
+// Language Standard Versions:
+//
+// The 'std' tag and '\compile_args' support specifying a specific language
+// version, a whole language and all of its versions, and thresholds (implies
+// ranges). Multiple arguments are passed with a ',' separator. For a language
+// and version to execute a tested matcher, it has to match the specified
+// '\compile_args' for the code, and the 'std' tag for the matcher. Predicates
+// for the 'std' compiler flag are used with disjunction between languages
+// (e.g. 'c || c++') and conjunction for all predicates specific to each
+// language (e.g. 'c++11-or-later && c++23-or-earlier').
+//
+// Examples:
+// - `c` all available versions of C
+// - `c++11` only C++11
+// - `c++11-or-later` C++11 or later
+// - `c++11-or-earlier` C++11 or earlier
+// - `c++11-or-later,c++23-or-earlier,c` all of C and C++ between 11 and
+// 23 (inclusive)
+// - `c++11-23,c` same as above
+//
+// Tags
+//
+// `type`:
+// **Match types** are used to select where the string that is used to check if
+// a node matches comes from. Available: `code`, `name`, `typestr`,
+// `typeofstr`. The default is `code`.
+//
+// - `code`: Forwards to `tooling::fixit::getText(...)` and should be the
+// preferred way to show what matches.
+// - `name`: Casts the match to a `NamedDecl` and returns the result of
+// `getNameAsString`. Useful when the matched AST node is not easy to spell
+// out (`code` type), e.g., namespaces or classes with many members.
+// - `typestr`: Returns the result of `QualType::getAsString` for the type
+// derived from `Type` (otherwise, if it is derived from `Decl`, recurses with
+// `Node->getTypeForDecl()`)
+//
+// **Matcher types** are used to mark matchers as sub-matcher with 'sub' or as
+// deactivated using 'none'. Testing sub-matcher is not implemented.
+//
+// `count`:
+// Specifying a 'count=n' on a match will result in a test that requires that
+// the specified match will be matched n times. Default is 1.
+//
+// `std`:
+// A match allows specifying if it matches only in specific language versions.
+// This may be needed when the AST differs between language versions.
+//
+// `sub`:
+// The `sub` tag on a `\match` will indicate that the match is for a node of a
+// bound sub-matcher. E.g., `\matcher{expr(expr().bind("inner"))}` has a
+// sub-matcher that binds to `inner`, which is the value for the `sub` tag of
+// the expected match for the sub-matcher `\match{sub=inner$...}`. Currently,
+// sub-matchers are not tested in any way.
+//
+//
+// What if ...?
+//
+// ... I want to add a matcher?
+//
+// Add a doxygen comment to the matcher with a code example, corresponding
+// matchers and matches, that shows what the matcher is supposed to do. Specify
+// the compile arguments/supported languages if required, and run `ninja
+// check-clang-unit` to test the documentation.
+//
+// ... the example I wrote is wrong?
+//
+// The test-failure output of the generated test file will provide information
+// about
+// - where the generated test file is located
+// - which line in `ASTMatcher.h` the example is from
+// - which matches were: found, not-(yet)-found, expected
+// - in case of an unexpected match: what the node looks like using the
+// different `type`s
+// - the language version and if the test ran with a windows `-target` flag
+// (also in failure summary)
+//
+// ... I don't adhere to the required order of the syntax?
+//
+// The script will diagnose any found issues, such as `matcher is missing an
+// example` with a `file:line:` prefix, which should provide enough information
+// about the issue.
+//
+// ... the script diagnoses a false-positive issue with a doxygen comment?
+//
+// It hopefully shouldn't, but if you, e.g., added some non-matcher code and
+// documented it with doxygen, then the script will consider that as a matcher
+// documentation. As a result, the script will print that it detected a
+// mismatch between the actual and the expected number of failures. If the
+// diagnostic truly is a false-positive, change the
+// `expected_failure_statistics` at the top of the
+// `generate_ast_matcher_doc_tests.py` file.
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERS_H
@@ -160,13 +312,13 @@ using AttrMatcher = internal::Matcher;
/// additional constraint. This will often be used with an explicit conversion
/// to an \c internal::Matcher<> type such as \c TypeMatcher.
///
-/// Example: \c DeclarationMatcher(anything()) matches all declarations, e.g.,
+/// Given
/// \code
-/// "int* p" and "void f()" in
/// int* p;
/// void f();
/// \endcode
-///
+/// The matcher \matcher{decl(anything())}
+/// matches \match{int* p} and \match{void f()}.
/// Usable as: Any Matcher
inline internal::TrueMatcher anything() { return internal::TrueMatcher(); }
@@ -175,12 +327,13 @@ inline internal::TrueMatcher anything() { return internal::TrueMatcher(); }
/// Given
/// \code
/// int X;
-/// namespace NS {
-/// int Y;
-/// } // namespace NS
+/// namespace NS { int Y; }
/// \endcode
-/// decl(hasDeclContext(translationUnitDecl()))
-/// matches "int X", but not "int Y".
+/// \compile_args{-std=c++}
+/// The matcher \matcher{namedDecl(hasDeclContext(translationUnitDecl()))}
+/// matches \match{int X} and \match{namespace NS { int Y; }},
+/// but does not match \nomatch{int Y} because its decl-context is the
+/// namespace \c NS .
extern const internal::VariadicDynCastAllOfMatcher
translationUnitDecl;
@@ -191,8 +344,10 @@ extern const internal::VariadicDynCastAllOfMatcher
/// typedef int X;
/// using Y = int;
/// \endcode
-/// typedefDecl()
-/// matches "typedef int X", but not "using Y = int"
+/// \compile_args{-std=c++}
+/// The matcher \matcher{typedefDecl()}
+/// matches \match{typedef int X},
+/// but does not match \nomatch{using Y = int}.
extern const internal::VariadicDynCastAllOfMatcher
typedefDecl;
@@ -203,8 +358,9 @@ extern const internal::VariadicDynCastAllOfMatcher
/// typedef int X;
/// using Y = int;
/// \endcode
-/// typedefNameDecl()
-/// matches "typedef int X" and "using Y = int"
+/// \compile_args{-std=c++11-or-later}
+/// The matcher \matcher{typedefNameDecl()}
+/// matches \match{typedef int X} and \match{using Y = int}.
extern const internal::VariadicDynCastAllOfMatcher
typedefNameDecl;
@@ -215,34 +371,45 @@ extern const internal::VariadicDynCastAllOfMatcher
/// typedef int X;
/// using Y = int;
/// \endcode
-/// typeAliasDecl()
-/// matches "using Y = int", but not "typedef int X"
+/// \compile_args{-std=c++11-or-later}
+/// The matcher \matcher{typeAliasDecl()}
+/// matches \match{using Y = int},
+/// but does not match \nomatch{typedef int X}.
extern const internal::VariadicDynCastAllOfMatcher
typeAliasDecl;
/// Matches type alias template declarations.
///
-/// typeAliasTemplateDecl() matches
+/// Given
/// \code
-/// template
-/// using Y = X;
+/// template struct X {};
+/// template using Y = X;
/// \endcode
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+/// The matcher \matcher{typeAliasTemplateDecl()}
+/// matches \match{template using Y = X}.
extern const internal::VariadicDynCastAllOfMatcher
typeAliasTemplateDecl;
/// Matches AST nodes that were expanded within the main-file.
///
-/// Example matches X but not Y
-/// (matcher = cxxRecordDecl(isExpansionInMainFile())
-/// \code
-/// #include
-/// class X {};
-/// \endcode
-/// Y.h:
+/// Given the header \c Y.h
+/// \header{Y.h}
+/// #pragma once
+/// typedef int my_header_int;
+/// \endheader
+/// and the source file
/// \code
-/// class Y {};
+/// #include "Y.h"
+/// typedef int my_main_file_int;
+/// my_main_file_int a = 0;
+/// my_header_int b = 1;
/// \endcode
///
+/// The matcher \matcher{typedefDecl(isExpansionInMainFile())}
+/// matches \match{typedef int my_main_file_int},
+/// but does not match \nomatch{typedef int my_header_int}.
+///
/// Usable as: Matcher, Matcher, Matcher
AST_POLYMORPHIC_MATCHER(isExpansionInMainFile,
AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc)) {
@@ -253,16 +420,21 @@ AST_POLYMORPHIC_MATCHER(isExpansionInMainFile,
/// Matches AST nodes that were expanded within system-header-files.
///
-/// Example matches Y but not X
-/// (matcher = cxxRecordDecl(isExpansionInSystemHeader())
+/// Given the header \c SystemHeader.h
+/// \header{system_include/SystemHeader.h}
+/// #pragma once
+/// int header();
+/// \endheader
+/// and the source code
/// \code
/// #include
-/// class X {};
-/// \endcode
-/// SystemHeader.h:
-/// \code
-/// class Y {};
+/// static int main_file();
/// \endcode
+/// \compile_args{-isystemsystem_include/}
+///
+/// The matcher \matcher{type=none$functionDecl(isExpansionInSystemHeader())}
+/// matches \match{int header()},
+/// but does not match \nomatch{static int main_file()}.
///
/// Usable as: Matcher, Matcher, Matcher
AST_POLYMORPHIC_MATCHER(isExpansionInSystemHeader,
@@ -278,17 +450,32 @@ AST_POLYMORPHIC_MATCHER(isExpansionInSystemHeader,
/// Matches AST nodes that were expanded within files whose name is
/// partially matching a given regex.
///
-/// Example matches Y but not X
-/// (matcher = cxxRecordDecl(isExpansionInFileMatching("AST.*"))
-/// \code
-/// #include "ASTMatcher.h"
-/// class X {};
-/// \endcode
-/// ASTMatcher.h:
-/// \code
-/// class Y {};
+/// Given the headers \c Y.h
+/// \header{Y.h}
+/// #pragma once
+/// typedef int my_y_int;
+/// \endheader
+/// and \c X.h
+/// \header{X.h}
+/// #pragma once
+/// typedef int my_x_int;
+/// \endheader
+/// and the source code
+/// \code
+/// #include "X.h"
+/// #include "Y.h"
+/// typedef int my_main_file_int;
+/// my_main_file_int a = 0;
+/// my_x_int b = 1;
+/// my_y_int c = 2;
/// \endcode
///
+/// The matcher
+/// \matcher{type=none$typedefDecl(isExpansionInFileMatching("Y.h"))}
+/// matches \match{typedef int my_y_int},
+/// but does not match \nomatch{typedef int my_main_file_int} or
+/// \nomatch{typedef int my_x_int}.
+///
/// Usable as: Matcher, Matcher, Matcher
AST_POLYMORPHIC_MATCHER_REGEX(isExpansionInFileMatching,
AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt,
@@ -313,6 +500,17 @@ AST_POLYMORPHIC_MATCHER_REGEX(isExpansionInFileMatching,
/// Does not match if only part of the statement is expanded from that macro or
/// if different parts of the statement are expanded from different
/// appearances of the macro.
+///
+/// Given
+/// \code
+/// #define A 0
+/// #define B A
+/// int c = B;
+/// \endcode
+///
+/// The matcher \matcher{integerLiteral(isExpandedFromMacro("A"))}
+/// matches the literal expanded at the initializer \match{B} of the variable
+/// \c c .
AST_POLYMORPHIC_MATCHER_P(isExpandedFromMacro,
AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc),
std::string, MacroName) {
@@ -330,35 +528,50 @@ AST_POLYMORPHIC_MATCHER_P(isExpandedFromMacro,
/// Matches declarations.
///
-/// Examples matches \c X, \c C, and the friend declaration inside \c C;
+/// Given
/// \code
/// void X();
/// class C {
-/// friend X;
+/// friend void X();
/// };
/// \endcode
+/// \compile_args{-std=c++}
+/// The matcher \matcher{decl()}
+/// matches \match{void X()} once, \match{type=name;count=2$C}
+/// twice, once for the definition and once for the implicit class declaration,
+/// and \match{count=2$friend void X()} twice, once for the declaration of the
+/// friend, and once for the redeclaration of the function itself.
extern const internal::VariadicAllOfMatcher decl;
/// Matches decomposition-declarations.
///
-/// Examples matches the declaration node with \c foo and \c bar, but not
-/// \c number.
-/// (matcher = declStmt(has(decompositionDecl())))
-///
+/// Given
/// \code
+/// struct pair { int x; int y; };
+/// pair make(int, int);
/// int number = 42;
-/// auto [foo, bar] = std::make_pair{42, 42};
+/// auto [foo, bar] = make(42, 42);
/// \endcode
+/// \compile_args{-std=c++17-or-later}
+/// The matcher \matcher{decompositionDecl()}
+/// matches \match{auto [foo, bar] = make(42, 42)},
+/// but does not match \nomatch{type=name$number}.
extern const internal::VariadicDynCastAllOfMatcher
decompositionDecl;
/// Matches binding declarations
-/// Example matches \c foo and \c bar
-/// (matcher = bindingDecl()
///
+/// Given
/// \code
-/// auto [foo, bar] = std::make_pair{42, 42};
+/// struct pair { int x; int y; };
+/// pair make(int, int);
+/// void f() {
+/// auto [foo, bar] = make(42, 42);
+/// }
/// \endcode
+/// \compile_args{-std=c++17-or-later}
+/// The matcher \matcher{bindingDecl()}
+/// matches \match{type=name$foo} and \match{type=name$bar}.
extern const internal::VariadicDynCastAllOfMatcher
bindingDecl;
@@ -368,33 +581,41 @@ extern const internal::VariadicDynCastAllOfMatcher
/// \code
/// extern "C" {}
/// \endcode
-/// linkageSpecDecl()
-/// matches "extern "C" {}"
+/// \compile_args{-std=c++}
+/// The matcher \matcher{linkageSpecDecl()}
+/// matches \match{extern "C" {}}.
extern const internal::VariadicDynCastAllOfMatcher
linkageSpecDecl;
/// Matches a declaration of anything that could have a name.
///
/// Example matches \c X, \c S, the anonymous union type, \c i, and \c U;
+/// Given
/// \code
/// typedef int X;
-/// struct S {
-/// union {
-/// int i;
-/// } U;
-/// };
-/// \endcode
+/// struct S { union { int i; } U; };
+/// \endcode
+/// The matcher \matcher{namedDecl()}
+/// matches \match{typedef int X},
+/// \match{std=c$struct S { union { int i; } U; }}, \match{int i},
+/// the unnamed union\match{type=name$} and the variable
+/// \match{union { int i; } U},
+/// with \match{type=name;count=2;std=c++$S} matching twice in C++.
+/// Once for the implicit class declaration and once for the declaration itself.
extern const internal::VariadicDynCastAllOfMatcher namedDecl;
/// Matches a declaration of label.
///
/// Given
/// \code
-/// goto FOO;
-/// FOO: bar();
+/// void bar();
+/// void foo() {
+/// goto FOO;
+/// FOO: bar();
+/// }
/// \endcode
-/// labelDecl()
-/// matches 'FOO:'
+/// The matcher \matcher{type=none$labelDecl()}
+/// matches \match{FOO: bar()}.
extern const internal::VariadicDynCastAllOfMatcher labelDecl;
/// Matches a declaration of a namespace.
@@ -404,8 +625,9 @@ extern const internal::VariadicDynCastAllOfMatcher labelDecl;
/// namespace {}
/// namespace test {}
/// \endcode
-/// namespaceDecl()
-/// matches "namespace {}" and "namespace test {}"
+/// \compile_args{-std=c++}
+/// The matcher \matcher{namespaceDecl()}
+/// matches \match{namespace {}} and \match{namespace test {}}.
extern const internal::VariadicDynCastAllOfMatcher
namespaceDecl;
@@ -416,38 +638,53 @@ extern const internal::VariadicDynCastAllOfMatcher
/// namespace test {}
/// namespace alias = ::test;
/// \endcode
-/// namespaceAliasDecl()
-/// matches "namespace alias" but not "namespace test"
+/// \compile_args{-std=c++}
+/// The matcher \matcher{namespaceAliasDecl()}
+/// matches \match{namespace alias = ::test},
+/// but does not match \nomatch{namespace test {}}.
extern const internal::VariadicDynCastAllOfMatcher
namespaceAliasDecl;
/// Matches class, struct, and union declarations.
///
-/// Example matches \c X, \c Z, \c U, and \c S
+/// Given
/// \code
/// class X;
/// template class Z {};
/// struct S {};
/// union U {};
/// \endcode
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+/// The matcher \matcher{recordDecl()}
+/// matches \match{class X} once, and the rest of the declared records twice,
+/// once for their written definition and once for their implicit declaration:
+/// \match{type=name;count=2$Z}, \match{type=name;count=2$S} and
+/// \match{type=name;count=2$U}.
extern const internal::VariadicDynCastAllOfMatcher recordDecl;
/// Matches C++ class declarations.
///
-/// Example matches \c X, \c Z
+/// Given
/// \code
/// class X;
/// template class Z {};
/// \endcode
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+/// The matcher \matcher{cxxRecordDecl()}
+/// matches \match{class X} once, and \match{type=name;count=2$Z} twice,
+/// once for the written definition and once for the implicit declaration.
extern const internal::VariadicDynCastAllOfMatcher
cxxRecordDecl;
/// Matches C++ class template declarations.
///
-/// Example matches \c Z
+/// Given
/// \code
/// template class Z {};
/// \endcode
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+/// The matcher \matcher{classTemplateDecl()}
+/// matches \match{template class Z {}}.
extern const internal::VariadicDynCastAllOfMatcher
classTemplateDecl;
@@ -459,8 +696,10 @@ extern const internal::VariadicDynCastAllOfMatcher
/// template<> class A {};
/// A a;
/// \endcode
-/// classTemplateSpecializationDecl()
-/// matches the specializations \c A and \c A
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+/// The matcher \matcher{classTemplateSpecializationDecl()}
+/// matches \match{type=typestr$class A}
+/// and \match{type=typestr$class A}.
extern const internal::VariadicDynCastAllOfMatcher<
Decl, ClassTemplateSpecializationDecl>
classTemplateSpecializationDecl;
@@ -472,14 +711,15 @@ extern const internal::VariadicDynCastAllOfMatcher<
/// template
/// class A {};
///
-/// template
-/// class A {};
+/// template class A {};
///
/// template<>
/// class A {};
/// \endcode
-/// classTemplatePartialSpecializationDecl()
-/// matches the specialization \c A but not \c A
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+/// The matcher \matcher{classTemplatePartialSpecializationDecl()}
+/// matches \match{template class A {}},
+/// but does not match \nomatch{A}.
extern const internal::VariadicDynCastAllOfMatcher<
Decl, ClassTemplatePartialSpecializationDecl>
classTemplatePartialSpecializationDecl;
@@ -491,8 +731,9 @@ extern const internal::VariadicDynCastAllOfMatcher<
/// \code
/// class X { int y; };
/// \endcode
-/// declaratorDecl()
-/// matches \c int y.
+/// \compile_args{-std=c++}
+/// The matcher \matcher{declaratorDecl()}
+/// matches \match{int y}.
extern const internal::VariadicDynCastAllOfMatcher
declaratorDecl;
@@ -502,8 +743,8 @@ extern const internal::VariadicDynCastAllOfMatcher
/// \code
/// void f(int x);
/// \endcode
-/// parmVarDecl()
-/// matches \c int x.
+/// The matcher \matcher{parmVarDecl()}
+/// matches \match{int x}.
extern const internal::VariadicDynCastAllOfMatcher
parmVarDecl;
@@ -516,29 +757,36 @@ extern const internal::VariadicDynCastAllOfMatcher
/// int a;
/// };
/// \endcode
-/// accessSpecDecl()
-/// matches 'public:'
+/// \compile_args{-std=c++}
+/// The matcher \matcher{accessSpecDecl()}
+/// matches \match{public:}.
extern const internal::VariadicDynCastAllOfMatcher
accessSpecDecl;
/// Matches class bases.
///
-/// Examples matches \c public virtual B.
+/// Given
/// \code
/// class B {};
-/// class C : public virtual B {};
+/// class C : public B {};
/// \endcode
+/// \compile_args{-std=c++}
+/// The matcher \matcher{cxxRecordDecl(hasDirectBase(cxxBaseSpecifier()))}
+/// matches \match{class C : public B {}}.
extern const internal::VariadicAllOfMatcher cxxBaseSpecifier;
/// Matches constructor initializers.
///
-/// Examples matches \c i(42).
+/// Given
/// \code
/// class C {
/// C() : i(42) {}
/// int i;
/// };
/// \endcode
+/// \compile_args{-std=c++}
+/// The matcher \matcher{cxxCtorInitializer()}
+/// matches \match{i(42)}.
extern const internal::VariadicAllOfMatcher
cxxCtorInitializer;
@@ -549,8 +797,10 @@ extern const internal::VariadicAllOfMatcher
/// template struct C {};
/// C c;
/// \endcode
-/// templateArgument()
-/// matches 'int' in C.
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+/// The matcher
+/// \matcher{templateSpecializationType(hasAnyTemplateArgument(templateArgument()))}
+/// matches \match{type=typestr$C}.
extern const internal::VariadicAllOfMatcher templateArgument;
/// Matches template arguments (with location info).
@@ -560,8 +810,9 @@ extern const internal::VariadicAllOfMatcher templateArgument;
/// template struct C {};
/// C c;
/// \endcode
-/// templateArgumentLoc()
-/// matches 'int' in C.
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+/// The matcher \matcher{templateArgumentLoc()}
+/// matches \match{int} in C.
extern const internal::VariadicAllOfMatcher
templateArgumentLoc;
@@ -569,11 +820,15 @@ extern const internal::VariadicAllOfMatcher
///
/// Given
/// \code
-/// template class X { };
-/// X xi;
+/// template class S> class X {};
+/// template class Y {};
+/// X xi;
/// \endcode
-/// templateName()
-/// matches 'X' in X.
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+/// The matcher
+/// \matcher{classTemplateSpecializationDecl(hasAnyTemplateArgument(
+/// refersToTemplate(templateName())))}
+/// matches the specialization \match{type=typestr$class X}
extern const internal::VariadicAllOfMatcher templateName;
/// Matches non-type template parameter declarations.
@@ -582,8 +837,10 @@ extern const internal::VariadicAllOfMatcher templateName;
/// \code
/// template struct C {};
/// \endcode
-/// nonTypeTemplateParmDecl()
-/// matches 'N', but not 'T'.
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+/// The matcher \matcher{nonTypeTemplateParmDecl()}
+/// matches \match{int N},
+/// but does not match \nomatch{typename T}.
extern const internal::VariadicDynCastAllOfMatcher
nonTypeTemplateParmDecl;
@@ -594,8 +851,10 @@ extern const internal::VariadicDynCastAllOfMatcher struct C {};
/// \endcode
-/// templateTypeParmDecl()
-/// matches 'T', but not 'N'.
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+/// The matcher \matcher{templateTypeParmDecl()}
+/// matches \match{typename T},
+/// but does not \nomatch{int N}.
extern const internal::VariadicDynCastAllOfMatcher
templateTypeParmDecl;
@@ -605,8 +864,10 @@ extern const internal::VariadicDynCastAllOfMatcher
/// \code
/// template class Z, int N> struct C {};
/// \endcode
-/// templateTypeParmDecl()
-/// matches 'Z', but not 'N'.
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+/// The matcher \matcher{templateTemplateParmDecl()}
+/// matches \match{template class Z},
+/// but does not match \nomatch{int N}.
extern const internal::VariadicDynCastAllOfMatcher
templateTemplateParmDecl;
@@ -614,20 +875,31 @@ extern const internal::VariadicDynCastAllOfMatchergetASTContext()) == Width;
@@ -722,10 +1015,14 @@ AST_MATCHER_P(FieldDecl, hasBitWidth, unsigned, Width) {
/// int c;
/// };
/// \endcode
-/// fieldDecl(hasInClassInitializer(integerLiteral(equals(2))))
-/// matches 'int a;' but not 'int b;'.
-/// fieldDecl(hasInClassInitializer(anything()))
-/// matches 'int a;' and 'int b;' but not 'int c;'.
+/// \compile_args{-std=c++}
+/// The matcher
+/// \matcher{fieldDecl(hasInClassInitializer(integerLiteral(equals(2))))}
+/// matches \match{int a = 2},
+/// but does not match \nomatch{int b = 3}.
+/// The matcher \matcher{fieldDecl(hasInClassInitializer(anything()))}
+/// matches \match{int a = 2} and \match{int b = 3},
+/// but does not match \nomatch{int c}.
AST_MATCHER_P(FieldDecl, hasInClassInitializer, internal::Matcher,
InnerMatcher) {
const Expr *Initializer = Node.getInClassInitializer();
@@ -735,20 +1032,29 @@ AST_MATCHER_P(FieldDecl, hasInClassInitializer, internal::Matcher,
/// Determines whether the function is "main", which is the entry point
/// into an executable program.
-AST_MATCHER(FunctionDecl, isMain) {
- return Node.isMain();
-}
+///
+/// Given
+/// \code
+/// void f();
+/// int main() {}
+/// \endcode
+///
+/// The matcher \matcher{functionDecl(isMain())} matches \match{int main() {}}.
+AST_MATCHER(FunctionDecl, isMain) { return Node.isMain(); }
/// Matches the specialized template of a specialization declaration.
///
/// Given
/// \code
-/// template class A {}; #1
-/// template<> class A {}; #2
+/// template class A {}; // #1
+/// template<> class A {}; // #2
/// \endcode
-/// classTemplateSpecializationDecl(hasSpecializedTemplate(classTemplateDecl()))
-/// matches '#2' with classTemplateDecl() matching the class template
-/// declaration of 'A' at #1.
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+/// The matcher
+/// \matcher{classTemplateSpecializationDecl(hasSpecializedTemplate(classTemplateDecl().bind("ctd")))}
+/// matches \match{template<> class A {}},
+/// with \matcher{type=sub$classTemplateDecl()} matching the class template
+/// declaration \match{sub=ctd$template class A {}}.
AST_MATCHER_P(ClassTemplateSpecializationDecl, hasSpecializedTemplate,
internal::Matcher, InnerMatcher) {
const ClassTemplateDecl* Decl = Node.getSpecializedTemplate();
@@ -758,6 +1064,22 @@ AST_MATCHER_P(ClassTemplateSpecializationDecl, hasSpecializedTemplate,
/// Matches an entity that has been implicitly added by the compiler (e.g.
/// implicit default/copy constructors).
+///
+/// Given
+/// \code
+/// struct S {};
+/// void f(S obj) {
+/// S copy = obj;
+/// [&](){ return copy; };
+/// }
+/// \endcode
+/// \compile_args{-std=c++11}
+///
+/// The matcher \matcher{cxxConstructorDecl(isImplicit(), isCopyConstructor())}
+/// matches the implicit copy constructor of \match{S}.
+/// The matcher \matcher{lambdaExpr(forEachLambdaCapture(
+/// lambdaCapture(isImplicit())))} matches \match{[&](){ return copy; }},
+/// because it implicitly captures \c copy .
AST_POLYMORPHIC_MATCHER(isImplicit,
AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Attr,
LambdaCapture)) {
@@ -774,17 +1096,21 @@ AST_POLYMORPHIC_MATCHER(isImplicit,
/// template<> class A {};
/// A a;
///
-/// template f() {};
+/// template void f() {};
/// void func() { f(); };
/// \endcode
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
///
-/// \endcode
-/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
-/// refersToType(asString("int"))))
-/// matches the specialization \c A
+/// The matcher \matcher{classTemplateSpecializationDecl(
+/// hasAnyTemplateArgument(
+/// refersToType(asString("int"))))}
+/// matches \match{type=typestr$class A}.
///
-/// functionDecl(hasAnyTemplateArgument(refersToType(asString("int"))))
-/// matches the specialization \c f
+/// The matcher
+/// \matcher{functionDecl(hasAnyTemplateArgument(
+/// refersToType(asString("int"))))}
+/// matches the instantiation of
+/// \match{void f() {}}.
AST_POLYMORPHIC_MATCHER_P(
hasAnyTemplateArgument,
AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
@@ -807,12 +1133,10 @@ AST_POLYMORPHIC_MATCHER_P(
/// }
/// \endcode
/// The matcher
-/// \code
-/// traverse(TK_IgnoreUnlessSpelledInSource,
+/// \matcher{traverse(TK_IgnoreUnlessSpelledInSource,
/// varDecl(hasInitializer(floatLiteral().bind("init")))
-/// )
-/// \endcode
-/// matches the variable declaration with "init" bound to the "3.0".
+/// )}
+/// matches \match{int i = 3.0} with "init" bound to \match{sub=init$3.0}.
template
internal::Matcher traverse(TraversalKind TK,
const internal::Matcher &InnerMatcher) {
@@ -873,25 +1197,37 @@ traverse(TraversalKind TK, const internal::MapAnyOfHelper &InnerMatcher) {
/// nodes are stripped off.
///
/// Parentheses and explicit casts are not discarded.
+///
/// Given
/// \code
-/// class C {};
-/// C a = C();
-/// C b;
-/// C c = b;
-/// \endcode
-/// The matchers
-/// \code
-/// varDecl(hasInitializer(ignoringImplicit(cxxConstructExpr())))
-/// \endcode
-/// would match the declarations for a, b, and c.
-/// While
-/// \code
-/// varDecl(hasInitializer(cxxConstructExpr()))
+/// void f(int param) {
+/// int a = 0;
+/// int b = param;
+/// const int c = 0;
+/// const int d = param;
+/// int e = (0U);
+/// int f = (int)0.0;
+/// const int g = ((int)(((0))));
+/// }
/// \endcode
-/// only match the declarations for b and c.
-AST_MATCHER_P(Expr, ignoringImplicit, internal::Matcher,
- InnerMatcher) {
+///
+/// The matcher
+/// \matcher{varDecl(hasInitializer(ignoringImplicit(integerLiteral())))}
+/// matches \match{int a = 0} and \match{const int c = 0},
+/// but not \nomatch{int e = (0U)} and \nomatch{((int)(((0)))}.
+/// The matcher
+/// \matcher{varDecl(hasInitializer(integerLiteral()))}
+/// matches \match{int a = 0} and \match{const int c = 0},
+/// but not \nomatch{int e = (0U)} and \nomatch{((int)(((0)))}.
+///
+/// The matcher
+/// \matcher{varDecl(hasInitializer(ignoringImplicit(declRefExpr())))}
+/// matches \match{int b = param} and \match{const int d = param}.
+/// The matcher
+/// \matcher{varDecl(hasInitializer(declRefExpr()))}
+/// matches neither \nomatch{int b = param} nor \nomatch{const int d = param},
+/// because an l-to-r-value cast happens.
+AST_MATCHER_P(Expr, ignoringImplicit, internal::Matcher, InnerMatcher) {
return InnerMatcher.matches(*Node.IgnoreImplicit(), Finder, Builder);
}
@@ -902,24 +1238,32 @@ AST_MATCHER_P(Expr, ignoringImplicit, internal::Matcher,
/// Given
/// \code
/// int arr[5];
-/// int a = 0;
+/// const int a = 0;
/// char b = 0;
/// const int c = a;
/// int *d = arr;
/// long e = (long) 0l;
/// \endcode
-/// The matchers
-/// \code
-/// varDecl(hasInitializer(ignoringImpCasts(integerLiteral())))
-/// varDecl(hasInitializer(ignoringImpCasts(declRefExpr())))
-/// \endcode
-/// would match the declarations for a, b, c, and d, but not e.
-/// While
-/// \code
-/// varDecl(hasInitializer(integerLiteral()))
-/// varDecl(hasInitializer(declRefExpr()))
-/// \endcode
-/// only match the declarations for a.
+/// The matcher
+/// \matcher{varDecl(hasInitializer(ignoringImpCasts(integerLiteral())))}
+/// matches \match{const int a = 0} and \match{char b = 0},
+/// but does not match \nomatch{long e = (long) 0l} because of the c-style
+/// case.
+///
+/// The matcher
+/// \matcher{varDecl(hasInitializer(ignoringImpCasts(declRefExpr())))}
+/// matches \match{const int c = a} and \match{int *d = arr}.
+///
+/// The matcher
+/// \matcher{varDecl(hasInitializer(integerLiteral()))}
+/// matches \match{const int a = 0},
+/// but does not match \nomatch{char b = 0} because of the implicit cast to
+/// \c char or \nomatch{long e = (long) 0l} because of the c-style cast.
+///
+/// The matcher \matcher{varDecl(hasInitializer(declRefExpr()))}
+/// does not match \nomatch{const int c = a} because \c a is cast from an
+/// l- to an r-value or \nomatch{int *d = arr} because the array-to-pointer
+/// decay.
AST_MATCHER_P(Expr, ignoringImpCasts,
internal::Matcher, InnerMatcher) {
return InnerMatcher.matches(*Node.IgnoreImpCasts(), Finder, Builder);
@@ -936,12 +1280,15 @@ AST_MATCHER_P(Expr, ignoringImpCasts,
/// void* c = reinterpret_cast(0);
/// char d = char(0);
/// \endcode
+/// \compile_args{-std=c++}
/// The matcher
-/// varDecl(hasInitializer(ignoringParenCasts(integerLiteral())))
-/// would match the declarations for a, b, c, and d.
-/// while
-/// varDecl(hasInitializer(integerLiteral()))
-/// only match the declaration for a.
+/// \matcher{varDecl(hasInitializer(ignoringParenCasts(integerLiteral())))}
+/// matches \match{int a = 0}, \match{char b = (0)},
+/// \match{void* c = reinterpret_cast(0)} and \match{type=name$d}.
+///
+/// The matcher
+/// \matcher{varDecl(hasInitializer(integerLiteral()))}
+/// matches \match{int a = 0}.
AST_MATCHER_P(Expr, ignoringParenCasts, internal::Matcher, InnerMatcher) {
return InnerMatcher.matches(*Node.IgnoreParenCasts(), Finder, Builder);
}
@@ -959,14 +1306,25 @@ AST_MATCHER_P(Expr, ignoringParenCasts, internal::Matcher, InnerMatcher) {
/// int *d = (arr);
/// long e = ((long) 0l);
/// \endcode
-/// The matchers
-/// varDecl(hasInitializer(ignoringParenImpCasts(integerLiteral())))
-/// varDecl(hasInitializer(ignoringParenImpCasts(declRefExpr())))
-/// would match the declarations for a, b, c, and d, but not e.
-/// while
-/// varDecl(hasInitializer(integerLiteral()))
-/// varDecl(hasInitializer(declRefExpr()))
-/// would only match the declaration for a.
+/// \compile_args{-std=c++}
+///
+/// The matcher
+/// \matcher{varDecl(hasInitializer(ignoringParenImpCasts(integerLiteral())))}
+/// matches \match{int a = 0} and \match{char b = (0)},
+/// but does not match \nomatch{long e = ((long) 0l)} because of the c-style
+/// cast.
+///
+/// The matcher
+/// \matcher{varDecl(hasInitializer(ignoringParenImpCasts(declRefExpr())))}
+/// matches \match{const int c = a} and \match{int *d = (arr)}.
+///
+/// The matcher \matcher{varDecl(hasInitializer(integerLiteral()))} matches
+/// \match{int a = 0}, but does not match \nomatch{char b = (0)} or
+/// \nomatch{long e = ((long) 0l)} because of the casts.
+///
+/// The matcher \matcher{varDecl(hasInitializer(declRefExpr()))}
+/// does not match \nomatch{const int c = a} because of the l- to r-value cast,
+/// or \nomatch{int *d = (arr)} because of the array-to-pointer decay.
AST_MATCHER_P(Expr, ignoringParenImpCasts,
internal::Matcher, InnerMatcher) {
return InnerMatcher.matches(*Node.IgnoreParenImpCasts(), Finder, Builder);
@@ -979,10 +1337,8 @@ AST_MATCHER_P(Expr, ignoringParenImpCasts,
/// void (*fp)(void);
/// \endcode
/// The matcher
-/// \code
-/// varDecl(hasType(pointerType(pointee(ignoringParens(functionType())))))
-/// \endcode
-/// would match the declaration for fp.
+/// \matcher{varDecl(hasType(pointerType(pointee(ignoringParens(functionType())))))}
+/// matches \match{void (*fp)(void)}.
AST_MATCHER_P_OVERLOAD(QualType, ignoringParens, internal::Matcher,
InnerMatcher, 0) {
return InnerMatcher.matches(Node.IgnoreParens(), Finder, Builder);
@@ -995,10 +1351,9 @@ AST_MATCHER_P_OVERLOAD(QualType, ignoringParens, internal::Matcher,
/// const char* str = ("my-string");
/// \endcode
/// The matcher
-/// \code
-/// implicitCastExpr(hasSourceExpression(ignoringParens(stringLiteral())))
-/// \endcode
-/// would match the implicit cast resulting from the assignment.
+/// \matcher{implicitCastExpr(hasSourceExpression(ignoringParens(stringLiteral())))}
+/// would match the implicit cast resulting from the assignment
+/// \match{("my-string")}.
AST_MATCHER_P_OVERLOAD(Expr, ignoringParens, internal::Matcher,
InnerMatcher, 1) {
const Expr *E = Node.IgnoreParens();
@@ -1015,9 +1370,13 @@ AST_MATCHER_P_OVERLOAD(Expr, ignoringParens, internal::Matcher,
/// sizeof is known.
/// \code
/// template
-/// void f(T x, T y) { sizeof(sizeof(T() + T()); }
+/// void f(T x, T y) { sizeof(T() + T()); }
/// \endcode
-/// expr(isInstantiationDependent()) matches sizeof(sizeof(T() + T())
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+/// The matcher \matcher{expr(isInstantiationDependent())}
+/// matches \match{sizeof(T() + T())},
+/// \match{(T() + T())},
+/// \match{T() + T()} and two time \match{count=2$T()}.
AST_MATCHER(Expr, isInstantiationDependent) {
return Node.isInstantiationDependent();
}
@@ -1033,7 +1392,9 @@ AST_MATCHER(Expr, isInstantiationDependent) {
/// x + y;
/// }
/// \endcode
-/// expr(isTypeDependent()) matches x + y
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+/// The matcher \matcher{expr(isTypeDependent())}
+/// matches \match{x + y} and \match{x}.
AST_MATCHER(Expr, isTypeDependent) { return Node.isTypeDependent(); }
/// Matches expression that are value-dependent because they contain a
@@ -1044,7 +1405,9 @@ AST_MATCHER(Expr, isTypeDependent) { return Node.isTypeDependent(); }
/// \code
/// template int f() { return Size; }
/// \endcode
-/// expr(isValueDependent()) matches return Size
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+/// The matcher \matcher{expr(isValueDependent())}
+/// matches the return value \match{Size}.
AST_MATCHER(Expr, isValueDependent) { return Node.isValueDependent(); }
/// Matches templateSpecializationType, class template specializations,
@@ -1054,18 +1417,21 @@ AST_MATCHER(Expr, isValueDependent) { return Node.isValueDependent(); }
/// Given
/// \code
/// template class A {};
-/// A b;
-/// A c;
+/// A b;
+/// A c;
///
/// template void f() {}
/// void func() { f(); };
/// \endcode
-/// classTemplateSpecializationDecl(hasTemplateArgument(
-/// 1, refersToType(asString("int"))))
-/// matches the specialization \c A
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+/// The matcher
+/// \matcher{classTemplateSpecializationDecl(hasTemplateArgument(
+/// 1, refersToType(asString("int"))))}
+/// matches the specialization \match{type=typestr$class A}.
///
-/// functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))
-/// matches the specialization \c f
+/// The matcher \matcher{functionDecl(hasTemplateArgument(0,
+/// refersToType(asString("int"))))}
+/// matches the specialization of \match{void f() {}}.
AST_POLYMORPHIC_MATCHER_P2(
hasTemplateArgument,
AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
@@ -1086,8 +1452,10 @@ AST_POLYMORPHIC_MATCHER_P2(
/// template struct C {};
/// C c;
/// \endcode
-/// classTemplateSpecializationDecl(templateArgumentCountIs(1))
-/// matches C.
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+/// The matcher
+/// \matcher{classTemplateSpecializationDecl(templateArgumentCountIs(1))}
+/// matches \match{type=typestr$struct C}.
AST_POLYMORPHIC_MATCHER_P(
templateArgumentCountIs,
AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
@@ -1104,9 +1472,11 @@ AST_POLYMORPHIC_MATCHER_P(
/// template struct A {};
/// A a;
/// \endcode
-/// classTemplateSpecializationDecl(hasAnyTemplateArgument(refersToType(
-/// recordType(hasDeclaration(recordDecl(hasName("X")))))))
-/// matches the specialization of \c struct A generated by \c A.
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+/// The matcher
+/// \matcher{classTemplateSpecializationDecl(hasAnyTemplateArgument(refersToType(
+/// recordType(hasDeclaration(recordDecl(hasName("X")))))))}
+/// matches the specialization \match{type=typestr$struct A}.
AST_MATCHER_P(TemplateArgument, refersToType,
internal::Matcher, InnerMatcher) {
if (Node.getKind() != TemplateArgument::Type)
@@ -1122,9 +1492,11 @@ AST_MATCHER_P(TemplateArgument, refersToType,
/// template class Y {};
/// X xi;
/// \endcode
-/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
-/// refersToTemplate(templateName())))
-/// matches the specialization \c X
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+/// The matcher
+/// \matcher{classTemplateSpecializationDecl(hasAnyTemplateArgument(
+/// refersToTemplate(templateName())))}
+/// matches the specialization \match{type=typestr$class X}
AST_MATCHER_P(TemplateArgument, refersToTemplate,
internal::Matcher, InnerMatcher) {
if (Node.getKind() != TemplateArgument::Template)
@@ -1141,10 +1513,13 @@ AST_MATCHER_P(TemplateArgument, refersToTemplate,
/// template struct A {};
/// A<&B::next> a;
/// \endcode
-/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
-/// refersToDeclaration(fieldDecl(hasName("next")))))
-/// matches the specialization \c A<&B::next> with \c fieldDecl(...) matching
-/// \c B::next
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+/// The matcher
+/// \matcher{classTemplateSpecializationDecl(hasAnyTemplateArgument(
+/// refersToDeclaration(fieldDecl(hasName("next")).bind("next"))))}
+/// matches the specialization \match{type=typestr$struct A<&B::next>}
+/// with \matcher{type=sub$fieldDecl(hasName("next"))} matching
+/// \match{sub=next$int next}.
AST_MATCHER_P(TemplateArgument, refersToDeclaration,
internal::Matcher, InnerMatcher) {
if (Node.getKind() == TemplateArgument::Declaration)
@@ -1160,10 +1535,13 @@ AST_MATCHER_P(TemplateArgument, refersToDeclaration,
/// template struct A {};
/// A<&B::next> a;
/// \endcode
-/// templateSpecializationType(hasAnyTemplateArgument(
-/// isExpr(hasDescendant(declRefExpr(to(fieldDecl(hasName("next"))))))))
-/// matches the specialization \c A<&B::next> with \c fieldDecl(...) matching
-/// \c B::next
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+/// The matcher
+/// \matcher{templateSpecializationType(hasAnyTemplateArgument(
+/// isExpr(hasDescendant(declRefExpr(to(fieldDecl(hasName("next")).bind("next")))))))}
+/// matches the specialization \match{type=typestr$A<&struct B::next>}
+/// with \matcher{type=sub$fieldDecl(hasName("next"))} matching
+/// \match{sub=next$int next}.
AST_MATCHER_P(TemplateArgument, isExpr, internal::Matcher, InnerMatcher) {
if (Node.getKind() == TemplateArgument::Expression)
return InnerMatcher.matches(*Node.getAsExpr(), Finder, Builder);
@@ -1177,10 +1555,12 @@ AST_MATCHER_P(TemplateArgument, isExpr, internal::Matcher, InnerMatcher) {
/// template struct C {};
/// C<42> c;
/// \endcode
-/// classTemplateSpecializationDecl(
-/// hasAnyTemplateArgument(isIntegral()))
-/// matches the implicit instantiation of C in C<42>
-/// with isIntegral() matching 42.
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+/// The matcher \matcher{classTemplateSpecializationDecl(
+/// hasAnyTemplateArgument(isIntegral()))}
+/// matches the implicitly declared specialization
+/// \match{type=typestr$struct C<42>} from the instantiation for the type of the
+/// variable \c c .
AST_MATCHER(TemplateArgument, isIntegral) {
return Node.getKind() == TemplateArgument::Integral;
}
@@ -1192,9 +1572,12 @@ AST_MATCHER(TemplateArgument, isIntegral) {
/// template struct C {};
/// C<42> c;
/// \endcode
-/// classTemplateSpecializationDecl(
-/// hasAnyTemplateArgument(refersToIntegralType(asString("int"))))
-/// matches the implicit instantiation of C in C<42>.
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+/// The matcher \matcher{classTemplateSpecializationDecl(
+/// hasAnyTemplateArgument(refersToIntegralType(asString("int"))))}
+/// matches the implicitly declared specialization
+/// \match{type=typestr$struct C<42>} from the instantiation for the type of the
+/// variable \c c .
AST_MATCHER_P(TemplateArgument, refersToIntegralType,
internal::Matcher, InnerMatcher) {
if (Node.getKind() != TemplateArgument::Integral)
@@ -1213,9 +1596,12 @@ AST_MATCHER_P(TemplateArgument, refersToIntegralType,
/// template struct C {};
/// C<42> c;
/// \endcode
-/// classTemplateSpecializationDecl(
-/// hasAnyTemplateArgument(equalsIntegralValue("42")))
-/// matches the implicit instantiation of C in C<42>.
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+/// The matcher \matcher{classTemplateSpecializationDecl(
+/// hasAnyTemplateArgument(equalsIntegralValue("42")))}
+/// matches the implicitly declared specialization
+/// \match{type=typestr$struct C<42>} from the instantiation for the type of the
+/// variable \c c .
AST_MATCHER_P(TemplateArgument, equalsIntegralValue,
std::string, Value) {
if (Node.getKind() != TemplateArgument::Integral)
@@ -1231,23 +1617,28 @@ AST_MATCHER_P(TemplateArgument, equalsIntegralValue,
/// int x = 0;
/// }
/// \endcode
-/// autoreleasePoolStmt(stmt()) matches the declaration of "x"
-/// inside the autorelease pool.
+/// \compile_args{-ObjC}
+/// The matcher \matcher{autoreleasePoolStmt(stmt())} matches the declaration of
+/// \match{int x = 0} inside the autorelease pool.
extern const internal::VariadicDynCastAllOfMatcher autoreleasePoolStmt;
/// Matches any value declaration.
///
-/// Example matches A, B, C and F
+/// Given
/// \code
/// enum X { A, B, C };
/// void F();
+/// int V = 0;
/// \endcode
+/// The matcher \matcher{valueDecl()}
+/// matches \match{A}, \match{B}, \match{C}, \match{void F()}
+/// and \match{int V = 0}.
extern const internal::VariadicDynCastAllOfMatcher valueDecl;
/// Matches C++ constructor declarations.
///
-/// Example matches Foo::Foo() and Foo::Foo(int)
+/// Given
/// \code
/// class Foo {
/// public:
@@ -1255,93 +1646,134 @@ extern const internal::VariadicDynCastAllOfMatcher valueDecl;
/// Foo(int);
/// int DoSomething();
/// };
+///
+/// struct Bar {};
/// \endcode
+/// \compile_args{-std=c++}
+///
+/// The matcher \matcher{cxxConstructorDecl()}
+/// matches \match{Foo()} and \match{Foo(int)}.
extern const internal::VariadicDynCastAllOfMatcher
cxxConstructorDecl;
/// Matches explicit C++ destructor declarations.
///
-/// Example matches Foo::~Foo()
+/// Given
/// \code
/// class Foo {
/// public:
/// virtual ~Foo();
/// };
+///
+/// struct Bar {};
/// \endcode
+/// \compile_args{-std=c++}
+///
+/// The matcher \matcher{cxxDestructorDecl()}
+/// matches \match{virtual ~Foo()}.
extern const internal::VariadicDynCastAllOfMatcher
cxxDestructorDecl;
/// Matches enum declarations.
///
-/// Example matches X
+/// Given
/// \code
-/// enum X {
-/// A, B, C
-/// };
+/// enum X { A, B, C };
/// \endcode
+///
+/// The matcher \matcher{enumDecl()}
+/// matches the enum \match{enum X { A, B, C }}.
extern const internal::VariadicDynCastAllOfMatcher enumDecl;
/// Matches enum constants.
///
-/// Example matches A, B, C
+/// Given
/// \code
/// enum X {
/// A, B, C
/// };
/// \endcode
+/// The matcher \matcher{enumConstantDecl()}
+/// matches \match{A}, \match{B} and \match{C}.
extern const internal::VariadicDynCastAllOfMatcher
enumConstantDecl;
/// Matches tag declarations.
///
-/// Example matches X, Z, U, S, E
+/// Given
/// \code
/// class X;
/// template class Z {};
/// struct S {};
/// union U {};
-/// enum E {
-/// A, B, C
-/// };
+/// enum E { A, B, C };
/// \endcode
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+///
+/// The matcher \matcher{tagDecl()}
+/// matches \match{class X}, \match{class Z {}}, the implicit class
+/// declaration \match{class Z}, \match{struct S {}},
+/// the implicit class declaration \match{struct S}, \match{union U {}},
+/// the implicit class declaration \match{union U}
+/// and \match{enum E { A, B, C }}.
extern const internal::VariadicDynCastAllOfMatcher tagDecl;
/// Matches method declarations.
///
-/// Example matches y
+/// Given
/// \code
/// class X { void y(); };
/// \endcode
+/// \compile_args{-std=c++}
+///
+/// The matcher \matcher{cxxMethodDecl()}
+/// matches \match{void y()}.
extern const internal::VariadicDynCastAllOfMatcher
cxxMethodDecl;
/// Matches conversion operator declarations.
///
-/// Example matches the operator.
+/// Given
/// \code
/// class X { operator int() const; };
/// \endcode
+/// \compile_args{-std=c++}
+///
+/// The matcher \matcher{cxxConversionDecl()}
+/// matches \match{operator int() const}.
extern const internal::VariadicDynCastAllOfMatcher
cxxConversionDecl;
/// Matches user-defined and implicitly generated deduction guide.
///
-/// Example matches the deduction guide.
+/// Given
/// \code
/// template
-/// class X { X(int) };
+/// class X { X(int); };
/// X(int) -> X;
/// \endcode
+/// \compile_args{-fno-delayed-template-parsing;-std=c++17-or-later}
+///
+/// The matcher \matcher{cxxDeductionGuideDecl()}
+/// matches the written deduction guide
+/// \match{type=typestr$auto (int) -> X},
+/// the implicit copy deduction guide \match{type=typestr$auto (int) -> X}
+/// and the implicitly declared deduction guide
+/// \match{type=typestr$auto (X) -> X}.
extern const internal::VariadicDynCastAllOfMatcher
cxxDeductionGuideDecl;
/// Matches concept declarations.
///
-/// Example matches integral
+/// Given
/// \code
-/// template
-/// concept integral = std::is_integral_v;
+/// template concept my_concept = true;
/// \endcode
+/// \compile_args{-fno-delayed-template-parsing;-std=c++20-or-later}
+///
+/// The matcher \matcher{conceptDecl()}
+/// matches \match{template
+/// concept my_concept = true}.
extern const internal::VariadicDynCastAllOfMatcher
conceptDecl;
@@ -1353,17 +1785,29 @@ extern const internal::VariadicDynCastAllOfMatcher
/// Example matches a
/// \code
/// int a;
+/// struct Foo {
+/// int x;
+/// };
+/// void bar(int val);
/// \endcode
+///
+/// The matcher \matcher{varDecl()}
+/// matches \match{int a} and \match{int val}, but not \nomatch{int x}.
extern const internal::VariadicDynCastAllOfMatcher varDecl;
/// Matches field declarations.
///
/// Given
/// \code
-/// class X { int m; };
+/// int a;
+/// struct Foo {
+/// int x;
+/// };
+/// void bar(int val);
/// \endcode
-/// fieldDecl()
-/// matches 'm'.
+/// \compile_args{-std=c++}
+/// The matcher \matcher{fieldDecl()}
+/// matches \match{int x}.
extern const internal::VariadicDynCastAllOfMatcher fieldDecl;
/// Matches indirect field declarations.
@@ -1372,17 +1816,20 @@ extern const internal::VariadicDynCastAllOfMatcher fieldDecl;
/// \code
/// struct X { struct { int a; }; };
/// \endcode
-/// indirectFieldDecl()
-/// matches 'a'.
+/// The matcher \matcher{indirectFieldDecl()}
+/// matches \match{a}.
extern const internal::VariadicDynCastAllOfMatcher
indirectFieldDecl;
/// Matches function declarations.
///
-/// Example matches f
+/// Given
/// \code
/// void f();
/// \endcode
+///
+/// The matcher \matcher{functionDecl()}
+/// matches \match{void f()}.
extern const internal::VariadicDynCastAllOfMatcher
functionDecl;
@@ -1392,6 +1839,10 @@ extern const internal::VariadicDynCastAllOfMatcher
/// \code
/// template void f(T t) {}
/// \endcode
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+///
+/// The matcher \matcher{functionTemplateDecl()}
+/// matches \match{template void f(T t) {}}.
extern const internal::VariadicDynCastAllOfMatcher
functionTemplateDecl;
@@ -1401,28 +1852,32 @@ extern const internal::VariadicDynCastAllOfMatcher
/// \code
/// class X { friend void foo(); };
/// \endcode
-/// friendDecl()
-/// matches 'friend void foo()'.
+/// \compile_args{-std=c++}
+/// The matcher \matcher{friendDecl()}
+/// matches \match{friend void foo()}.
extern const internal::VariadicDynCastAllOfMatcher friendDecl;
/// Matches statements.
///
/// Given
/// \code
-/// { ++a; }
+/// void foo(int a) { { ++a; } }
/// \endcode
-/// stmt()
-/// matches both the compound statement '{ ++a; }' and '++a'.
+/// The matcher \matcher{stmt()}
+/// matches the function body itself \match{{ { ++a; } }}, the compound
+/// statement \match{{ ++a; }}, the expression \match{++a} and \match{a}.
extern const internal::VariadicAllOfMatcher stmt;
/// Matches declaration statements.
///
/// Given
/// \code
-/// int a;
+/// void foo() {
+/// int a;
+/// }
/// \endcode
-/// declStmt()
-/// matches 'int a'.
+/// The matcher \matcher{declStmt()}
+/// matches \match{int a;}.
extern const internal::VariadicDynCastAllOfMatcher declStmt;
/// Matches member expressions.
@@ -1434,8 +1889,9 @@ extern const internal::VariadicDynCastAllOfMatcher declStmt;
/// int a; static int b;
/// };
/// \endcode
-/// memberExpr()
-/// matches this->x, x, y.x, a, this->b
+/// \compile_args{-std=c++}
+/// The matcher \matcher{memberExpr()}
+/// matches \match{this->x}, \match{x}, \match{y.x}, \match{a}, \match{this->b}.
extern const internal::VariadicDynCastAllOfMatcher memberExpr;
/// Matches unresolved member expressions.
@@ -1448,8 +1904,9 @@ extern const internal::VariadicDynCastAllOfMatcher memberExpr;
/// };
/// template void h() { X x; x.f(); x.g(); }
/// \endcode
-/// unresolvedMemberExpr()
-/// matches x.f
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+/// The matcher \matcher{unresolvedMemberExpr()}
+/// matches \match{x.f}
extern const internal::VariadicDynCastAllOfMatcher
unresolvedMemberExpr;
@@ -1460,8 +1917,9 @@ extern const internal::VariadicDynCastAllOfMatcher
/// \code
/// template void f() { T t; t.g(); }
/// \endcode
-/// cxxDependentScopeMemberExpr()
-/// matches t.g
+/// \compile_args{-fno-delayed-template-parsing;-std=c++}
+/// The matcher \matcher{cxxDependentScopeMemberExpr()}
+/// matches \match{t.g}
extern const internal::VariadicDynCastAllOfMatcher
cxxDependentScopeMemberExpr;
@@ -1470,15 +1928,22 @@ extern const internal::VariadicDynCastAllOfMatcher callExpr;
/// Matches call expressions which were resolved using ADL.
///
-/// Example matches y(x) but not y(42) or NS::y(x).
+/// Given
/// \code
/// namespace NS {
/// struct X {};
@@ -1494,25 +1959,46 @@ extern const internal::VariadicDynCastAllOfMatcher callExpr;
/// y(42); // Doesn't match
/// using NS::y;
/// y(x); // Found by both unqualified lookup and ADL, doesn't match
-// }
+/// }
/// \endcode
+/// \compile_args{-std=c++11-or-later}
+///
+/// The matcher \matcher{callExpr(usesADL())}
+/// matches \match{y(x)}, but not \nomatch{y(42)} or \nomatch{NS::y(x)}.
AST_MATCHER(CallExpr, usesADL) { return Node.usesADL(); }
/// Matches lambda expressions.
///
-/// Example matches [&](){return 5;}
+/// Given
/// \code
-/// [&](){return 5;}
+/// void f() {
+/// []() { return 5; };
+/// }
/// \endcode
+/// \compile_args{-std=c++11-or-later}
+///
+/// The matcher \matcher{lambdaExpr()} matches \match{[]() { return 5; }}.
extern const internal::VariadicDynCastAllOfMatcher lambdaExpr;
/// Matches member call expressions.
///
-/// Example matches x.y()
+/// Given
/// \code
-/// X x;
-/// x.y();
+/// struct X {
+/// void y();
+/// void m() { y(); }
+/// };
+/// void f();
+/// void g() {
+/// X x;
+/// x.y();
+/// f();
+/// }
/// \endcode
+/// \compile_args{-std=c++}
+///
+/// The matcher \matcher{cxxMemberCallExpr()} matches \match{x.y()} and
+/// \match{y()}, but not \nomatch{f()}.
extern const internal::VariadicDynCastAllOfMatcher
cxxMemberCallExpr;
@@ -1525,6 +2011,10 @@ extern const internal::VariadicDynCastAllOfMatcher
/// \code
/// [[NSString alloc] initWithString:@"Hello"]
/// \endcode
+/// \compile_args{-ObjC}
+///
+/// The matcher \matcher{objcMessageExpr()} matches
+/// \match{[[NSString alloc] initWithString:@"Hello"]}
extern const internal::VariadicDynCastAllOfMatcher
objcMessageExpr;
@@ -1534,6 +2024,7 @@ extern const internal::VariadicDynCastAllOfMatcher
/// \code
/// NSString *s = @"abcd";
/// \endcode
+/// \compile_args{-ObjC}
extern const internal::VariadicDynCastAllOfMatcher
objcStringLiteral;
@@ -1544,6 +2035,7 @@ extern const internal::VariadicDynCastAllOfMatcher
/// @interface Foo
/// @end
/// \endcode
+/// \compile_args{-ObjC}
extern const internal::VariadicDynCastAllOfMatcher
objcInterfaceDecl;
@@ -1554,6 +2046,7 @@ extern const internal::VariadicDynCastAllOfMatcher
/// @implementation Foo
/// @end
/// \endcode
+/// \compile_args{-ObjC}
extern const internal::VariadicDynCastAllOfMatcher
objcImplementationDecl;
@@ -1564,6 +2057,7 @@ extern const internal::VariadicDynCastAllOfMatcher
/// @protocol FooDelegate
/// @end
/// \endcode
+/// \compile_args{-ObjC}
extern const internal::VariadicDynCastAllOfMatcher
objcProtocolDecl;
@@ -1574,6 +2068,7 @@ extern const internal::VariadicDynCastAllOfMatcher
/// @interface Foo (Additions)
/// @end
/// \endcode
+/// \compile_args{-ObjC}
extern const internal::VariadicDynCastAllOfMatcher
objcCategoryDecl;
@@ -1584,6 +2079,7 @@ extern const internal::VariadicDynCastAllOfMatcher
/// @implementation Foo (Additions)
/// @end
/// \endcode
+/// \compile_args{-ObjC}
extern const internal::VariadicDynCastAllOfMatcher
objcCategoryImplDecl;
@@ -1599,6 +2095,7 @@ extern const internal::VariadicDynCastAllOfMatcher
/// - (void)method {}
/// @end
/// \endcode
+/// \compile_args{-ObjC}
extern const internal::VariadicDynCastAllOfMatcher
objcMethodDecl;
@@ -1612,6 +2109,7 @@ extern const internal::VariadicDynCastAllOfMatcher
/// printf("%d", p);
/// })
/// \endcode
+/// \compile_args{-ObjC}
extern const internal::VariadicDynCastAllOfMatcher
blockDecl;
@@ -1624,6 +2122,7 @@ extern const internal::VariadicDynCastAllOfMatcher
/// }
/// @end
/// \endcode
+/// \compile_args{-ObjC}
extern const internal::VariadicDynCastAllOfMatcher
objcIvarDecl;
@@ -1635,6 +2134,7 @@ extern const internal::VariadicDynCastAllOfMatcher