diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html index 99917ccff5260..c6307954d7f1b 100644 --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -586,36 +586,28 @@
Matches class bases. -Given +Examples matches public virtual B. class B {}; class C : public virtual B {}; - -The matcher cxxRecordDecl(hasDirectBase(cxxBaseSpecifier())) -matches C.
Matches constructor initializers. -Given +Examples matches i(42). class C { C() : i(42) {} int i; }; - -The matcher cxxCtorInitializer() -matches i(42).
Matches binding declarations +Example matches foo and bar +(matcher = bindingDecl() -Given - struct pair { int x; int y; }; - pair make(int, int); - auto [foo, bar] = make(42, 42); - -The matcher bindingDecl() -matches foo and bar. + auto [foo, bar] = std::make_pair{42, 42};
Matches C++ class template declarations. -Given +Example matches Z template<class T> class Z {}; - -The matcher classTemplateDecl() -matches Z.
Matches concept declarations. -Given - template<typename T> concept my_concept = true; - - -The matcher conceptDecl() -matches template<typename T> -concept my_concept = true. +Example matches integral + template<typename T> + concept integral = std::is_integral_v<T>;
Matches C++ constructor declarations. -Given +Example matches Foo::Foo() and Foo::Foo(int) class Foo { public: Foo(); Foo(int); int DoSomething(); }; - - struct Bar {}; - - -The matcher cxxConstructorDecl() -matches Foo() and Foo(int).
Matches conversion operator declarations. -Given +Example matches the operator. class X { operator int() const; }; - - -The matcher cxxConversionDecl() -matches operator int() const.
Matches user-defined and implicitly generated deduction guide. -Given +Example matches the deduction guide. 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. -Given +Example matches Foo::~Foo() class Foo { public: virtual ~Foo(); }; - - struct Bar {}; - - -The matcher cxxDestructorDecl() -matches virtual ~Foo().
Matches method declarations. -Given +Example matches y class X { void y(); }; - - -The matcher cxxMethodDecl() -matches void y().
Matches C++ class declarations. -Given +Example matches X, Z class X; template<class T> class Z {}; - -The matcher cxxRecordDecl() -matches X and Z.
Matches declarations. -Given +Examples matches X, C, and the friend declaration inside C; void X(); class C { - friend void X(); + friend X; }; - -The matcher decl() -matches void X(), C -and friend void X().
Matches decomposition-declarations. -Given - struct pair { int x; int y; }; - pair make(int, int); - int number = 42; - auto [foo, bar] = make(42, 42); +Examples matches the declaration node with foo and bar, but not +number. +(matcher = declStmt(has(decompositionDecl()))) -The matcher decompositionDecl() -matches auto [foo, bar] = make(42, 42), -but does not match number. + int number = 42; + auto [foo, bar] = std::make_pair{42, 42};
Matches enum constants. -Given +Example matches A, B, C enum X { A, B, C }; -The matcher enumConstantDecl() -matches A, B and C.
Matches enum declarations. -Given +Example matches X enum X { A, B, C }; - -The matcher enumDecl() -matches the enum X.
Matches field declarations. Given - int a; - struct Foo { - int x; - }; - void bar(int val); - -The matcher fieldDecl() -matches int x. + class X { int m; }; +fieldDecl() + matches 'm'.
Matches function declarations. -Given +Example matches f void f(); - -The matcher functionDecl() -matches void f().
Matches a declaration of label. Given - void bar(); - void foo() { - goto FOO; - FOO: bar(); - } -The matcher labelDecl() -matches FOO: bar(). + goto FOO; + FOO: bar(); +labelDecl() + matches 'FOO:'
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. -Given +Example matches X, Z, U, and S 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. -Given +Example: + staticAssertDecl() +matches + static_assert(sizeof(S) == sizeof(int)) +in struct S { int x; }; static_assert(sizeof(S) == sizeof(int)); - - -The matcher staticAssertDecl() -matches static_assert(sizeof(S) == sizeof(int)).
Matches tag declarations. -Given +Example matches X, Z, U, S, E class X; template<class T> class Z {}; struct S {}; union U {}; - 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 }. + enum E { + A, B, C + };
Matches type alias template declarations. -Given - template <typename T> struct X {}; - template <typename T> using Y = X<T>; - -The matcher typeAliasTemplateDecl() -matches template <typename T> using Y = X<T>. +typeAliasTemplateDecl() matches + template <typename T> + using Y = X<T>;
Matches using-enum declarations. Given - namespace X { enum x { val1, val2 }; } + namespace X { enum x {...}; } using enum X::x; - -The matcher usingEnumDecl() - matches using enum X::x -
Matches any value declaration. -Given +Example matches A, B, C and F 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 -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). +``ompDefaultClause()`` matches ``default(none)``, ``default(shared)``, +`` default(private)`` and ``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 *ptr; -} -The matcher addrLabelExpr() -matches &&FOO + goto *bar; +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 testStructuredBinding() { + void testStructBinding() { int a[2] = {1, 2}; auto [x, y] = a; } - - -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. +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`.
Matches a loop initializing the elements of an array in a number of -contexts: +@@ -1495,34 +1307,26 @@ 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 @@ -1482,12 +1293,13 @@Node Matchers
Given void testLambdaCapture() { int a[10]; - [a]() {}; + auto Lam1 = [a]() { + return; + }; } - -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. +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 - void foo() { - int a[2] = {0, 1}; - int i = a[1]; - } -The matcher arraySubscriptExpr() -matches a[1]. + int i = a[1]; +arraySubscriptExpr() + matches "a[1]"Matcher<Stmt> asmStmt Matcher<AsmStmt>... Matches asm statements. -void foo() { int i = 100; - __asm("mov %al, 2"); -} -The matcher asmStmt() -matches __asm("mov %al, 2") + __asm("mov al, 2"); +asmStmt() + matches '__asm("mov al, 2")'Matcher<Stmt> atomicExpr Matcher<AtomicExpr>... @@ -1533,35 +1337,24 @@ Matches atomic builtins. - -Given +Example matches __atomic_load_n(ptr, 1) void foo() { int *ptr; __atomic_load_n(ptr, 1); } - -The matcher atomicExpr() matches __atomic_load_n(ptr, 1).Node Matchers
@autoreleasepool { int x = 0; } - -The matcher autoreleasePoolStmt(stmt()) matches the declaration of -int x = 0 inside the autorelease pool. +autoreleasePoolStmt(stmt()) matches the declaration of "x" +inside the autorelease pool.
Matches binary conditional operator expressions (GNU extension). -Given - int f(int a, int b) { - return (a ?: b) + 42; - } - -The matcher binaryConditionalOperator() matches a ?: b. +Example matches a ?: b + (a ?: b) + 42;
Matches binary operator expressions. -Given - void foo(bool a, bool b) { - !(a || b); - } - - -The matcher binaryOperator() matches a || b. - +Example matches a || b + !(a || b) See also the binaryOperation() matcher for more-general matching.
Matches a reference to a block. -Given +Example: matches "^{}": void f() { ^{}(); } - - -The matcher blockExpr() matches ^{}.
Matches break statements. Given -void foo() { while (true) { break; } -} - -The matcher breakStmt() -matches break +breakStmt() + matches 'break'
Matches a C-style cast expression. -Given +Example: Matches (int) 2.2f in int i = (int) 2.2f; - -The matcher cStyleCastExpr() -matches (int) 2.2f.
Matches call expressions. Example matches x.y() and y() - struct X { void foo(); }; - void bar(); - void foobar() { - X x; - x.foo(); - bar(); - } - -The matcher callExpr() -matches x.foo() and bar(); + X x; + x.y(); + y();
Matches case statements inside switch statements. Given -void foo(int a) { switch(a) { case 42: break; default: break; } -} -The matcher caseStmt() -matches case 42: break. +caseStmt() + matches 'case 42:'.
Matches any cast nodes of Clang's AST. -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. +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;
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 - 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(). + co_await 1; +coawaitExpr() + matches 'co_await 1'
Matches compound (i.e. non-scalar) literals Example match: {1}, (1, 2) - struct vector { int x; int y; }; - struct vector myvec = (struct vector){ 1, 2 }; - -The matcher compoundLiteralExpr() -matches (struct vector){ 1, 2 }. + int array[4] = {1}; + vector int myvec = (vector int)(1, 2);
Matches compound statements. -Given -void foo() { for (;;) {{}} } - -The matcher compoundStmt() matches -{ for (;;) {{}} }, {{}} and {}. +Example matches '{}' and '{{}}' in 'for (;;) {{}}' + for (;;) {{}}
Matches conditional operator expressions. -Given - int f(int a, int b, int c) { - return (a ? b : c) + 42; - } - -The matcher conditionalOperator() matches a ? b : c. +Example matches a ? b : c + (a ? b : c) + 42
Matches a constant expression wrapper. -Given - void f(int a) { - switch (a) { - case 37: break; - } +Example matches the constant in the case statement: + (matcher = constantExpr()) + switch (a) { + case 37: break; } - -The matcher constantExpr() matches 37.
Matches continue statements. Given -void foo() { while (true) { continue; } -} - -The matcher continueStmt() -matches continue +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 - 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 + while (true) { co_return; } +coreturnStmt() + matches 'co_return'
Matches coroutine body statements. -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; } }. +coroutineBodyStmt() matches the coroutine below + generator<int> gen() { + co_return; + }
Matches co_yield expressions. 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 - - 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 + co_yield 1; +coyieldExpr() + matches 'co_yield 1'
Matches CUDA kernel call expression. -Given - __global__ void kernel() {} - void f() { - kernel<<<32,32>>>(); - } - -The matcher cudaKernelCallExpr() -matches kernel<<<i, k>>>() +Example matches, + kernel<<<i,j>>>();
Matches nodes where temporaries are created. -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(). +Example matches FunctionTakesString(GetStringByValue()) + (matcher = cxxBindTemporaryExpr()) + FunctionTakesString(GetStringByValue()); + FunctionTakesStringByPointer(GetStringPointer());
Matches bool literals. Example matches true - bool Flag = true; - - -The matcher cxxBoolLiteral() matches true. + true
Matches catch statements. -void foo() { try {} catch(int i) {} -} - -The matcher cxxCatchStmt() -matches catch(int i) {} +cxxCatchStmt() + matches 'catch(int i)'
Matches a const_cast expression. -Given +Example: Matches const_cast<int*>(&r) in 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). -Given - struct string { - string(const char*); - string(const char*s, int n); - }; +Example matches string(ptr, n) and ptr within arguments of f + (matcher = cxxConstructExpr()) void f(const string &a, const string &b); - void foo(char *ptr, int n) { - f(string(ptr, n), ptr); - } - - -The matcher cxxConstructExpr() matches string(ptr, n) -and ptr within arguments of f . + char *ptr; + int n; + f(string(ptr, n), ptr);
Matches the value of a default argument at the call site. -Given +Example matches the CXXDefaultArgExpr placeholder inserted for the + default value of the second parameter in the call expression f(42) + (matcher = cxxDefaultArgExpr()) void f(int x, int y = 0); - 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). + f(42);
Matches delete expressions. Given - 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. + delete X; +cxxDeleteExpr() + matches 'delete X'.
Matches a dynamic_cast expression. -Given +Example: + cxxDynamicCastExpr() +matches + dynamic_cast<D*>(&b); +in 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. -Given +Example matches `(0 + ... + args)`: template <typename... Args> auto sum(Args... args) { return (0 + ... + args); } - - -The matcher cxxFoldExpr() matches (0 + ... + args).
Matches range-based for statements. -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); +cxxForRangeStmt() matches 'for (auto a : i)' + int i[] = {1, 2, 3}; for (auto a : i); + for(int j = 0; j < 5; ++j);
Matches functional cast expressions -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). +Example: Matches Foo(bar); + Foo f = bar; + Foo g = (Foo) bar; + Foo h = Foo(bar);
Matches member call expressions. -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(). +Example matches x.y() + X x; + x.y();
Matches new expressions. Given - void* operator new(decltype(sizeof(void*))); - struct X {}; - void foo() { - auto* x = new X; - } - - -The matcher cxxNewExpr() -matches new X. + new X; +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 bool operator==(const HasSpaceshipMem&) const = default; + constexpr auto 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 - 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 }; + std::vector<int> a({ 1, 2, 3 }); + std::vector<int> b = { 4, 5 }; int c[] = { 6, 7 }; - struct pair { int x; int y; }; - pair d = { 8, 9 }; - -The matcher cxxStdInitializerListExpr() -matches { 1, 2, 3 } and { 4, 5 }. + std::pair<int, int> d = { 8, 9 }; +cxxStdInitializerListExpr() + matches "{ 1, 2, 3 }" and "{ 4, 5 }"
Matches functional cast expressions having N != 1 arguments -Given - struct Foo { - Foo(int x, int y); - }; - - void foo(int bar) { - Foo h = Foo(bar, bar); - } - - -The matcher cxxTemporaryObjectExpr() -matches Foo(bar, bar). +Example: Matches Foo(bar, bar) + Foo h = Foo(bar, bar);
Matches implicit and explicit this expressions. - -Given - struct foo { - int i; - int f() { return i; } - int g() { return this->i; } - }; - ++ Matcher<Stmt> cxxThisExpr Matcher<CXXThisExpr>... Matches implicit and explicit this expressions. -The matcher cxxThisExpr() -matches this of this->i and the implicit this expression -of i. +Example matches the implicit this expression in "return i". + (matcher = cxxThisExpr()) +struct foo { + int i; + int f() { return i; } +};Matcher<Stmt> cxxThrowExpr Matcher<CXXThrowExpr>... Matches throw expressions. -void foo() { try { throw 5; } catch(int i) {} -} - -The matcher cxxThrowExpr() -matches throw 5 +cxxThrowExpr() + matches 'throw 5'Matcher<Stmt> cxxTryStmt Matcher<CXXTryStmt>... Matches try statements. -void foo() { try {} catch(int i) {} -} - -The matcher cxxTryStmt() -matches try {} catch(int i) {} +cxxTryStmt() + matches 'try {}'Matcher<Stmt> cxxUnresolvedConstructExpr Matcher<CXXUnresolvedConstructExpr>... Matches unresolved constructor call expressions. -Given +Example matches T(t) in return statement of f + (matcher = cxxUnresolvedConstructExpr()) template <typename T> void f(const T& t) { return T(t); } - - -The matcher cxxUnresolvedConstructExpr() matches -T(t).Matcher<Stmt> declRefExpr Matcher<DeclRefExpr>... @@ -2396,11 +1836,9 @@ Matches expressions that refer to declarations. -Given - void f(bool x) { - if (x) {} - } - - -The matcher declRefExpr() matches x. +Example matches x in if (x) + bool x; + if (x) {}Node Matchers
@@ -2408,75 +1846,22 @@ Matches declaration statements. Given - void foo() { - int a; - } -The matcher declStmt() -matches int a;. + int a; +declStmt() + matches 'int a'.Node Matchers
Matches default statements inside switch statements. Given -void foo(int a) { switch(a) { case 42: break; default: break; } -} -The matcher defaultStmt() -matches default: break. +defaultStmt() + matches 'default:'.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>... @@ -2484,12 +1869,9 @@ Matches C99 designated initializer expressions [C99 6.7.8]. -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. +Example: Matches { [2].y = 1.0, [0].x = 1.0 } + point ptarray[10] = { [2].y = 1.0, [0].x = 1.0 };Node Matchers
@@ -2507,36 +1889,18 @@ Matches do statements. Given -void foo() { do {} while (true); -} - -The matcher doStmt() -matches do {} while (true) +doStmt() + matches 'do {} while(true)'Node Matchers
See also: hasDestinationType. - 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. +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;
Matches expressions. -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. +Example matches x() + void f() { x(); }
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. -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. +Does not match implicit conversions such as + float a = 10;
Matches for statements. -Given - void foo() { - for (;;) {} - int i[] = {1, 2, 3}; for (auto a : i); - } - - -The matcher forStmt() matches for (;;) {}, -but not for (auto a : i);. +Example matches 'for (;;) {}' + for (;;) {} + int i[] = {1, 2, 3}; 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(); -} -The matcher gotoStmt() -matches goto FOO +gotoStmt() + matches 'goto FOO'
Matches if statements. -Given - void foo(int x) { - if (x) {} - } - -The matcher ifStmt() matches if (x) {}. +Example matches 'if (x) {}' + 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 - struct point { double x; double y; }; - struct point pt = { .x = 42.0 }; -The matcher -initListExpr(has(implicitValueInitExpr().bind("implicit"))) -matches { .x = 42.0 }. + point ptarray[10] = { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 }; +implicitValueInitExpr() + matches "[0].y" (implicitly)
Matches label statements. Given -void bar(); -void foo() { goto FOO; FOO: bar(); -} -The matcher labelStmt() -matches FOO: bar() +labelStmt() + matches 'FOO:'
Matches lambda expressions. -Given - void f() { - []() { return 5; }; - } - - -The matcher lambdaExpr() matches []() { return 5; }. +Example matches [&](){return 5;} + [&](){return 5;}
Matches null statements. -void foo() { foo();; -} -The matcher nullStmt() -matches the second ; +nullStmt() + matches the second ';'
Matches a reference to an ObjCIvar. -Given +Example: matches "a" in "init" method: @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 - } - } -The matcher ompExecutableDirective() -matches #pragma omp parallel, -#pragma omp parallel default(none) -and #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``.
Matches parentheses used in expressions. -Given +Example matches (foo() + 1) int foo() { return 1; } - int bar() { - int a = (foo() + 1); - } - -The matcher parenExpr() matches (foo() + 1). + int a = (foo() + 1);
Matches predefined identifier expressions [C99 6.4.2.2]. Example: Matches __func__ - void f() { - const char* func_name = __func__; - } - -The matcher predefinedExpr() -matches __func__. + printf("%s", __func__);
Matches return statements. Given -int foo() { return 1; -} -The matcher returnStmt() -matches return 1 +returnStmt() + matches 'return 1'
Matches statements. Given - void foo(int a) { { ++a; } } -The matcher stmt() -matches the function body itself { { ++a; } }, the compound -statement { ++a; }, the expression ++a and a. + { ++a; } +stmt() + matches both the compound statement '{ ++a; }' and '++a'.
Matches statement expression (GNU extension). -Given - void f() { - int C = ({ int X = 4; X; }); - } - -The matcher stmtExpr() matches ({ int X = 4; X; }). +Example match: ({ int X = 4; X; }) + int C = ({ int X = 4; X; });
Matches string literals (also matches wide string literals). -Given +Example matches "abcd", L"abcd" 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; } -} -The matcher switchCase() -matches case 42: break and default: break +switchCase() + matches 'case 42:' and 'default:'.
Matches switch statements. Given -void foo(int a) { switch(a) { case 42: break; default: break; } -} -The matcher switchStmt() -matches switch(a) { case 42: break; default: break; }. +switchStmt() + matches 'switch(a)'.
Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL) Given - int x = 42; + Foo x = bar; int y = sizeof(x) + alignof(x); - -The matcher unaryExprOrTypeTraitExpr() -matches sizeof(x) and alignof(x) +unaryExprOrTypeTraitExpr() + matches sizeof(x) and alignof(x)
Matches unary operator expressions. Example matches !a - void foo(bool a, bool b) { - !a || b; - } - - -The matcher unaryOperator() matches !a. + !a || b
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) {} -} - -The matcher whileStmt() -matches while (true) {}. +whileStmt() + matches 'while (true) {}'.
Matches template name. Given - 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> + template <typename T> class X { }; + X<int> xi; +templateName() + matches 'X' in X<int>.
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 - 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). +Given: + auto n = 4; + int v[] = { 2, 3 } + for (auto i : v) { } +autoType() + matches "auto n" and "auto i"
Matches builtin Types. Given - enum E { Ok }; - enum E e; + struct A {}; + A a; int b; float c; -The matcher varDecl(hasType(builtinType())) -matches int b and float c. + bool d; +builtinType() + matches "int b", "float c" and "bool d"
Matches C arrays with a specified constant size. Given - void foo() { + void() { int a[2]; int b[] = { 2, 3 }; int c[b[0]]; } -The matcher constantArrayType() -int[2] +constantArrayType() + matches "int a[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; } -The matcher -valueDecl(hasType(decayedType(hasDecayedType(pointerType())))) -matches int i[] in declaration of The matcher -expr(hasType(decayedType(hasDecayedType(pointerType())))) -matches i in
Matches types nodes representing C++11 decltype(<expr>) types. -Given +Given: short i = 1; int j = 42; decltype(i + j) result = i + j; - -The matcher decltypeType() -decltype(i + j) +decltypeType() + matches "decltype(i + j)"
Matches injected class name types. -Given +Example matches S s, but not S<T> s. + (matcher = parmVarDecl(hasType(injectedClassNameType()))) 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; @@ -3523,11 +2655,8 @@Node Matchers
auto &&f = 2; int g = 5; - -The matcher lValueReferenceType() matches the type -int & of b and the type auto & -of d. -FIXME: figure out why auto changechange matches twice +lValueReferenceType() matches the types of b, d, and e. e is +matched since the type is deduced as int& by reference collapsing rules.
Matches member pointer types. Given - struct A { int i; }; - int A::* ptr = &A::i; - -The matcher memberPointerType() -matches int struct A::*. + struct A { int i; } + A::* ptr = A::i; +memberPointerType() + matches "A::* ptr"
Matches rvalue reference types. -Given +Given: int *a; int &b = *a; int &&c = 1; @@ -3623,10 +2738,8 @@Node Matchers
auto &&f = 2; int g = 5; - -The matcher rValueReferenceType() matches the type -int && of c and the type -auto && of f. +rValueReferenceType() matches the types of c and f. e is not +matched as it is deduced to int& by reference collapsing rules.
Matches tag types (record and enum types). Given - enum E { Ok }; + enum E {}; class C {}; E e; C 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. +tagType() matches the type of the variable declarations of both e +and c.
Matches template type parameter types. -Given +Example matches T, but not int. + (matcher = templateTypeParmType()) 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 - template <typename T> struct A { - typedef __underlying_type(T) type; - }; - -The matcher unaryTransformType() -matches __underlying_type(T) +Given: + typedef __underlying_type(T) type; +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 - 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; );. + 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") + ); 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. -Given +Example matches Y (matcher = cxxRecordDecl(unless(hasName("X")))) 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. -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). + Is equivalent to + anyOf(hasOperatorName("+"), hasOperatorName("-"))
Matches the operator Name of operator expressions and fold expressions (binary or unary). -Given -void foo(bool a, bool b) { - !(a || b); - } - -The matcher binaryOperator(hasOperatorName("||")) -matches a || b +Example matches a || b (matcher = binaryOperator(hasOperatorName("||"))) + !(a || b) -Given +Example matches `(0 + ... + args)` + (matcher = cxxFoldExpr(hasOperatorName("+"))) template <typename... Args> auto sum(Args... args) { return (0 + ... + args); } - -The matcher cxxFoldExpr(hasOperatorName("+")) - matches (0 + ... + args).
Matches all kinds of assignment operators. -Given -void foo(int a, int b) { +Example 1: matches a += b (matcher = binaryOperator(isAssignmentOperator())) if (a == b) a += b; -} -The matcher binaryOperator(isAssignmentOperator()) -matches a += b. -Given +Example 2: matches s1 = s2 + (matcher = cxxOperatorCallExpr(isAssignmentOperator())) struct S { S& operator=(const S&); }; void x() { S s1, s2; s1 = s2; } - -The matcher cxxOperatorCallExpr(isAssignmentOperator()) -matches s1 = s2.
Matches comparison operators. -Given -void foo(int a, int b) { +Example 1: matches a == b (matcher = binaryOperator(isComparisonOperator())) if (a == b) a += b; -} -The matcher binaryOperator(isComparisonOperator()) -matches a == b -Given +Example 2: matches s1 < s2 + (matcher = cxxOperatorCallExpr(isComparisonOperator())) 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. -Given +Examples: class C { public: int a; protected: int b; - private: int c; + private: int c; // fieldDecl(isPrivate()) matches 'c' }; -The matcher fieldDecl(isPrivate()) -matches c. - struct 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. + struct Derived1 : private Base {}; // matches 'Base' + class Derived2 : Base {}; // matches 'Base'
Matches protected C++ declarations and C++ base specifers that specify protected inheritance. -Given +Examples: class C { public: int a; - protected: int b; + protected: int b; // fieldDecl(isProtected()) matches 'b' private: int c; }; -The matcher fieldDecl(isProtected()) -matches b. - class Base {}; - class Derived : protected Base {}; - -The matcher -cxxRecordDecl(hasAnyBase(cxxBaseSpecifier(isProtected()).bind("base"))) -matches Derived, with -cxxBaseSpecifier(isProtected()) matching -Base. + class Derived : protected Base {}; // matches 'Base'
Matches public C++ declarations and C++ base specifers that specify public inheritance. -Given +Examples: class C { - public: int a; + public: int a; // fieldDecl(isPublic()) matches 'a' protected: int b; private: int c; }; -The matcher fieldDecl(isPublic()) -matches a. - -Given class 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. + class Derived1 : public Base {}; // matches 'Base' + struct Derived2 : Base {}; // matches 'Base'
Matches declarations of virtual methods and C++ base specifers that specify virtual inheritance. -Given +Example: class A { public: virtual void x(); // matches x }; -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. +Example: + class Base {}; + class DirectlyDerived : virtual Base {}; // matches Base + class IndirectlyDerived : DirectlyDerived, Base {}; // matches Base 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); -} - -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. +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 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: -Given - int val = -1; - -The matcher unaryOperator(hasOperatorName("-"), - hasUnaryOperand(integerLiteral(equals(1)))) -matches -1. +unaryOperator(hasOperatorName("-"), + hasUnaryOperand(integerLiteral(equals(13)))) Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteralExpr>, Matcher<FloatingLiteral>, Matcher<IntegerLiteral> @@ -4168,15 +3130,14 @@Narrowing Matchers
@@ -4184,15 +3145,12 @@ Matches a C++ catch statement that has a catch-all handler. Given - void foo() { - try {} - catch (int) {} - catch (...) {} + try { + // ... + } catch (int) { + // ... + } catch (...) { + // ... } - -The matcher cxxCatchStmt(isCatchAll()) -matches catch (...) {} -but does not match catch(int) +cxxCatchStmt(isCatchAll()) matches catch(...) but not catch(int).Narrowing Matchers
@@ -4200,39 +3158,14 @@ Checks that a call expression or a constructor call expression has at least the specified number of arguments (including absent default arguments). -Given +Example matches f(0, 0) and g(0, 0, 0) +(matcher = callExpr(argumentCountAtLeast(2))) void f(int x, int y); void g(int x, int y, int z); - void foo() { - f(0, 0); - g(0, 0, 0); - } -The matcher callExpr(argumentCountAtLeast(2)) -matches f(0, 0) and g(0, 0, 0) + f(0, 0); + 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). -Given +Example matches f(0, 0) (matcher = callExpr(argumentCountIs(2))) void f(int x, int y); - void foo() { - f(0, 0); - } -The matcher callExpr(argumentCountIs(2)) -matches f(0, 0) + f(0, 0);Matcher<CXXConstructExpr> isListInitialization @@ -4242,15 +3175,11 @@ 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 }.Narrowing Matchers
Given void foo() { - struct Foo { - double x; - }; - auto Val = Foo(); + struct point { double x; double y; }; + point pt[2] = { { 1.0, 2.0 } }; } - -The matcher -cxxConstructExpr(requiresZeroInitialization()) -matches Foo() because the x member has to be zero initialized. +initListExpr(has(cxxConstructExpr(requiresZeroInitialization())) +will match the implicit array filler for pt[1].
Matches the operator Name of operator expressions and fold expressions (binary or unary). -Given -void foo(bool a, bool b) { - !(a || b); - } - -The matcher binaryOperator(hasOperatorName("||")) -matches a || b +Example matches a || b (matcher = binaryOperator(hasOperatorName("||"))) + !(a || b) -Given +Example matches `(0 + ... + args)` + (matcher = cxxFoldExpr(hasOperatorName("+"))) 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. -Given +Example matches `(0 + ... + args)` + (matcher = cxxFoldExpr(isBinaryFold())) template <typename... Args> auto sum(Args... args) { return (0 + ... + args); @@ -4626,17 +3478,14 @@Narrowing Matchers
auto multiply(Args... args) { return (args * ...); } - - -The matcher cxxFoldExpr(isBinaryFold()) -matches (0 + ... + args).
Matches left-folding fold expressions. -Given +Example matches `(0 + ... + args)` + (matcher = cxxFoldExpr(isLeftFold())) template <typename... Args> auto sum(Args... args) { return (0 + ... + args); @@ -4646,17 +3495,14 @@Narrowing Matchers
auto multiply(Args... args) { return (args * ... * 1); } - - -The matcher cxxFoldExpr(isLeftFold()) -matches (0 + ... + args).
Matches right-folding fold expressions. -Given +Example matches `(args * ... * 1)` + (matcher = cxxFoldExpr(isRightFold())) template <typename... Args> auto sum(Args... args) { return (0 + ... + args); @@ -4666,10 +3512,6 @@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. -Given +Example matches `(args * ...)` + (matcher = cxxFoldExpr(isUnaryFold())) template <typename... Args> auto sum(Args... args) { return (0 + ... + args); @@ -4687,10 +3530,6 @@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 { @@ -4760,13 +3591,7 @@Narrowing Matchers
struct C : B { void f() final; }; - -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 A and C::f, but not B, C, or B::f
Matches declarations of virtual methods and C++ base specifers that specify virtual inheritance. -Given +Example: class A { public: virtual void x(); // matches x }; -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. +Example: + class Base {}; + class DirectlyDerived : virtual Base {}; // matches Base + class IndirectlyDerived : DirectlyDerived, Base {}; // matches Base Usable as: Matcher<CXXMethodDecl>, Matcher<CXXBaseSpecifier>
Matches array new expressions. -Given - struct MyClass { int x; }; +Given: MyClass *p1 = new MyClass[10]; - -The matcher cxxNewExpr(isArray()) -matches new MyClass[10]. +cxxNewExpr(isArray()) + matches the expression '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 - 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). + Is equivalent to + anyOf(hasOperatorName("+"), hasOperatorName("-"))
Matches the operator Name of operator expressions and fold expressions (binary or unary). -Given -void foo(bool a, bool b) { - !(a || b); - } - -The matcher binaryOperator(hasOperatorName("||")) -matches a || b +Example matches a || b (matcher = binaryOperator(hasOperatorName("||"))) + !(a || b) -Given +Example matches `(0 + ... + args)` + (matcher = cxxFoldExpr(hasOperatorName("+"))) template <typename... Args> auto sum(Args... args) { return (0 + ... + args); } - -The matcher cxxFoldExpr(hasOperatorName("+")) - matches (0 + ... + args).
Matches all kinds of assignment operators. -Given -void foo(int a, int b) { +Example 1: matches a += b (matcher = binaryOperator(isAssignmentOperator())) if (a == b) a += b; -} -The matcher binaryOperator(isAssignmentOperator()) -matches a += b. -Given +Example 2: matches s1 = s2 + (matcher = cxxOperatorCallExpr(isAssignmentOperator())) struct S { S& operator=(const S&); }; void x() { S s1, s2; s1 = s2; } - -The matcher cxxOperatorCallExpr(isAssignmentOperator()) -matches s1 = s2.
Matches comparison operators. -Given -void foo(int a, int b) { +Example 1: matches a == b (matcher = binaryOperator(isComparisonOperator())) if (a == b) a += b; -} -The matcher binaryOperator(isComparisonOperator()) -matches a == b -Given +Example 2: matches s1 < s2 + (matcher = cxxOperatorCallExpr(isComparisonOperator())) 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. -Given +Example matches x (matcher = cxxRecordDecl(hasDefinition())) 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 { @@ -5134,46 +3829,24 @@Narrowing Matchers
struct C : B { void f() final; }; - -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 A and C::f, but not B, C, or B::f
Matches the generated class of lambda expressions. -Given +Given: auto x = []{}; - -The matcher varDecl(hasType(cxxRecordDecl(isLambda()))) -matches auto x = []{}. +cxxRecordDecl(isLambda()) matches the implicit class declaration of +decltype(x)
Similar to isDerivedFrom(), but also matches classes that directly -match Base. -Overloaded method as shortcut for +@@ -5182,36 +3855,18 @@ 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; - -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> + 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>. But given - template <typename T> class X {}; - class A {}; - template <> class X<A> {}; - X<A> x; - -The matcher cxxRecordDecl(hasName("::X"), -isTemplateInstantiation()) + template <typename T> class X {}; class A {}; + template <> class X<A> {}; X<A> x; +cxxRecordDecl(hasName("::X"), isTemplateInstantiation()) does not match, as X<A> is an explicit template specialization. Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl> @@ -5222,26 +3877,9 @@Narrowing Matchers
@@ -5249,62 +3887,43 @@ 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 - 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). + Is equivalent to + anyOf(hasOperatorName("+"), hasOperatorName("-"))Narrowing Matchers
Matches the operator Name of operator expressions and fold expressions (binary or unary). -Given -void foo(bool a, bool b) { - !(a || b); - } - -The matcher binaryOperator(hasOperatorName("||")) -matches a || b +Example matches a || b (matcher = binaryOperator(hasOperatorName("||"))) + !(a || b) -Given +Example matches `(0 + ... + args)` + (matcher = cxxFoldExpr(hasOperatorName("+"))) 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. -Given -void foo(int a, int b) { +Example 1: matches a += b (matcher = binaryOperator(isAssignmentOperator())) if (a == b) a += b; -} -The matcher binaryOperator(isAssignmentOperator()) -matches a += b. -Given +Example 2: matches s1 = s2 + (matcher = cxxOperatorCallExpr(isAssignmentOperator())) struct S { S& operator=(const S&); }; void x() { S s1, s2; s1 = s2; } - -The matcher cxxOperatorCallExpr(isAssignmentOperator()) -matches s1 = s2.Matcher<CXXRewrittenBinaryOperator> isComparisonOperator @@ -5312,15 +3931,12 @@ Matches comparison operators. -Given -void foo(int a, int b) { +Example 1: matches a == b (matcher = binaryOperator(isComparisonOperator())) if (a == b) a += b; -} -The matcher binaryOperator(isComparisonOperator()) -matches a == b -Given +Example 2: matches s1 < s2 + (matcher = cxxOperatorCallExpr(isComparisonOperator())) 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
@@ -5328,13 +3944,9 @@ Checks that a call expression or a constructor call expression has at least the specified number of arguments (including absent default arguments). -Given +Example matches f(0, 0) and g(0, 0, 0) +(matcher = callExpr(argumentCountAtLeast(2))) void f(int x, int y); void g(int x, int y, int z); - void foo() { - f(0, 0); - g(0, 0, 0); - } -The matcher callExpr(argumentCountAtLeast(2)) -matches f(0, 0) and g(0, 0, 0) + f(0, 0); + g(0, 0, 0);Narrowing Matchers
@@ -5342,15 +3954,12 @@ Checks that a call expression or a constructor call expression has a specific number of arguments (including absent default arguments). -Given +Example matches f(0, 0) (matcher = callExpr(argumentCountIs(2))) void f(int x, int y); - void foo() { - f(0, 0); - } -The matcher callExpr(argumentCountIs(2)) -matches f(0, 0) + f(0, 0);Narrowing Matchers
@@ -5358,20 +3967,16 @@ Checks that a call expression or a constructor call expression has at least the specified number of arguments (including absent default arguments). -Given +Example matches f(0, 0) and g(0, 0, 0) +(matcher = callExpr(argumentCountAtLeast(2))) void f(int x, int y); void g(int x, int y, int z); - void foo() { - f(0, 0); - g(0, 0, 0); - } -The matcher callExpr(argumentCountAtLeast(2)) -matches f(0, 0) and g(0, 0, 0) + f(0, 0); + 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). -Given +Example matches f(0, 0) (matcher = callExpr(argumentCountIs(2))) void f(int x, int y); - void foo() { - f(0, 0); - } -The matcher callExpr(argumentCountIs(2)) -matches f(0, 0) + f(0, 0);Matcher<CallExpr> usesADL Matches call expressions which were resolved using ADL. -Given +Example matches y(x) but not y(42) or NS::y(x). namespace NS { struct X {}; void y(X); @@ -5387,20 +3992,15 @@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 @@ -5487,11 +4078,10 @@ Matches casts that has a given cast kind. -Given +Example: matches the implicit cast around 0 +(matcher = castExpr(hasCastKind(CK_NullToPointer))) 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"). @@ -5415,27 +4015,22 @@Narrowing Matchers
@@ -5468,11 +4061,9 @@ 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); -} - -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. +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 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: -Given - int val = -1; - -The matcher unaryOperator(hasOperatorName("-"), - hasUnaryOperand(integerLiteral(equals(1)))) -matches -1. +unaryOperator(hasOperatorName("-"), + hasUnaryOperand(integerLiteral(equals(13)))) Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteralExpr>, Matcher<FloatingLiteral>, Matcher<IntegerLiteral> @@ -5456,10 +4051,8 @@Narrowing Matchers
Given template<typename T> struct C {}; C<int> c; - -The matcher classTemplateSpecializationDecl(templateArgumentCountIs(1)) -matches struct C<int>. + matches C<int>.Narrowing Matchers
child statements. Example: Given -void foo() { { for (;;) {} } -} -The matcher compoundStmt(statementCountIs(0)) -{} +compoundStmt(statementCountIs(0))) + matches '{}' but does not match the outer compound statement.Narrowing Matchers
char *s = "abcd"; wchar_t *ws = L"abcd"; char *w = "a"; - -The matcher constantArrayType(hasSize(42)) -matches int[42] twice. -The matcher stringLiteral(hasSize(4)) -matches "abcd" and L"abcd". +constantArrayType(hasSize(42)) + matches "int a[42]" and "int b[2 * 21]" +stringLiteral(hasSize(4)) + matches "abcd", L"abcd"
Matches declaration statements that contain a specific number of declarations. -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; +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;'.
Matches declaration that has a given attribute. Given - __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"). + __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").
Matches AST nodes that were expanded within files whose name is partially matching a given regex. -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. +Example matches Y but not X + (matcher = cxxRecordDecl(isExpansionInFileMatching("AST.*")) + #include "ASTMatcher.h" + class X {}; +ASTMatcher.h: + class Y {}; Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc> @@ -5608,18 +4169,12 @@Narrowing Matchers
Matcher<Decl> isExpansionInMainFile @@ -5628,17 +4183,12 @@ Matches AST nodes that were expanded within the main-file. -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. +Example matches X but not Y + (matcher = cxxRecordDecl(isExpansionInMainFile()) + #include <Y.h> + class X {}; +Y.h: + class Y {}; Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>Narrowing Matchers
Matcher<Decl> isExpansionInSystemHeader @@ -5647,20 +4197,6 @@ Matches AST nodes that were expanded within system-header-files. -Given the header SystemHeader.h - #pragma once - int header(); -and the source code +Example matches Y but not X + (matcher = cxxRecordDecl(isExpansionInSystemHeader()) #include <SystemHeader.h> - static int main_file(); - - -The matcher functionDecl(isExpansionInSystemHeader()) -matches int header(), -but does not match static int main_file(). + class X {}; +SystemHeader.h: + class Y {}; Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>Narrowing Matchers
Matcher<Decl> isImplicit @@ -5678,14 +4214,11 @@ 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 .Narrowing Matchers
namespace { class vector {}; // #2 namespace foo { - class vector {}; // #3 + class vector{}; // #3 } } - -The matcher cxxRecordDecl(hasName("vector"), - isInAnonymousNamespace()) -matches vector, -twice per declaration at #1, #2 and #3. +cxxRecordDecl(hasName("vector"), isInAnonymousNamespace()) will match +#1, #2 and #3.
Matches private C++ declarations and C++ base specifers that specify private inheritance. -Given +Examples: class C { public: int a; protected: int b; - private: int c; + private: int c; // fieldDecl(isPrivate()) matches 'c' }; -The matcher fieldDecl(isPrivate()) -matches c. - struct 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. + struct Derived1 : private Base {}; // matches 'Base' + class Derived2 : Base {}; // matches 'Base'
Matches protected C++ declarations and C++ base specifers that specify protected inheritance. -Given +Examples: class C { public: int a; - protected: int b; + protected: int b; // fieldDecl(isProtected()) matches 'b' private: int c; }; -The matcher fieldDecl(isProtected()) -matches b. - class Base {}; - class Derived : protected Base {}; - -The matcher -cxxRecordDecl(hasAnyBase(cxxBaseSpecifier(isProtected()).bind("base"))) -matches Derived, with -cxxBaseSpecifier(isProtected()) matching -Base. + class Derived : protected Base {}; // matches 'Base'
Matches public C++ declarations and C++ base specifers that specify public inheritance. -Given +Examples: class C { - public: int a; + public: int a; // fieldDecl(isPublic()) matches 'a' protected: int b; private: int c; }; -The matcher fieldDecl(isPublic()) -matches a. - -Given class 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. + class Derived1 : public Base {}; // matches 'Base' + struct Derived2 : Base {}; // matches 'Base'
Matches C++11 scoped enum declaration. -Given +Example matches Y (matcher = enumDecl(isScoped())) 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 - #define NULL 0 +Given: void *v1 = NULL; void *v2 = nullptr; void *v3 = __null; // GNU extension char *cp = (char *)0; int *ip = 0; int i = 0; - -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. +expr(nullPointerConstant()) + matches the initializer for v1, v2, v3, cp, and ip. Does not match the + initializer for 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); -} - -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. +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 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: -Given - int val = -1; - -The matcher unaryOperator(hasOperatorName("-"), - hasUnaryOperand(integerLiteral(equals(1)))) -matches -1. +unaryOperator(hasOperatorName("-"), + hasUnaryOperand(integerLiteral(equals(13)))) Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteralExpr>, Matcher<FloatingLiteral>, Matcher<IntegerLiteral> @@ -5980,30 +4452,6 @@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(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 . +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.
Matches a function declared with a trailing return type. -Given +Example matches Y (matcher = functionDecl(hasTrailingReturn())) 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 {} } - -The matcher functionDecl(isConsteval()) -matches a. -The matcher ifStmt(isConsteval()) -matches the if statements -if consteval {}, if ! consteval {} and -if ! consteval {} else {}. +functionDecl(isConsteval()) + matches the declaration of "int a()". +ifStmt(isConsteval()) + matches the if statement in "void b()", "void c()", "void d()".
Matches constexpr variable and function declarations, and if constexpr. -Given +Given: constexpr int foo = 42; constexpr int bar(); void baz() { if constexpr(1 > 0) {} } - -The matcher varDecl(isConstexpr()) -matches foo. -The matcher functionDecl(isConstexpr()) -matches bar. -The matcher ifStmt(isConstexpr()) -matches 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.
Matches defaulted function declarations. -Given +Given: class A { ~A(); }; class B { ~B() = default; }; - -The matcher functionDecl(isDefaulted()) - matches ~B() = default, -but does not match ~A(). +functionDecl(isDefaulted()) + matches the declaration of ~B, but not ~A.
Matches deleted function declarations. -Given +Given: void Func(); void DeletedFunc() = delete; - -The matcher functionDecl(isDeleted()) -matches DeletedFunc, -but does not match Func. +functionDecl(isDeleted()) + matches the declaration of DeletedFunc, but not 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; - -The matcher functionDecl(isExternC()) -matches f -and g. -The matcher varDecl(isExternC()) -matches x -and y, -but does not match z. +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.
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(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 . +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.
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; -The matcher functionDecl(isStaticStorageClass()) - matches f -The matcher varDecl(isStaticStorageClass()) - matches i +functionDecl(isStaticStorageClass()) + matches the function declaration f. +varDecl(isStaticStorageClass()) + matches the variable declaration i.
Matches weak function declarations. -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(). +Given: + void foo() __attribute__((__weakref__("__foo"))); + void bar(); +functionDecl(isWeak()) + matches the weak declaration "foo", but not "bar".
Matches functions that have a dynamic exception specification. -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 . +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.
Matches functions that have a non-throwing exception specification. -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 . +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.
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 {} } - -The matcher functionDecl(isConsteval()) -matches a. -The matcher ifStmt(isConsteval()) -matches the if statements -if consteval {}, if ! consteval {} and -if ! consteval {} else {}. +functionDecl(isConsteval()) + matches the declaration of "int a()". +ifStmt(isConsteval()) + matches the if statement in "void b()", "void c()", "void d()".
Matches constexpr variable and function declarations, and if constexpr. -Given +Given: constexpr int foo = 42; constexpr int bar(); void baz() { if constexpr(1 > 0) {} } - -The matcher varDecl(isConstexpr()) -matches foo. -The matcher functionDecl(isConstexpr()) -matches bar. -The matcher ifStmt(isConstexpr()) -matches 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.
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); -} - -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. +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 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: -Given - int val = -1; - -The matcher unaryOperator(hasOperatorName("-"), - hasUnaryOperand(integerLiteral(equals(1)))) -matches -1. +unaryOperator(hasOperatorName("-"), + hasUnaryOperand(integerLiteral(equals(13)))) Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteralExpr>, Matcher<FloatingLiteral>, Matcher<IntegerLiteral> @@ -6558,30 +4876,14 @@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. - -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). + hasAnyName(a, b, c) + is equivalent to, but faster than + anyOf(hasName(a), hasName(b), hasName(c))
Matches a declaration that has external formal linkage. -Given +Example matches only z (matcher = varDecl(hasExternalFormalLinkage())) void f() { - int a; - static int b; + int x; + static int y; } -int c; -static int d; -The matcher varDecl(hasExternalFormalLinkage()) -matches int c, -but not int a, static int b or int d. - -Given - namespace { - void f() {} - } - void g() {} - static void h() {} +int z; +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())) -The matcher functionDecl(hasExternalFormalLinkage()) -matches void g() {}, but not void f() {} or -static void h() {}. +namespace { +void f() {} +}
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) -The matcher -ompExecutableDirective(hasAnyClause(ompDefaultClause(isNoneKind()))) -matches only #pragma omp parallel default(none). +``ompDefaultClause(isNoneKind())`` matches only ``default(none)``.
Matches if the OpenMP ``default`` clause has ``shared`` kind specified. Given - void foo() { - #pragma omp parallel - ; - #pragma omp parallel default(none) - ; + + #pragma omp parallel + #pragma omp parallel default(none) #pragma omp parallel default(shared) - ; #pragma omp parallel default(private) - ; #pragma omp parallel default(firstprivate) - ; - } - -The matcher -ompExecutableDirective(hasAnyClause(ompDefaultClause(isSharedKind()))) -matches #pragma omp parallel default(shared). +``ompDefaultClause(isSharedKind())`` matches only ``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.
Similar to isDerivedFrom(), but also matches classes that directly -match Base. -Overloaded method as shortcut for +@@ -6964,15 +5124,12 @@ 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
@@ -6980,13 +5137,9 @@ Checks that a call expression or a constructor call expression has at least the specified number of arguments (including absent default arguments). -Given +Example matches f(0, 0) and g(0, 0, 0) +(matcher = callExpr(argumentCountAtLeast(2))) void f(int x, int y); void g(int x, int y, int z); - void foo() { - f(0, 0); - g(0, 0, 0); - } -The matcher callExpr(argumentCountAtLeast(2)) -matches f(0, 0) and g(0, 0, 0) + f(0, 0); + g(0, 0, 0);Narrowing Matchers
@@ -6994,27 +5147,24 @@ Checks that a call expression or a constructor call expression has a specific number of arguments (including absent default arguments). -Given +Example matches f(0, 0) (matcher = callExpr(argumentCountIs(2))) void f(int x, int y); - void foo() { - f(0, 0); - } -The matcher callExpr(argumentCountIs(2)) -matches f(0, 0) + 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 @@ -7029,68 +5179,56 @@ Matches when the selector is a keyword selector -Given +objCMessageExpr(hasKeywordSelector()) matches the generated setFrame +message expression in + 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 -Given - [self.bodyView loadHTMLString:html baseURL:NULL]; - - - The matcher objCMessageExpr(matchesSelector(hasUnarySelector()); - matches self.bodyView, but does not match the outer message + matcher = objCMessageExpr(matchesSelector(hasUnarySelector()); + matches self.bodyView in the code below, but NOT the outer message invocation of "loadHTMLString:baseURL:". + [self.bodyView loadHTMLString:html baseURL:NULL];Matcher<ObjCMessageExpr> isClassMessage Returns true when the Objective-C message is sent to a class. -Given +Example +matcher = objcMessageExpr(isClassMessage()) +matches [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. -Given +Example +matcher = objcMessageExpr(isInstanceMessage()) +matches 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 @@ -7159,39 +5285,33 @@ Matches ObjC selectors whose name contains a substring matched by the given RegExp. - -Given + matcher = objCMessageExpr(matchesSelector("loadHTMLStringmatches 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(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" @@ -7100,26 +5238,25 @@Narrowing Matchers
Matcher<ObjCMessageExpr> numSelectorArgs unsigned N Matches when the selector has the specified number of arguments - [self.bodyView loadHTMLString:html baseURL:NULL]; + matcher = objCMessageExpr(numSelectorArgs(0)); + matches self.bodyView in the code below -The matcher objCMessageExpr(numSelectorArgs(0)) -matches self.bodyView. -The matcher objCMessageExpr(numSelectorArgs(2)) -matches the invocation of loadHTMLString:baseURL: -but does not match self.bodyView + matcher = objCMessageExpr(numSelectorArgs(2)); + matches the invocation of "loadHTMLString:baseURL:" but not that + of self.bodyView + [self.bodyView loadHTMLString:html baseURL:NULL];Matcher<ObjCMethodDecl> isClassMethod @@ -7133,14 +5270,6 @@ Returns true when the Objective-C method declaration is a class method. -Given +Example +matcher = objcMethodDecl(isClassMethod()) +matches @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 @@ -7148,9 +5277,6 @@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. -Given +Example +matcher = objcMethodDecl(isInstanceMethod()) +matches @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 @@ -7206,9 +5326,9 @@ Matches a declaration that has default arguments. -Given - void x(int val) {} - void y(int val = 0) {} - - -The matcher parmVarDecl(hasDefaultArgument()) -matches int val = 0. +Example matches y (matcher = parmVarDecl(hasDefaultArgument())) +void x(int val) {} +void y(int val = 0) {} Deprecated. Use hasInitializer() instead to be able to match on the contents of the default argument. For example: -Given - void x(int val = 7) {} - void y(int val = 42) {} - +void x(int val = 7) {} +void y(int val = 42) {} +parmVarDecl(hasInitializer(integerLiteral(equals(42)))) + matches the parameter of y -The matcher -parmVarDecl(hasInitializer(integerLiteral(equals(42)))), -matches int val = 42. +A matcher such as + parmVarDecl(hasInitializer(anything())) +is equivalent to parmVarDecl(hasDefaultArgument()).Narrowing Matchers
void f(int a, int b, int c) { } -The matcher parmVarDecl(isAtPosition(0)) matches -a. The matcher parmVarDecl(isAtPosition(1)) -matches b. +``parmVarDecl(isAtPosition(0))`` matches ``int a``. + +``parmVarDecl(isAtPosition(1))`` matches ``int b``.
Matches AST nodes that were expanded within files whose name is partially matching a given regex. -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. +Example matches Y but not X + (matcher = cxxRecordDecl(isExpansionInFileMatching("AST.*")) + #include "ASTMatcher.h" + class X {}; +ASTMatcher.h: + class Y {}; Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc> @@ -7459,18 +5541,12 @@Narrowing Matchers
Matcher<Stmt> isExpansionInMainFile @@ -7479,17 +5555,12 @@ Matches AST nodes that were expanded within the main-file. -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. +Example matches X but not Y + (matcher = cxxRecordDecl(isExpansionInMainFile()) + #include <Y.h> + class X {}; +Y.h: + class Y {}; Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>Narrowing Matchers
Matcher<Stmt> isExpansionInSystemHeader @@ -7500,18 +5571,14 @@ Matches AST nodes that were expanded within system-header-files. -Given the header SystemHeader.h - #pragma once - int header(); -and the source code +Example matches Y but not X + (matcher = cxxRecordDecl(isExpansionInSystemHeader()) #include <SystemHeader.h> - static int main_file(); - - -The matcher functionDecl(isExpansionInSystemHeader()) -matches int header(), -but does not match static int main_file(). + class X {}; +SystemHeader.h: + class Y {}; Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>Narrowing Matchers
Given int j; - 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. + 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.
Matches TagDecl object that are spelled with "class." -Given +Example matches C, but not S, U or E. struct S {}; class C {}; union U {}; - enum E { Ok }; - -The matcher tagDecl(isClass()) -matches class C, -but does not match struct S, -union U -or enum E. + enum E {};
Matches TagDecl object that are spelled with "enum." -Given +Example matches E, but not C, S or U. struct S {}; class C {}; union U {}; - enum E { Ok }; - -The matcher tagDecl(isEnum()) -matches enum E { Ok }, -but does not match struct S {}, -class C {} or union U {}. + enum E {};
Matches TagDecl object that are spelled with "union." -Given +Example matches U, but not C, S or E. struct S {}; class C {}; union U {}; - enum E { Ok }; - -The matcher tagDecl(isUnion()) -matches union U, -does not match struct S, -class C -or enum E. + enum E {};
Matches AST nodes that were expanded within files whose name is partially matching a given regex. -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. +Example matches Y but not X + (matcher = cxxRecordDecl(isExpansionInFileMatching("AST.*")) + #include "ASTMatcher.h" + class X {}; +ASTMatcher.h: + class Y {}; Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc> @@ -7732,18 +5735,12 @@Narrowing Matchers
Matcher<TypeLoc> isExpansionInMainFile @@ -7752,17 +5749,12 @@ Matches AST nodes that were expanded within the main-file. -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. +Example matches X but not Y + (matcher = cxxRecordDecl(isExpansionInMainFile()) + #include <Y.h> + class X {}; +Y.h: + class Y {}; Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>Narrowing Matchers
Matcher<TypeLoc> isExpansionInSystemHeader @@ -7773,9 +5765,8 @@ Matches AST nodes that were expanded within system-header-files. -Given the header SystemHeader.h - #pragma once - int header(); -and the source code +Example matches Y but not X + (matcher = cxxRecordDecl(isExpansionInSystemHeader()) #include <SystemHeader.h> - static int main_file(); - - -The matcher functionDecl(isExpansionInSystemHeader()) -matches int header(), -but does not match static int main_file(). + class X {}; +SystemHeader.h: + class Y {}; Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>Narrowing Matchers
Given struct S { bool func(); }; - -The matcher functionDecl(returns(booleanType())) -func +functionDecl(returns(booleanType())) + matches "bool 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 - 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). + Is equivalent to + anyOf(hasOperatorName("+"), hasOperatorName("-"))
Matches the operator Name of operator expressions and fold expressions (binary or unary). -Given -void foo(bool a, bool b) { - !(a || b); - } - -The matcher binaryOperator(hasOperatorName("||")) -matches a || b +Example matches a || b (matcher = binaryOperator(hasOperatorName("||"))) + !(a || b) -Given +Example matches `(0 + ... + args)` + (matcher = cxxFoldExpr(hasOperatorName("+"))) 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. -Given +Example matches x, but not y, z, or a. +(matcher = varDecl(hasAutomaticStorageDuration()) 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. -Given +Example matches y and z (matcher = varDecl(hasGlobalStorage()) 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. -Given +Example matches x (matcher = varDecl(hasLocalStorage()) void f() { int x; static int y; } int z; -The matcher varDecl(hasLocalStorage()) -matches x
Matches a variable declaration that has thread storage duration. -Given +Example matches z, but not x, z, or a. +(matcher = varDecl(hasThreadStorageDuration()) 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) {} } - -The matcher varDecl(isConstexpr()) -matches foo. -The matcher functionDecl(isConstexpr()) -matches bar. -The matcher ifStmt(isConstexpr()) -matches 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.
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; - -The matcher varDecl(isConstinit()) -matches the declaration of foo -and bar, -but does not match baz or -xyz. +varDecl(isConstinit()) + matches the declaration of `foo` and `bar`, but not `baz` and `xyz`.
Matches a variable declaration that is an exception variable from a C++ catch block, or an Objective-C statement. -Given +Example matches x (matcher = varDecl(isExceptionVariable()) 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; - -The matcher functionDecl(isExternC()) -matches f -and g. -The matcher varDecl(isExternC()) -matches x -and y, -but does not match z. +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.
Matches a variable serving as the implicit variable for a lambda init- capture. -Given -auto f = [x = 3]() { return x; }; - -The matcher varDecl(isInitCapture()) -matches x = 3. +Example matches x (matcher = varDecl(isInitCapture())) +auto f = [x=3]() { return x; };
Matches a static variable with local scope. -Given +Example matches y (matcher = varDecl(isStaticLocal())) 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; -The matcher functionDecl(isStaticStorageClass()) - matches f -The matcher varDecl(isStaticStorageClass()) - matches i +functionDecl(isStaticStorageClass()) + matches the function declaration f. +varDecl(isStaticStorageClass()) + matches the variable declaration i.
Matches nodes which can be used with binary operators. -A comparison of two expressions might be represented in the clang AST as a -binaryOperator, a cxxOperatorCallExpr or a -cxxRewrittenBinaryOperator, depending on +The code + var1 != var2; +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) @@ -8278,6 +6168,12 @@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; }; @@ -8291,28 +6187,25 @@AST Traversal Matchers
template<typename T> void templ() { - 3 != 4; + 1 != 2; T() != S(); } struct HasOpEq { - friend bool - operator==(const HasOpEq &, const HasOpEq&) noexcept = default; + bool operator==(const HasOpEq &) const; }; void inverse() { - HasOpEq e1; - HasOpEq e2; - if (e1 != e2) + HasOpEq s1; + HasOpEq s2; + if (s1 != s2) return; } struct HasSpaceship { - friend bool - operator<=>(const HasSpaceship &, - const HasSpaceship&) noexcept = default; + bool operator<=>(const HasOpEq &) const; }; void use_spaceship() @@ -8322,15 +6215,6 @@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. -Given +Example matches X, A, A::X, B, B::C, B::C::X + (matcher = cxxRecordDecl(forEachDescendant(cxxRecordDecl(hasName("X"))))) 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: - 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. + 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 {}; }; }; }; }; Usable as: Any Matcher
Matches AST nodes that have child AST nodes that match the provided matcher. -Given +Example matches X, Y, Y::X, Z::Y, Z::Y::X + (matcher = cxxRecordDecl(forEach(cxxRecordDecl(hasName("X"))) 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. -Given +Example matches X, Y, Z + (matcher = cxxRecordDecl(hasDescendant(cxxRecordDecl(hasName("X"))))) 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 @@ -8516,29 +6333,19 @@AST Traversal Matchers
@@ -8548,9 +6355,7 @@ Matches AST nodes that have child AST nodes that match the provided matcher. -Given +Example matches X, Y + (matcher = cxxRecordDecl(has(cxxRecordDecl(hasName("X"))) 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: - -Given - int x =0; - double y = static_cast<double>(x); - -The matcher -cxxStaticCastExpr(has(ignoringParenImpCasts(declRefExpr()))). -matches static_cast<double>(x) +probably consider using ignoringParenImpCasts like: +has(ignoringParenImpCasts(expr())).AST Traversal Matchers
Given void f() { for (;;) { int x = 42; if (true) { int x = 43; } } } - -The matcher compoundStmt(hasParent(ifStmt())) -matches { int x = 43; } +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. -Given -void foo() { +Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true)))) 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 -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. + condition ? a : b Example 2 (conditional binary operator): matches opaqueValueExpr(condition) -Given - void foo(bool condition, int a, int b) { - condition ?: b; - } - -The matcher binaryConditionalOperator(hasTrueExpression(expr())) -matches condition ?: b, -with expr() matching conditoin. + condition ?: b
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 @@ -8699,25 +6477,17 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -Given +For type nodes, hasDeclaration will generally match the declaration of the +sugared type. Given class X {}; typedef X Y; Y y; - -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. +in varDecl(hasType(hasDeclaration(decl()))) the decl will match the +typedefDecl. 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().bind("d")))))) -matches Y y. -In this matcher, the matcher decl() will match the -CXXRecordDecl -class X {};. + varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl()))))) +In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -8735,7 +6505,7 @@AST Traversal Matchers
Given int i[5]; void f() { i[1] = 42; } -The matcher arraySubscriptExpr(hasBase(implicitCastExpr( +arraySubscriptExpression(hasBase(implicitCastExpr( hasSourceExpression(declRefExpr())))) matches i[1] with the declRefExpr() matching i
Matches the left hand side of binary operator expressions. -Given -void foo(bool a, bool b) { - a || b; -} - -The matcher binaryOperator(hasLHS(expr().bind("lhs"))) -matches a || b, -with expr() -matching a. +Example matches a (matcher = binaryOperator(hasLHS())) + a || b
Matches the right hand side of binary operator expressions. -Given -void foo(bool a, bool b) { - a || b; -} - -The matcher binaryOperator(hasRHS(expr().bind("rhs"))) -matches a || b, -with expr() -matching b. +Example matches b (matcher = binaryOperator(hasRHS())) + a || 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. -Given -void foo(bool a, bool b) { - a || b; -} - -The matcher binaryOperator(hasLHS(expr().bind("lhs"))) -matches a || b, -with expr() -matching a. +Example matches a (matcher = binaryOperator(hasLHS())) + a || b
Matches if both matchers match with opposite sides of the binary operator or fold expression. -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. +Example matcher = binaryOperator(hasOperands(integerLiteral(equals(1), + integerLiteral(equals(2))) + 1 + 2 // Match + 2 + 1 // Match + 1 + 1 // No match + 2 + 2 // No match
Matches the right hand side of binary operator expressions. - -Given -void foo(bool a, bool b) { - a || b; -} ++ Matcher<BinaryOperator> hasRHS Matcher<Expr> InnerMatcher Matches the right hand side of binary operator expressions. -The matcher binaryOperator(hasRHS(expr().bind("rhs"))) -matches a || b, -with expr() -matching b. +Example matches b (matcher = binaryOperator(hasRHS())) + a || bMatcher<BindingDecl> forDecomposition Matcher<ValueDecl> InnerMatcher @@ -8947,26 +6653,23 @@ Matches the DecompositionDecl the binding belongs to. -Given +For example, in: void foo() { int arr[3]; @@ -8932,10 +6638,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]'.AST Traversal Matchers
Given class X { void f(int x, int y, int z) {} }; - -The matcher cxxMethodDecl(hasAnyParameter(hasName("y"))) - matches f +cxxMethodDecl(hasAnyParameter(hasName("y"))) + matches f(int x, int y, int z) {} with hasAnyParameter(...) matching int y For ObjectiveC, given @interface I - (void) f:(int) y; @end - the matcher objcMethodDecl(hasAnyParameter(hasName("y"))) - matches the declaration of method f with hasParameter +matches the declaration of method f with hasParameter matching y. For blocks, given b = ^(int y) { printf("%d", y) }; - the matcher blockDecl(hasAnyParameter(hasName("y"))) - matches the declaration of the block b with hasParameter +matches the declaration of the block b with hasParameter matching y.
Matches if the type location of a node matches the inner matcher. -Given +Examples: 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); +declaratorDecl(hasTypeLoc(loc(asString("int")))) + matches int x -The matcher -cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point")))) -matches point(1.0, -1.0). +auto x = int(3); +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) + matches int(3) -Given struct Foo { Foo(int, int); }; -Foo x = Foo(1, 2); - -The matcher cxxTemporaryObjectExpr(hasTypeLoc( - loc(asString("Foo")))) -matches Foo(1, 2). +auto x = Foo(1, 2); +cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) + matches Foo(1, 2) Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, @@ -9035,14 +6728,10 @@AST Traversal Matchers
Given int *a; - 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 *. + int const *b; + float const *f; +pointerType(pointee(isConstQualified(), isInteger())) + matches "int const *b" Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>, Matcher<PointerType>, Matcher<ReferenceType> @@ -9052,26 +6741,19 @@AST Traversal Matchers
Matcher<CXXBaseSpecifier> hasTypeLoc Matcher<TypeLoc> Inner @@ -9128,25 +6800,17 @@ Matches if the type location of a node matches the inner matcher. -Given +Examples: 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); +declaratorDecl(hasTypeLoc(loc(asString("int")))) + matches int x -The matcher -cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point")))) -matches point(1.0, -1.0). +auto x = int(3); +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) + matches int(3) -Given struct Foo { Foo(int, int); }; -Foo x = Foo(1, 2); - -The matcher cxxTemporaryObjectExpr(hasTypeLoc( - loc(asString("Foo")))) -matches Foo(1, 2). +auto x = Foo(1, 2); +cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) + matches Foo(1, 2) Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, @@ -9094,31 +6776,21 @@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 {}; -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 +Example matches class Derived +(matcher = cxxRecordDecl(hasAnyBase(hasType(cxxRecordDecl(hasName("Base")))))) 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>AST Traversal Matchers
@@ -9156,10 +6820,8 @@ Matches if the expression's or declaration's type matches a type matcher. -Exmaple +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"))) 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.AST Traversal Matchers
Given void f(int i); int y; - void foo() { - f(y); - } -The matcher callExpr( + f(y); +callExpr( forEachArgumentWithParam( declRefExpr(to(varDecl(hasName("y")))), parmVarDecl(hasType(isInteger())) @@ -9182,15 +6844,14 @@AST Traversal Matchers
Given void f(int i); - void foo(int y) { - f(y); - void (*f_ptr)(int) = f; - f_ptr(y); - } -The matcher callExpr( + int y; + f(y); + void (*f_ptr)(int) = f; + f_ptr(y); +callExpr( forEachArgumentWithParamType( declRefExpr(to(varDecl(hasName("y")))), - qualType(isInteger()).bind("type") + qualType(isInteger()).bind("type) )) matches f(y) and f_ptr(y) with declRefExpr(...) @@ -9205,19 +6866,17 @@AST Traversal Matchers
expression, or an ObjC-message-send expression. Given - 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(...) + void x(int, int, int) { int y; x(1, y, 42); } +callExpr(hasAnyArgument(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. -Given +Example matches y in x(y) + (matcher = callExpr(hasArgument(0, declRefExpr()))) 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 @@ -9245,25 +6902,17 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -Given +For type nodes, hasDeclaration will generally match the declaration of the +sugared type. Given class X {}; typedef X Y; Y y; - -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. +in varDecl(hasType(hasDeclaration(decl()))) the decl will match the +typedefDecl. 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().bind("d")))))) -matches Y y. -In this matcher, the matcher decl() will match the -CXXRecordDecl -class X {};. + varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl()))))) +In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -9280,12 +6929,10 @@AST Traversal Matchers
Given class A { A() : i(42), j(42) {} int i; int j; }; - -The matcher cxxConstructorDecl(forEachConstructorInitializer( - forField(fieldDecl().bind("x")))) -matches the constructor of A twice, with -fieldDecl() matching i and -j respectively. +cxxConstructorDecl(forEachConstructorInitializer( + forField(decl().bind("x")) +)) + will trigger two matches, binding for 'i' and 'j' respectively.
Matches if the type location of a node matches the inner matcher. -Given +Examples: 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); +declaratorDecl(hasTypeLoc(loc(asString("int")))) + matches int x -The matcher -cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point")))) -matches point(1.0, -1.0). +auto x = int(3); +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) + matches int(3) -Given struct Foo { Foo(int, int); }; -Foo x = Foo(1, 2); - -The matcher cxxTemporaryObjectExpr(hasTypeLoc( - loc(asString("Foo")))) -matches Foo(1, 2). +auto x = Foo(1, 2); +cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) + matches Foo(1, 2) Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, @@ -9365,11 +7002,9 @@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. -Given +Example matches `(0 + ... + args)` and `(args * ... * 1)` + (matcher = cxxFoldExpr(hasFoldInit(expr()))) + with hasFoldInit(...) + matching `0` and `1` respectively template <typename... Args> auto sum(Args... args) { return (0 + ... + args); @@ -9483,27 +7082,14 @@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. -Given -void foo(bool a, bool b) { - a || b; -} - -The matcher binaryOperator(hasLHS(expr().bind("lhs"))) -matches a || b, -with expr() -matching a. +Example matches a (matcher = binaryOperator(hasLHS())) + a || b
Matches if both matchers match with opposite sides of the binary operator or fold expression. -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. +Example matcher = binaryOperator(hasOperands(integerLiteral(equals(1), + integerLiteral(equals(2))) + 1 + 2 // Match + 2 + 1 // Match + 1 + 1 // No match + 2 + 2 // No match
Matches the operand that contains the parameter pack. -Given +Example matches `(0 + ... + args)` + (matcher = cxxFoldExpr(hasPattern(expr()))) + with hasPattern(...) + matching `args` template <typename... Args> auto sum(Args... args) { return (0 + ... + args); @@ -9539,27 +7122,14 @@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. -Given -void foo(bool a, bool b) { - a || b; -} - -The matcher binaryOperator(hasRHS(expr().bind("rhs"))) -matches a || b, -with expr() -matching b. +Example matches b (matcher = binaryOperator(hasRHS())) + a || b
Matches selection statements with initializer. -Given - struct vec { int* begin(); int* end(); }; - int foobar(); - vec& get_range(); +Given: void foo() { if (int i = foobar(); i > 0) {} switch (int i = foobar(); i) {} @@ -9606,71 +7171,51 @@AST Traversal Matchers
switch (foobar()) {} for (auto& x : get_range()) {} } - -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. +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.
Matches the initialization statement of a for loop. -Given - void foo() { - int a[42] = {}; +Example: + forStmt(hasLoopVariable(anything())) +matches 'int x' in for (int x : a) { } - } - -The matcher cxxForRangeStmt(hasLoopVariable(anything())) -matches for (int x : a) { }
Matches the range initialization statement of a for loop. -Given - void foo() { - int a[42] = {}; +Example: + forStmt(hasRangeInit(anything())) +matches 'a' in 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. -Given +Examples: 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); +declaratorDecl(hasTypeLoc(loc(asString("int")))) + matches int x -The matcher -cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point")))) -matches point(1.0, -1.0). +auto x = int(3); +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) + matches int(3) -Given struct Foo { Foo(int, int); }; -Foo x = Foo(1, 2); - -The matcher cxxTemporaryObjectExpr(hasTypeLoc( - loc(asString("Foo")))) -matches Foo(1, 2). +auto x = Foo(1, 2); +cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) + matches Foo(1, 2) Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, @@ -9690,16 +7235,13 @@AST Traversal Matchers
Given class Y { public: void m(); }; Y g(); - class X : public Y { public: void g(); }; + class X : public Y { void g(); }; void z(Y y, X x) { y.m(); x.m(); x.g(); (g()).m(); } - -The matcher cxxMemberCallExpr(onImplicitObjectArgument(hasType( +cxxMemberCallExpr(onImplicitObjectArgument(hasType( cxxRecordDecl(hasName("Y"))))) -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`) + matches `y.m()`, `x.m()` and (`g()).m()`, but not `x.g()`). +cxxMemberCallExpr(on(callExpr())) + only matches `(g()).m()` (the parens are ignored). 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() 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(). + 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()`.
Matches any placement new expression arguments. -Given - void* operator new(decltype(sizeof(void*)), void*); - struct MyClass { int x; }; - unsigned char Storage[sizeof(MyClass) * 10]; +Given: MyClass *p1 = new (Storage) MyClass(); - - -The matcher cxxNewExpr(hasAnyPlacementArg(anything())) -matches new (Storage) MyClass(). +cxxNewExpr(hasAnyPlacementArg(anything())) + matches the expression 'new (Storage, 16) MyClass()'.
Matches array new expressions with a given array size. -Given - void* operator new(decltype(sizeof(void*))); - struct MyClass { int x; }; +Given: MyClass *p1 = new MyClass[10]; - - -The matcher -cxxNewExpr(hasArraySize( - ignoringImplicit(integerLiteral(equals(10))))) -matches new MyClass[10]. +cxxNewExpr(hasArraySize(integerLiteral(equals(10)))) + matches the expression '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 @@ -9857,25 +7365,17 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -Given +For type nodes, hasDeclaration will generally match the declaration of the +sugared type. Given class X {}; typedef X Y; Y y; - -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. +in varDecl(hasType(hasDeclaration(decl()))) the decl will match the +typedefDecl. 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().bind("d")))))) -matches Y y. -In this matcher, the matcher decl() will match the -CXXRecordDecl -class X {};. + varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl()))))) +In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -9890,42 +7390,29 @@AST Traversal Matchers
Matcher<CXXNewExpr> hasPlacementArg unsigned Index, Matcher<Expr> InnerMatcher Matches placement new expression arguments. -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(). +Given: + MyClass *p1 = new (Storage, 16) MyClass(); +cxxNewExpr(hasPlacementArg(1, integerLiteral(equals(16)))) + matches the expression 'new (Storage, 16) MyClass()'.Matcher<CXXNewExpr> hasTypeLoc Matcher<TypeLoc> Inner @@ -10121,90 +7545,38 @@ Matches if the type location of a node matches the inner matcher. -Given +Examples: 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); +declaratorDecl(hasTypeLoc(loc(asString("int")))) + matches int x -The matcher -cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point")))) -matches point(1.0, -1.0). +auto x = int(3); +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) + matches int(3) -Given struct Foo { Foo(int, int); }; -Foo x = Foo(1, 2); - -The matcher cxxTemporaryObjectExpr(hasTypeLoc( - loc(asString("Foo")))) -matches Foo(1, 2). +auto x = Foo(1, 2); +cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) + matches Foo(1, 2) Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, @@ -9941,45 +7428,14 @@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 @@ -9987,64 +7443,44 @@ Matches the left hand side of binary operator expressions. -Given -void foo(bool a, bool b) { - a || b; -} - -The matcher binaryOperator(hasLHS(expr().bind("lhs"))) -matches a || b, -with expr() -matching a. +Example matches a (matcher = binaryOperator(hasLHS())) + a || bAST Traversal Matchers
Matches if both matchers match with opposite sides of the binary operator or fold expression. -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. +Example matcher = binaryOperator(hasOperands(integerLiteral(equals(1), + integerLiteral(equals(2))) + 1 + 2 // Match + 2 + 1 // Match + 1 + 1 // No match + 2 + 2 // No matchMatcher<CXXOperatorCallExpr> hasRHS Matcher<Expr> InnerMatcher Matches the right hand side of binary operator expressions. -Given -void foo(bool a, bool b) { - a || b; -} - -The matcher binaryOperator(hasRHS(expr().bind("rhs"))) -matches a || b, -with expr() -matching b. +Example matches b (matcher = binaryOperator(hasRHS())) + a || bMatcher<CXXOperatorCallExpr> hasUnaryOperand Matcher<Expr> InnerMatcher Matches if the operand of a unary operator matches. -void foo() { - !true; -} - -The matcher -unaryOperator(hasUnaryOperand(cxxBoolLiteral(equals(true)))) -matches !true. +Example matches true (matcher = hasUnaryOperand( + cxxBoolLiteral(equals(true)))) + !trueMatcher<CXXRecordDecl> hasAnyBase Matcher<CXXBaseSpecifier> BaseSpecMatcher @@ -10052,31 +7488,26 @@ Matches C++ classes that have a direct or indirect base matching BaseSpecMatcher. -Given - class Foo {}; +Example: +matcher hasAnyBase(hasType(cxxRecordDecl(hasName("SpecialBase")))) + 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. -Given - class Foo {}; +Example: +matcher hasDirectBase(hasType(cxxRecordDecl(hasName("SpecialBase")))) + 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 @@ -10088,29 +7519,22 @@ Matches the first method of a class or struct that satisfies InnerMatcher. -Given +Given: class A { void func(); }; class B { void member(); }; - -The matcher cxxRecordDecl(hasMethod(hasName("func"))) -matches the declaration of class A { void func(); } -but does not match class B { void member(); } +cxxRecordDecl(hasMethod(hasName("func"))) matches the declaration of +A but not B.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 - 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("X")): + class Foo; + typedef Foo X; + class Bar : public Foo {}; // derived from a type that X is a typedef of 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. -Given - class X {}; +Example matches Y, 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 -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. -Given -void foo(bool a, bool b) { - a || b; -} - -The matcher binaryOperator(hasLHS(expr().bind("lhs"))) -matches a || b, -with expr() -matching a. +Example matches a (matcher = binaryOperator(hasLHS())) + a || b
Matches if both matchers match with opposite sides of the binary operator or fold expression. -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. +Example matcher = binaryOperator(hasOperands(integerLiteral(equals(1), + integerLiteral(equals(2))) + 1 + 2 // Match + 2 + 1 // Match + 1 + 1 // No match + 2 + 2 // No match
Matches the right hand side of binary operator expressions. -Given -void foo(bool a, bool b) { - a || b; -} - -The matcher binaryOperator(hasRHS(expr().bind("rhs"))) -matches a || b, -with expr() -matching b. +Example matches b (matcher = binaryOperator(hasRHS())) + a || b
Matches if the type location of a node matches the inner matcher. -Given +Examples: 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); +declaratorDecl(hasTypeLoc(loc(asString("int")))) + matches int x -The matcher -cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point")))) -matches point(1.0, -1.0). +auto x = int(3); +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) + matches int(3) -Given struct Foo { Foo(int, int); }; -Foo x = Foo(1, 2); - -The matcher cxxTemporaryObjectExpr(hasTypeLoc( - loc(asString("Foo")))) -matches Foo(1, 2). +auto x = Foo(1, 2); +cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) + matches Foo(1, 2) Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, @@ -10282,19 +7634,17 @@AST Traversal Matchers
expression, or an ObjC-message-send expression. Given - 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(...) + void x(int, int, int) { int y; x(1, y, 42); } +callExpr(hasAnyArgument(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. -Given +Example matches y in x(y) + (matcher = callExpr(hasArgument(0, declRefExpr()))) 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. -Given +Examples: 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); +declaratorDecl(hasTypeLoc(loc(asString("int")))) + matches int x -The matcher -cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point")))) -matches point(1.0, -1.0). +auto x = int(3); +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) + matches int(3) -Given struct Foo { Foo(int, int); }; -Foo x = Foo(1, 2); - -The matcher cxxTemporaryObjectExpr(hasTypeLoc( - loc(asString("Foo")))) -matches Foo(1, 2). +auto x = Foo(1, 2); +cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) + matches Foo(1, 2) Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, @@ -10350,23 +7691,19 @@AST Traversal Matchers
given matcher; or 2) if the Obj-C message expression's callee's method declaration matches the given matcher. -Example 1 +Example matches y.x() (matcher = callExpr(callee( + cxxMethodDecl(hasName("x"))))) class Y { public: void x(); }; void z() { Y y; y.x(); } -The matcher callExpr(callee(cxxMethodDecl(hasName("x")))) -matches y.x() +Example 2. Matches [I foo] with +objcMessageExpr(callee(objcMethodDecl(hasName("foo")))) -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. -Given +Example matches y in x(y) + (matcher = callExpr(hasArgument(0, declRefExpr()))) 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 @@ -10510,25 +7828,17 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -Given +For type nodes, hasDeclaration will generally match the declaration of the +sugared type. Given class X {}; typedef X Y; Y y; - -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. +in varDecl(hasType(hasDeclaration(decl()))) the decl will match the +typedefDecl. 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().bind("d")))))) -matches Y y. -In this matcher, the matcher decl() will match the -CXXRecordDecl -class X {};. + varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl()))))) +In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -10545,12 +7855,9 @@AST Traversal Matchers
extension, matches the constant given in the statement. Given - 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. + switch (1) { case 1: case 1+1: case 3 ... 4: ; } +caseStmt(hasCaseConstant(integerLiteral())) + matches "case 1:"
Matches if the cast's source expression or opaque value's source expression matches the given matcher. -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 1: matches "a string" +(matcher = castExpr(hasSourceExpression(cxxConstructExpr()))) +class URL { URL(string); }; +URL url = "a string"; -The matcher -opaqueValueExpr(hasSourceExpression( - implicitCastExpr(has( - implicitCastExpr(has(declRefExpr())))))) -matches b twice, for the conditiona and the true expression. +Example 2: matches 'b' (matcher = +opaqueValueExpr(hasSourceExpression(implicitCastExpr(declRefExpr()))) +int a = b ?: 1;
Matches the specialized template of a specialization declaration. Given - 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 {}. + 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.
Matches if the type location of a node matches the inner matcher. -Given +Examples: 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); +declaratorDecl(hasTypeLoc(loc(asString("int")))) + matches int x -The matcher -cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point")))) -matches point(1.0, -1.0). +auto x = int(3); +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) + matches int(3) -Given struct Foo { Foo(int, int); }; -Foo x = Foo(1, 2); - -The matcher cxxTemporaryObjectExpr(hasTypeLoc( - loc(asString("Foo")))) -matches Foo(1, 2). +auto x = Foo(1, 2); +cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) + matches Foo(1, 2) Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, @@ -10770,12 +8035,11 @@AST Traversal Matchers
a given matcher. Also matches StmtExprs that have CompoundStmt as children. Given -void foo() { { {}; 1+2; } } -The matcher -compoundStmt(hasAnySubstatement(compoundStmt().bind("compound"))) -{ {}; 1+2; } and { { {}; 1+2; } } + { {}; 1+2; } +hasAnySubstatement(compoundStmt()) + matches '{ {}; 1+2; }' with compoundStmt() -matching {} and { {}; 1+2; }. + matching '{}'
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 @@ -10847,25 +8099,17 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -Given +For type nodes, hasDeclaration will generally match the declaration of the +sugared type. Given class X {}; typedef X Y; Y y; - -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. +in varDecl(hasType(hasDeclaration(decl()))) the decl will match the +typedefDecl. 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().bind("d")))))) -matches Y y. -In this matcher, the matcher decl() will match the -CXXRecordDecl -class X {};. + varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl()))))) +In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -10886,12 +8130,9 @@AST Traversal Matchers
template<typename T, typename U> class A {}; A<double, int> b; 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}. +varDecl(hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(0, + hasTypeLoc(loc(asString("double"))))))) + matches `A<double, int> b`, but not `A<int, double> c`.
Matches if a node refers to a declaration through a specific using shadow declaration. -Given +Examples: namespace a { int f(); } using a::f; int x = f(); - -The matcher declRefExpr(throughUsingDecl(anything())) -matches f +declRefExpr(throughUsingDecl(anything())) + matches f namespace a { class X{}; } using a::X; X x; - -The matcher typeLoc(loc(usingType(throughUsingDecl(anything())))) -matches X +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. -Given - void foo() { - bool x; - if (x) {} - } - -The matcher declRefExpr(to(varDecl(hasName("x")))) -matches x inside the condition of the if-stmt. +Example matches x in if(x) + (matcher = declRefExpr(to(varDecl(hasName("x"))))) + bool x; + if (x) {}
Matches the Decl of a DeclStmt which has a single declaration. Given - void foo() { - int a, b; - int c; - } -The matcher declStmt(hasSingleDecl(anything())) -matches int c; -but does not match int a, b; + int a, b; + int c; +declStmt(hasSingleDecl(anything())) + matches 'int c;' but not 'int a, b;'.
Matches if the type location of a node matches the inner matcher. -Given +Examples: 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); +declaratorDecl(hasTypeLoc(loc(asString("int")))) + matches int x -The matcher -cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point")))) -matches point(1.0, -1.0). +auto x = int(3); +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) + matches int(3) -Given struct Foo { Foo(int, int); }; -Foo x = Foo(1, 2); - -The matcher cxxTemporaryObjectExpr(hasTypeLoc( - loc(asString("Foo")))) -matches Foo(1, 2). +auto x = Foo(1, 2); +cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) + matches Foo(1, 2) Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, @@ -11015,9 +8237,8 @@AST Traversal Matchers
} } - -The matcher cxxRecordDecl(hasDeclContext(namedDecl(hasName("M")))) - matches the declaration of D. +cxxRcordDecl(hasDeclContext(namedDecl(hasName("M")))) matches the +declaration of class D.
Matches the Nth binding of a DecompositionDecl. -Given +For example, in: void foo() { int arr[3]; @@ -11066,10 +8283,10 @@AST Traversal Matchers
f = 42; } - -The matcher decompositionDecl(hasBinding(0, - bindingDecl(hasName("f")).bind("fBinding"))) -matches auto &[f, s, t] = arr with 'f' bound to "fBinding". +The matcher: + decompositionDecl(hasBinding(0, + bindingDecl(hasName("f").bind("fBinding")))) +matches the decomposition decl with 'f' bound to "fBinding".
Matches the condition expression of an if statement, for loop, switch statement or conditional operator. -Given -void foo() { +Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true)))) 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 { @@ -11143,11 +8351,8 @@AST Traversal Matchers
} N::M::D d; - -The matcher -elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N"))))) - matches the type N::M::D of the variable declaration - of d. +elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))) +matches the type 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 @@ -11180,25 +8385,17 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -Given +For type nodes, hasDeclaration will generally match the declaration of the +sugared type. Given class X {}; typedef X Y; Y y; - -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. +in varDecl(hasType(hasDeclaration(decl()))) the decl will match the +typedefDecl. 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().bind("d")))))) -matches Y y. -In this matcher, the matcher decl() will match the -CXXRecordDecl -class X {};. + varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl()))))) +In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -11215,37 +8412,25 @@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. -Given +Examples: 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); +declaratorDecl(hasTypeLoc(loc(asString("int")))) + matches int x -The matcher -cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point")))) -matches point(1.0, -1.0). +auto x = int(3); +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) + matches int(3) -Given struct Foo { Foo(int, int); }; -Foo x = Foo(1, 2); - -The matcher cxxTemporaryObjectExpr(hasTypeLoc( - loc(asString("Foo")))) -matches Foo(1, 2). +auto x = Foo(1, 2); +cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) + matches Foo(1, 2) Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, @@ -11268,31 +8453,21 @@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 {}; -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 +Example matches class Derived +(matcher = cxxRecordDecl(hasAnyBase(hasType(cxxRecordDecl(hasName("Base")))))) 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. -Exmaple +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"))) 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. -Given -void foo() { +Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true)))) if (true) {} -} - -The matcher ifStmt(hasCondition(cxxBoolLiteral(equals(true)))) -if (true) {}
Matches the increment statement of a for loop. -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) { } +Example: + forStmt(hasIncrement(unaryOperator(hasOperatorName("++")))) +matches '++x' in + for (x; x < N; ++x) { }
Matches the initialization statement of a for loop. -Given -void foo(int N) { +Example: + forStmt(hasLoopInit(declStmt())) +matches 'int x = 0' in 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. -Exmaple +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"))) 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; } }; - -The matcher cxxMethodDecl(returns(asString("int"))) - matches f +cxxMethodDecl(returns(asString("int"))) + matches int f() { return 1; }
Matches the condition expression of an if statement, for loop, switch statement or conditional operator. -Given -void foo() { +Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true)))) 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()) {} -} - -The matcher ifStmt(hasConditionVariableStatement(declStmt())) -if (A* a = GetAPointer()) {} +hasConditionVariableStatement(...) + matches 'A* a = GetAPointer()'.
Matches the else-statement of an if statement. -Given -void foo() { +Examples matches the if statement + (matcher = ifStmt(hasElse(cxxBoolLiteral(equals(true))))) if (false) false; else true; -} - -The matcher ifStmt(hasElse(cxxBoolLiteral(equals(true)))) -if (false) false; else true
Matches selection statements with initializer. -Given - struct vec { int* begin(); int* end(); }; - int foobar(); - vec& get_range(); +Given: void foo() { if (int i = foobar(); i > 0) {} switch (int i = foobar(); i) {} @@ -11964,77 +9004,48 @@AST Traversal Matchers
switch (foobar()) {} for (auto& x : get_range()) {} } - -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. +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.
Matches the then-statement of an if statement. -Given -void foo() { +Examples matches the if statement + (matcher = ifStmt(hasThen(cxxBoolLiteral(equals(true))))) 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. -Given - int y = 42; - int x{y}; - -The matcher initListExpr(hasInit(0, expr())) -matches {y}. +Example matches y. + (matcher = initListExpr(hasInit(0, expr()))) + int x{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 @@ -12044,25 +9055,17 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -Given +For type nodes, hasDeclaration will generally match the declaration of the +sugared type. Given class X {}; typedef X Y; Y y; - -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. +in varDecl(hasType(hasDeclaration(decl()))) the decl will match the +typedefDecl. 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().bind("d")))))) -matches Y y. -In this matcher, the matcher decl() will match the -CXXRecordDecl -class X {};. + varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl()))))) +In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -12076,7 +9079,7 @@AST Traversal Matchers
Matcher<LabelStmt> hasDeclaration Matcher<Decl> InnerMatcher @@ -12142,18 +9133,13 @@ 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 @@ -12086,25 +9089,17 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -Given +For type nodes, hasDeclaration will generally match the declaration of the +sugared type. Given class X {}; typedef X Y; Y y; - -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. +in varDecl(hasType(hasDeclaration(decl()))) the decl will match the +typedefDecl. 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().bind("d")))))) -matches Y y. -In this matcher, the matcher decl() will match the -CXXRecordDecl -class X {};. + varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl()))))) +In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -12127,13 +9122,9 @@AST Traversal Matchers
auto f = [x](){}; auto g = [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. +In the matcher +lambdaExpr(hasAnyCapture(lambdaCapture(capturesVar(hasName("x")))), +capturesVar(hasName("x")) matches `x` and `x = 1`.AST Traversal Matchers
Given int main() { - int x; - int y; + int x, y; float z; auto f = [=]() { return x + y + z; }; } - -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. +lambdaExpr(forEachLambdaCapture( + lambdaCapture(capturesVar(varDecl(hasType(isInteger())))))) +will trigger two matches, binding for 'x' and 'y' respectively.
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 @@ -12184,25 +9169,17 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -Given +For type nodes, hasDeclaration will generally match the declaration of the +sugared type. Given class X {}; typedef X Y; Y y; - -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. +in varDecl(hasType(hasDeclaration(decl()))) the decl will match the +typedefDecl. 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().bind("d")))))) -matches Y y. -In this matcher, the matcher decl() will match the -CXXRecordDecl -class X {};. + varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl()))))) +In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -12224,14 +9201,11 @@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, -The matcher memberExpr(hasObjectExpression(hasType(pointsTo( -cxxRecordDecl(hasName("X")))))) -matches m (aka. this->m), but not x.m. + matches `x.m`, but not `m`; however, +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. - -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. ++ Matcher<NestedNameSpecifierLoc> loc Matcher<NestedNameSpecifier> InnerMatcher @@ -12323,10 +9276,9 @@ Matches NestedNameSpecifierLocs for which the given inner +NestedNameSpecifier-matcher matches.AST Traversal Matchers
Given struct A { struct B { struct C {}; }; }; A::B::C c; - -The matcher nestedNameSpecifierLoc(specifiesTypeLoc(loc(qualType( +nestedNameSpecifierLoc(specifiesTypeLoc(loc(type( 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) - ; - } - -The matcher ompExecutableDirective(hasAnyClause(anything())) -matches #pragma omp parallel default(none). +``ompExecutableDirective(hasAnyClause(anything()))`` matches +``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. -Given +Example matches y in x(y) + (matcher = callExpr(hasArgument(0, declRefExpr()))) 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. -Given +For example the method call in NSString *x = @"hello"; [x containsString:@"h"]; - -The matcher +is matched by 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. -Given +Examples: 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); +declaratorDecl(hasTypeLoc(loc(asString("int")))) + matches int x -The matcher -cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point")))) -matches point(1.0, -1.0). +auto x = int(3); +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) + matches int(3) -Given struct Foo { Foo(int, int); }; -Foo x = Foo(1, 2); - -The matcher cxxTemporaryObjectExpr(hasTypeLoc( - loc(asString("Foo")))) -matches Foo(1, 2). +auto x = Foo(1, 2); +cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) + matches Foo(1, 2) Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, @@ -12673,23 +9559,14 @@AST Traversal Matchers
@@ -12704,11 +9581,9 @@ Matches if the cast's source expression or opaque value's source expression matches the given matcher. -Given - struct URL { URL(const char*); }; - URL url = "a string"; - -The matcher castExpr(hasSourceExpression(cxxConstructExpr())) -matches "a string". +Example 1: matches "a string" +(matcher = castExpr(hasSourceExpression(cxxConstructExpr()))) +class URL { URL(string); }; +URL url = "a string"; -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. +Example 2: matches 'b' (matcher = +opaqueValueExpr(hasSourceExpression(implicitCastExpr(declRefExpr()))) +int a = b ?: 1;AST Traversal Matchers
foo(t); bar(t); } - -The matcher unresolvedLookupExpr(hasAnyDeclaration( +unresolvedLookupExpr(hasAnyDeclaration( functionTemplateDecl(hasName("foo")))) -matches foo in foo(t); -but does not match bar in bar(t); + matches foo in foo(t); but not bar in bar(t);
Matches QualTypes whose canonical type matches InnerMatcher. -Given +Given: typedef int &int_ref; int a; int_ref b = a; -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. +varDecl(hasType(qualType(referenceType()))))) will not match the +declaration of b but varDecl(hasType(qualType(hasCanonicalType(referenceType())))))) does.
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 @@ -12787,25 +9653,17 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -Given +For type nodes, hasDeclaration will generally match the declaration of the +sugared type. Given class X {}; typedef X Y; Y y; - -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. +in varDecl(hasType(hasDeclaration(decl()))) the decl will match the +typedefDecl. 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().bind("d")))))) -matches Y y. -In this matcher, the matcher decl() will match the -CXXRecordDecl -class X {};. + varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl()))))) +In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -12823,56 +9681,30 @@AST Traversal Matchers
Given void (*fp)(void); The matcher -varDecl(hasType(pointerType(pointee(ignoringParens(functionType()))))) -matches fp. + varDecl(hasType(pointerType(pointee(ignoringParens(functionType()))))) +would match the declaration for fp.
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() + Overloaded to match the pointee type's declaration.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. -Given +Example matches y->x() + (matcher = cxxMemberCallExpr(on(hasType(pointsTo + cxxRecordDecl(hasName("Y"))))))) 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; + const int y; +qualifiedTypeLoc(hasUnqualifiedLoc(pointerTypeLoc())) + matches the `TypeLoc` of the variable declaration of `x`, but not `y`. + 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. +@@ -12880,17 +9712,14 @@ Overloaded to match the referenced type's declaration.AST Traversal Matchers
@@ -12899,18 +9728,16 @@ Matches if the matched type is a reference type and the referenced type matches the specified matcher. -Given +Example matches X &x and const X &y + (matcher = varDecl(hasType(references(cxxRecordDecl(hasName("X")))))) 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 = nullptr; - const int y = 0; - - -The matcher qualifiedTypeLoc(hasUnqualifiedLoc(pointerTypeLoc())) -matches the type int* of the variable declaration but -not
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 @@ -12920,25 +9747,17 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -Given +For type nodes, hasDeclaration will generally match the declaration of the +sugared type. Given class X {}; typedef X Y; Y y; - -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. +in varDecl(hasType(hasDeclaration(decl()))) the decl will match the +typedefDecl. 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().bind("d")))))) -matches Y y. -In this matcher, the matcher decl() will match the -CXXRecordDecl -class X {};. + varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl()))))) +In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -12957,10 +9776,8 @@AST Traversal Matchers
Given int x = 3; int& xx = x; - - -The matcher referenceTypeLoc(hasReferentLoc(loc(asString("int")))) - matches int&. +referenceTypeLoc(hasReferentLoc(loc(asString("int")))) + matches `int&`.
Matches the return value expression of a return statement Given - 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. + return a + b; +hasReturnValue(binaryOperator()) + 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 -struct F { - F& operator=(const F& other) { - []() { return 42 == 42; }; - return *this; - } -}; - -The matcher returnStmt(forFunction(hasName("operator="))) -matches return *this -but does not match return 42 == 42. +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 -void foo { +Given: +-(void) foo { int x = 1; dispatch_sync(queue, ^{ int y = 2; }); } - -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. +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'.
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. -Given -void foo() { +Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true)))) if (true) {} -} - -The matcher ifStmt(hasCondition(cxxBoolLiteral(equals(true)))) -if (true) {}
Matches selection statements with initializer. -Given - struct vec { int* begin(); int* end(); }; - int foobar(); - vec& get_range(); +Given: void foo() { if (int i = foobar(); i > 0) {} switch (int i = foobar(); i) {} @@ -13159,23 +9930,18 @@AST Traversal Matchers
switch (foobar()) {} for (auto& x : get_range()) {} } - -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. +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.
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 @@ -13185,25 +9951,17 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -Given +For type nodes, hasDeclaration will generally match the declaration of the +sugared type. Given class X {}; typedef X Y; Y y; - -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. +in varDecl(hasType(hasDeclaration(decl()))) the decl will match the +typedefDecl. 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().bind("d")))))) -matches Y y. -In this matcher, the matcher decl() will match the -CXXRecordDecl -class X {};. + varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl()))))) +In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -13218,26 +9976,19 @@AST Traversal Matchers
Matcher<TemplateArgumentLoc> hasTypeLoc Matcher<TypeLoc> Inner @@ -13275,13 +10023,10 @@ Matches if the type location of a node matches the inner matcher. -Given +Examples: 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); +declaratorDecl(hasTypeLoc(loc(asString("int")))) + matches int x -The matcher -cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point")))) -matches point(1.0, -1.0). +auto x = int(3); +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) + matches int(3) -Given struct Foo { Foo(int, int); }; -Foo x = Foo(1, 2); - -The matcher cxxTemporaryObjectExpr(hasTypeLoc( - loc(asString("Foo")))) -matches Foo(1, 2). +auto x = Foo(1, 2); +cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) + matches Foo(1, 2) Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, @@ -13257,13 +10008,10 @@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")).bind("next"))))))) -matches the specialization A<&struct B::next> -with fieldDecl(hasName("next")) matching -B::next. + isExpr(hasDescendant(declRefExpr(to(fieldDecl(hasName("next")))))))) + matches the specialization A<&B::next> with fieldDecl(...) matching + B::nextAST 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")).bind("next")))) -matches the specialization struct A<&B::next> -with fieldDecl(hasName("next")) matching -B::next. + refersToDeclaration(fieldDecl(hasName("next"))))) + matches the specialization A<&B::next> with fieldDecl(...) 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 @@ -13438,25 +10158,17 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -Given +For type nodes, hasDeclaration will generally match the declaration of the +sugared type. Given class X {}; typedef X Y; Y y; - -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. +in varDecl(hasType(hasDeclaration(decl()))) the decl will match the +typedefDecl. 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().bind("d")))))) -matches Y y. -In this matcher, the matcher decl() will match the -CXXRecordDecl -class X {};. + varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl()))))) +In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -13475,26 +10187,23 @@AST Traversal Matchers
Given template<typename T, typename U> class A {}; - A<double, int> b; - A<int, double> c; + A<bool, int> b; + A<int, bool> c; template<typename T> void f() {} void func() { f<int>(); }; - -The matcher classTemplateSpecializationDecl(hasTemplateArgument( 1, refersToType(asString("int")))) -matches the specialization class A<double, int>. + matches the specialization A<bool, int> -The matcher functionDecl(hasTemplateArgument(0, - refersToType(asString("int")))) -matches the specialization of f. +functionDecl(hasTemplateArgument(0, refersToType(asString("int")))) + matches the specialization f<int>
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 @@ -13504,25 +10213,17 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -Given +For type nodes, hasDeclaration will generally match the declaration of the +sugared type. Given class X {}; typedef X Y; Y y; - -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. +in varDecl(hasType(hasDeclaration(decl()))) the decl will match the +typedefDecl. 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().bind("d")))))) -matches Y y. -In this matcher, the matcher decl() will match the -CXXRecordDecl -class X {};. + varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl()))))) +In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -13537,37 +10238,25 @@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. -Given +Examples: 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); +declaratorDecl(hasTypeLoc(loc(asString("int")))) + matches int x -The matcher -cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point")))) -matches point(1.0, -1.0). +auto x = int(3); +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) + matches int(3) -Given struct Foo { Foo(int, int); }; -Foo x = Foo(1, 2); - -The matcher cxxTemporaryObjectExpr(hasTypeLoc( - loc(asString("Foo")))) -matches Foo(1, 2). +auto x = Foo(1, 2); +cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) + matches Foo(1, 2) Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, @@ -13584,31 +10273,23 @@AST Traversal Matchers
Matches if the expression's or declaration's type matches a type matcher. -Exmaple +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"))) 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 @@ -13668,23 +10338,17 @@ 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 @@ -13618,25 +10299,17 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -Given +For type nodes, hasDeclaration will generally match the declaration of the +sugared type. Given class X {}; typedef X Y; Y y; - -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. +in varDecl(hasType(hasDeclaration(decl()))) the decl will match the +typedefDecl. 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().bind("d")))))) -matches Y y. -In this matcher, the matcher decl() will match the -CXXRecordDecl -class X {};. + varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl()))))) +In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -13655,11 +10328,8 @@AST Traversal Matchers
For example, in: class A {}; using B = A; - B b; - -The matcher -varDecl(hasType(hasUnqualifiedDesugaredType(recordType()))) -matches B b. +The matcher type(hasUnqualifiedDesugaredType(recordType())) matches +both B and A.AST Traversal Matchers
Given int a, c; float b; int s = sizeof(a) + sizeof(b) + alignof(c); - -The matcher -unaryExprOrTypeTraitExpr(hasArgumentOfType(asString("int"))) -matches sizeof(a) and alignof(c) +unaryExprOrTypeTraitExpr(hasArgumentOfType(asString("int")) + matches sizeof(a) and alignof(c)Matcher<UnaryOperator> hasUnaryOperand Matcher<Expr> InnerMatcher @@ -13698,20 +10362,17 @@ Matches if the operand of a unary operator matches. -void foo() { - !true; -} - -The matcher -unaryOperator(hasUnaryOperand(cxxBoolLiteral(equals(true)))) -matches !true. +Example matches true (matcher = hasUnaryOperand( + cxxBoolLiteral(equals(true)))) + !trueAST 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, -The matcher memberExpr(hasObjectExpression(hasType(pointsTo( -cxxRecordDecl(hasName("X")))))) -matches m (aka. this->m), but not x.m. + matches `x.m`, but not `m`; however, +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 @@ -13721,25 +10382,17 @@AST Traversal Matchers
- for CXXNewExpr, the declaration of the operator new - for ObjCIvarExpr, the declaration of the ivar -Given +For type nodes, hasDeclaration will generally match the declaration of the +sugared type. Given class X {}; typedef X Y; Y y; - -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. +in varDecl(hasType(hasDeclaration(decl()))) the decl will match the +typedefDecl. 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().bind("d")))))) -matches Y y. -In this matcher, the matcher decl() will match the -CXXRecordDecl -class X {};. + varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl()))))) +In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>, @@ -13759,12 +10412,8 @@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 X::a} -
Matches if a node refers to a declaration through a specific using shadow declaration. -Given +Examples: namespace a { int f(); } using a::f; int x = f(); - -The matcher declRefExpr(throughUsingDecl(anything())) -matches f +declRefExpr(throughUsingDecl(anything())) + matches f namespace a { class X{}; } using a::X; X x; - -The matcher typeLoc(loc(usingType(throughUsingDecl(anything())))) -matches X +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. -Exmaple +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"))) 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. -Given - int y() { return 0; } - void foo() { - int x = y(); - } -The matcher varDecl(hasInitializer(callExpr())) -matches x +Example matches x (matcher = varDecl(hasInitializer(callExpr()))) + bool y() { return true; } + bool x = y();
Matches the condition expression of an if statement, for loop, switch statement or conditional operator. -Given -void foo() { +Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true)))) 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
@@ -312,13 +160,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.
///
-/// Given
+/// Example: \c DeclarationMatcher(anything()) matches all declarations, e.g.,
/// \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(); }
@@ -327,13 +175,12 @@ inline internal::TrueMatcher anything() { return internal::TrueMatcher(); }
/// Given
/// \code
/// int X;
-/// namespace NS { int Y; }
+/// namespace NS {
+/// int Y;
+/// } // namespace NS
/// \endcode
-/// \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 .
+/// decl(hasDeclContext(translationUnitDecl()))
+/// matches "int X", but not "int Y".
extern const internal::VariadicDynCastAllOfMatcher
translationUnitDecl;
@@ -344,10 +191,8 @@ extern const internal::VariadicDynCastAllOfMatcher
/// typedef int X;
/// using Y = int;
/// \endcode
-/// \compile_args{-std=c++}
-/// The matcher \matcher{typedefDecl()}
-/// matches \match{typedef int X},
-/// but does not match \nomatch{using Y = int}.
+/// typedefDecl()
+/// matches "typedef int X", but not "using Y = int"
extern const internal::VariadicDynCastAllOfMatcher
typedefDecl;
@@ -358,9 +203,8 @@ extern const internal::VariadicDynCastAllOfMatcher
/// typedef int X;
/// using Y = int;
/// \endcode
-/// \compile_args{-std=c++11-or-later}
-/// The matcher \matcher{typedefNameDecl()}
-/// matches \match{typedef int X} and \match{using Y = int}.
+/// typedefNameDecl()
+/// matches "typedef int X" and "using Y = int"
extern const internal::VariadicDynCastAllOfMatcher
typedefNameDecl;
@@ -371,44 +215,33 @@ extern const internal::VariadicDynCastAllOfMatcher
/// typedef int X;
/// using Y = int;
/// \endcode
-/// \compile_args{-std=c++11-or-later}
-/// The matcher \matcher{typeAliasDecl()}
-/// matches \match{using Y = int},
-/// but does not match \nomatch{typedef int X}.
+/// typeAliasDecl()
+/// matches "using Y = int", but not "typedef int X"
extern const internal::VariadicDynCastAllOfMatcher
typeAliasDecl;
/// Matches type alias template declarations.
///
-/// Given
+/// typeAliasTemplateDecl() matches
/// \code
-/// template struct X {};
-/// template using Y = 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.
///
-/// Given the header \c Y.h
-/// \header{Y.h}
-/// #pragma once
-/// typedef int my_header_int;
-/// \endheader
-/// and the source file
+/// Example matches X but not Y
+/// (matcher = cxxRecordDecl(isExpansionInMainFile())
/// \code
-/// #include "Y.h"
-/// typedef int my_main_file_int;
-/// my_main_file_int a = 0;
-/// my_header_int b = 1;
+/// #include
+/// class X {};
+/// \endcode
+/// Y.h:
+/// \code
+/// class Y {};
/// \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,
@@ -420,21 +253,16 @@ AST_POLYMORPHIC_MATCHER(isExpansionInMainFile,
/// Matches AST nodes that were expanded within system-header-files.
///
-/// Given the header \c SystemHeader.h
-/// \header{system_include/SystemHeader.h}
-/// #pragma once
-/// int header();
-/// \endheader
-/// and the source code
+/// Example matches Y but not X
+/// (matcher = cxxRecordDecl(isExpansionInSystemHeader())
/// \code
/// #include
-/// static int main_file();
+/// class X {};
+/// \endcode
+/// SystemHeader.h:
+/// \code
+/// class Y {};
/// \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,
@@ -450,31 +278,16 @@ AST_POLYMORPHIC_MATCHER(isExpansionInSystemHeader,
/// Matches AST nodes that were expanded within files whose name is
/// partially matching a given regex.
///
-/// 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;
+/// Example matches Y but not X
+/// (matcher = cxxRecordDecl(isExpansionInFileMatching("AST.*"))
+/// \code
+/// #include "ASTMatcher.h"
+/// class X {};
+/// \endcode
+/// ASTMatcher.h:
+/// \code
+/// class Y {};
/// \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,
@@ -500,17 +313,6 @@ 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) {
@@ -528,50 +330,35 @@ AST_POLYMORPHIC_MATCHER_P(isExpandedFromMacro,
/// Matches declarations.
///
-/// Given
+/// Examples matches \c X, \c C, and the friend declaration inside \c C;
/// \code
/// void X();
/// class C {
-/// friend void X();
+/// friend 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.
///
-/// Given
+/// Examples matches the declaration node with \c foo and \c bar, but not
+/// \c number.
+/// (matcher = declStmt(has(decompositionDecl())))
+///
/// \code
-/// struct pair { int x; int y; };
-/// pair make(int, int);
/// int number = 42;
-/// auto [foo, bar] = make(42, 42);
+/// auto [foo, bar] = std::make_pair{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
-/// struct pair { int x; int y; };
-/// pair make(int, int);
-/// void f() {
-/// auto [foo, bar] = make(42, 42);
-/// }
+/// auto [foo, bar] = std::make_pair{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;
@@ -581,41 +368,33 @@ extern const internal::VariadicDynCastAllOfMatcher
/// \code
/// extern "C" {}
/// \endcode
-/// \compile_args{-std=c++}
-/// The matcher \matcher{linkageSpecDecl()}
-/// matches \match{extern "C" {}}.
+/// linkageSpecDecl()
+/// matches "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
-/// 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.
+/// struct S {
+/// union {
+/// int i;
+/// } U;
+/// };
+/// \endcode
extern const internal::VariadicDynCastAllOfMatcher namedDecl;
/// Matches a declaration of label.
///
/// Given
/// \code
-/// void bar();
-/// void foo() {
-/// goto FOO;
-/// FOO: bar();
-/// }
+/// goto FOO;
+/// FOO: bar();
/// \endcode
-/// The matcher \matcher{type=none$labelDecl()}
-/// matches \match{FOO: bar()}.
+/// labelDecl()
+/// matches 'FOO:'
extern const internal::VariadicDynCastAllOfMatcher labelDecl;
/// Matches a declaration of a namespace.
@@ -625,9 +404,8 @@ extern const internal::VariadicDynCastAllOfMatcher labelDecl;
/// namespace {}
/// namespace test {}
/// \endcode
-/// \compile_args{-std=c++}
-/// The matcher \matcher{namespaceDecl()}
-/// matches \match{namespace {}} and \match{namespace test {}}.
+/// namespaceDecl()
+/// matches "namespace {}" and "namespace test {}"
extern const internal::VariadicDynCastAllOfMatcher
namespaceDecl;
@@ -638,53 +416,38 @@ extern const internal::VariadicDynCastAllOfMatcher
/// namespace test {}
/// namespace alias = ::test;
/// \endcode
-/// \compile_args{-std=c++}
-/// The matcher \matcher{namespaceAliasDecl()}
-/// matches \match{namespace alias = ::test},
-/// but does not match \nomatch{namespace test {}}.
+/// namespaceAliasDecl()
+/// matches "namespace alias" but not "namespace test"
extern const internal::VariadicDynCastAllOfMatcher
namespaceAliasDecl;
/// Matches class, struct, and union declarations.
///
-/// Given
+/// Example matches \c X, \c Z, \c U, and \c S
/// \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.
///
-/// Given
+/// Example matches \c X, \c Z
/// \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.
///
-/// Given
+/// Example matches \c Z
/// \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;
@@ -696,10 +459,8 @@ extern const internal::VariadicDynCastAllOfMatcher
/// template<> class A {};
/// A a;
/// \endcode
-/// \compile_args{-fno-delayed-template-parsing;-std=c++}
-/// The matcher \matcher{classTemplateSpecializationDecl()}
-/// matches \match{type=typestr$class A}
-/// and \match{type=typestr$class A}.
+/// classTemplateSpecializationDecl()
+/// matches the specializations \c A and \c A
extern const internal::VariadicDynCastAllOfMatcher<
Decl, ClassTemplateSpecializationDecl>
classTemplateSpecializationDecl;
@@ -711,15 +472,14 @@ extern const internal::VariadicDynCastAllOfMatcher<
/// template
/// class A {};
///
-/// template class A {};
+/// template
+/// class A {};
///
/// template<>
/// class A {};
/// \endcode
-/// \compile_args{-fno-delayed-template-parsing;-std=c++}
-/// The matcher \matcher{classTemplatePartialSpecializationDecl()}
-/// matches \match{template class A {}},
-/// but does not match \nomatch{A}.
+/// classTemplatePartialSpecializationDecl()
+/// matches the specialization \c A but not \c A
extern const internal::VariadicDynCastAllOfMatcher<
Decl, ClassTemplatePartialSpecializationDecl>
classTemplatePartialSpecializationDecl;
@@ -731,9 +491,8 @@ extern const internal::VariadicDynCastAllOfMatcher<
/// \code
/// class X { int y; };
/// \endcode
-/// \compile_args{-std=c++}
-/// The matcher \matcher{declaratorDecl()}
-/// matches \match{int y}.
+/// declaratorDecl()
+/// matches \c int y.
extern const internal::VariadicDynCastAllOfMatcher
declaratorDecl;
@@ -743,8 +502,8 @@ extern const internal::VariadicDynCastAllOfMatcher
/// \code
/// void f(int x);
/// \endcode
-/// The matcher \matcher{parmVarDecl()}
-/// matches \match{int x}.
+/// parmVarDecl()
+/// matches \c int x.
extern const internal::VariadicDynCastAllOfMatcher
parmVarDecl;
@@ -757,36 +516,29 @@ extern const internal::VariadicDynCastAllOfMatcher
/// int a;
/// };
/// \endcode
-/// \compile_args{-std=c++}
-/// The matcher \matcher{accessSpecDecl()}
-/// matches \match{public:}.
+/// accessSpecDecl()
+/// matches 'public:'
extern const internal::VariadicDynCastAllOfMatcher
accessSpecDecl;
/// Matches class bases.
///
-/// Given
+/// Examples matches \c public virtual B.
/// \code
/// class B {};
-/// class C : public B {};
+/// class C : public virtual 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.
///
-/// Given
+/// Examples matches \c i(42).
/// \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;
@@ -797,10 +549,8 @@ extern const internal::VariadicAllOfMatcher
/// template struct C {};
/// C c;
/// \endcode
-/// \compile_args{-fno-delayed-template-parsing;-std=c++}
-/// The matcher
-/// \matcher{templateSpecializationType(hasAnyTemplateArgument(templateArgument()))}
-/// matches \match{type=typestr$C}.
+/// templateArgument()
+/// matches 'int' in C.
extern const internal::VariadicAllOfMatcher templateArgument;
/// Matches template arguments (with location info).
@@ -810,9 +560,8 @@ extern const internal::VariadicAllOfMatcher templateArgument;
/// template struct C {};
/// C c;
/// \endcode
-/// \compile_args{-fno-delayed-template-parsing;-std=c++}
-/// The matcher \matcher{templateArgumentLoc()}
-/// matches \match{int} in C.
+/// templateArgumentLoc()
+/// matches 'int' in C.
extern const internal::VariadicAllOfMatcher
templateArgumentLoc;
@@ -820,15 +569,11 @@ extern const internal::VariadicAllOfMatcher
///
/// Given
/// \code
-/// template class S> class X {};
-/// template class Y {};
-/// X xi;
+/// template class X { };
+/// X xi;
/// \endcode
-/// \compile_args{-fno-delayed-template-parsing;-std=c++}
-/// The matcher
-/// \matcher{classTemplateSpecializationDecl(hasAnyTemplateArgument(
-/// refersToTemplate(templateName())))}
-/// matches the specialization \match{type=typestr$class X}
+/// templateName()
+/// matches 'X' in X.
extern const internal::VariadicAllOfMatcher templateName;
/// Matches non-type template parameter declarations.
@@ -837,10 +582,8 @@ extern const internal::VariadicAllOfMatcher templateName;
/// \code
/// template struct C {};
/// \endcode
-/// \compile_args{-fno-delayed-template-parsing;-std=c++}
-/// The matcher \matcher{nonTypeTemplateParmDecl()}
-/// matches \match{int N},
-/// but does not match \nomatch{typename T}.
+/// nonTypeTemplateParmDecl()
+/// matches 'N', but not 'T'.
extern const internal::VariadicDynCastAllOfMatcher
nonTypeTemplateParmDecl;
@@ -851,10 +594,8 @@ extern const internal::VariadicDynCastAllOfMatcher struct C {};
/// \endcode
-/// \compile_args{-fno-delayed-template-parsing;-std=c++}
-/// The matcher \matcher{templateTypeParmDecl()}
-/// matches \match{typename T},
-/// but does not \nomatch{int N}.
+/// templateTypeParmDecl()
+/// matches 'T', but not 'N'.
extern const internal::VariadicDynCastAllOfMatcher
templateTypeParmDecl;
@@ -864,10 +605,8 @@ extern const internal::VariadicDynCastAllOfMatcher
/// \code
/// template class Z, int N> struct C {};
/// \endcode
-/// \compile_args{-fno-delayed-template-parsing;-std=c++}
-/// The matcher \matcher{templateTemplateParmDecl()}
-/// matches \match{template class Z},
-/// but does not match \nomatch{int N}.
+/// templateTypeParmDecl()
+/// matches 'Z', but not 'N'.
extern const internal::VariadicDynCastAllOfMatcher
templateTemplateParmDecl;
@@ -875,31 +614,20 @@ extern const internal::VariadicDynCastAllOfMatchergetASTContext()) == Width;
@@ -1015,14 +722,10 @@ AST_MATCHER_P(FieldDecl, hasBitWidth, unsigned, Width) {
/// int c;
/// };
/// \endcode
-/// \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}.
+/// 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;'.
AST_MATCHER_P(FieldDecl, hasInClassInitializer, internal::Matcher,
InnerMatcher) {
const Expr *Initializer = Node.getInClassInitializer();
@@ -1032,29 +735,20 @@ AST_MATCHER_P(FieldDecl, hasInClassInitializer, internal::Matcher,
/// Determines whether the function is "main", which is the entry point
/// into an executable program.
-///
-/// Given
-/// \code
-/// void f();
-/// int main() {}
-/// \endcode
-///
-/// The matcher \matcher{functionDecl(isMain())} matches \match{int main() {}}.
-AST_MATCHER(FunctionDecl, isMain) { return Node.isMain(); }
+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
-/// \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 {}}.
+/// classTemplateSpecializationDecl(hasSpecializedTemplate(classTemplateDecl()))
+/// matches '#2' with classTemplateDecl() matching the class template
+/// declaration of 'A' at #1.
AST_MATCHER_P(ClassTemplateSpecializationDecl, hasSpecializedTemplate,
internal::Matcher, InnerMatcher) {
const ClassTemplateDecl* Decl = Node.getSpecializedTemplate();
@@ -1064,22 +758,6 @@ 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)) {
@@ -1096,21 +774,17 @@ AST_POLYMORPHIC_MATCHER(isImplicit,
/// template<> class A {};
/// A a;
///
-/// template void f() {};
+/// template f() {};
/// void func() { f(); };
/// \endcode
-/// \compile_args{-fno-delayed-template-parsing;-std=c++}
///
-/// The matcher \matcher{classTemplateSpecializationDecl(
-/// hasAnyTemplateArgument(
-/// refersToType(asString("int"))))}
-/// matches \match{type=typestr$class A}.
+/// \endcode
+/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
+/// refersToType(asString("int"))))
+/// matches the specialization \c A
///
-/// The matcher
-/// \matcher{functionDecl(hasAnyTemplateArgument(
-/// refersToType(asString("int"))))}
-/// matches the instantiation of
-/// \match{void f() {}}.
+/// functionDecl(hasAnyTemplateArgument(refersToType(asString("int"))))
+/// matches the specialization \c f
AST_POLYMORPHIC_MATCHER_P(
hasAnyTemplateArgument,
AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
@@ -1133,10 +807,12 @@ AST_POLYMORPHIC_MATCHER_P(
/// }
/// \endcode
/// The matcher
-/// \matcher{traverse(TK_IgnoreUnlessSpelledInSource,
+/// \code
+/// traverse(TK_IgnoreUnlessSpelledInSource,
/// varDecl(hasInitializer(floatLiteral().bind("init")))
-/// )}
-/// matches \match{int i = 3.0} with "init" bound to \match{sub=init$3.0}.
+/// )
+/// \endcode
+/// matches the variable declaration with "init" bound to the "3.0".
template
internal::Matcher traverse(TraversalKind TK,
const internal::Matcher &InnerMatcher) {
@@ -1197,37 +873,25 @@ traverse(TraversalKind TK, const internal::MapAnyOfHelper &InnerMatcher) {
/// nodes are stripped off.
///
/// Parentheses and explicit casts are not discarded.
-///
/// Given
/// \code
-/// 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))));
-/// }
+/// class C {};
+/// C a = C();
+/// C b;
+/// C c = b;
/// \endcode
-///
-/// 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) {
+/// The matchers
+/// \code
+/// varDecl(hasInitializer(ignoringImplicit(cxxConstructExpr())))
+/// \endcode
+/// would match the declarations for a, b, and c.
+/// While
+/// \code
+/// varDecl(hasInitializer(cxxConstructExpr()))
+/// \endcode
+/// only match the declarations for b and c.
+AST_MATCHER_P(Expr, ignoringImplicit, internal::Matcher,
+ InnerMatcher) {
return InnerMatcher.matches(*Node.IgnoreImplicit(), Finder, Builder);
}
@@ -1238,32 +902,24 @@ AST_MATCHER_P(Expr, ignoringImplicit, internal::Matcher, InnerMatcher) {
/// Given
/// \code
/// int arr[5];
-/// const int a = 0;
+/// int a = 0;
/// char b = 0;
/// const int c = a;
/// int *d = arr;
/// long e = (long) 0l;
/// \endcode
-/// 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.
+/// 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.
AST_MATCHER_P(Expr, ignoringImpCasts,
internal::Matcher, InnerMatcher) {
return InnerMatcher.matches(*Node.IgnoreImpCasts(), Finder, Builder);
@@ -1280,15 +936,12 @@ AST_MATCHER_P(Expr, ignoringImpCasts,
/// void* c = reinterpret_cast(0);
/// char d = char(0);
/// \endcode
-/// \compile_args{-std=c++}
/// The matcher
-/// \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}.
+/// varDecl(hasInitializer(ignoringParenCasts(integerLiteral())))
+/// would match the declarations for a, b, c, and d.
+/// while
+/// varDecl(hasInitializer(integerLiteral()))
+/// only match the declaration for a.
AST_MATCHER_P(Expr, ignoringParenCasts, internal::Matcher, InnerMatcher) {
return InnerMatcher.matches(*Node.IgnoreParenCasts(), Finder, Builder);
}
@@ -1306,25 +959,14 @@ AST_MATCHER_P(Expr, ignoringParenCasts, internal::Matcher, InnerMatcher) {
/// int *d = (arr);
/// long e = ((long) 0l);
/// \endcode
-/// \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.
+/// 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.
AST_MATCHER_P(Expr, ignoringParenImpCasts,
internal::Matcher, InnerMatcher) {
return InnerMatcher.matches(*Node.IgnoreParenImpCasts(), Finder, Builder);
@@ -1337,8 +979,10 @@ AST_MATCHER_P(Expr, ignoringParenImpCasts,
/// void (*fp)(void);
/// \endcode
/// The matcher
-/// \matcher{varDecl(hasType(pointerType(pointee(ignoringParens(functionType())))))}
-/// matches \match{void (*fp)(void)}.
+/// \code
+/// varDecl(hasType(pointerType(pointee(ignoringParens(functionType())))))
+/// \endcode
+/// would match the declaration for fp.
AST_MATCHER_P_OVERLOAD(QualType, ignoringParens, internal::Matcher,
InnerMatcher, 0) {
return InnerMatcher.matches(Node.IgnoreParens(), Finder, Builder);
@@ -1351,9 +995,10 @@ AST_MATCHER_P_OVERLOAD(QualType, ignoringParens, internal::Matcher,
/// const char* str = ("my-string");
/// \endcode
/// The matcher
-/// \matcher{implicitCastExpr(hasSourceExpression(ignoringParens(stringLiteral())))}
-/// would match the implicit cast resulting from the assignment
-/// \match{("my-string")}.
+/// \code
+/// implicitCastExpr(hasSourceExpression(ignoringParens(stringLiteral())))
+/// \endcode
+/// would match the implicit cast resulting from the assignment.
AST_MATCHER_P_OVERLOAD(Expr, ignoringParens, internal::Matcher,
InnerMatcher, 1) {
const Expr *E = Node.IgnoreParens();
@@ -1370,13 +1015,9 @@ AST_MATCHER_P_OVERLOAD(Expr, ignoringParens, internal::Matcher,
/// sizeof is known.
/// \code
/// template
-/// void f(T x, T y) { sizeof(T() + T()); }
+/// void f(T x, T y) { sizeof(sizeof(T() + T()); }
/// \endcode
-/// \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()}.
+/// expr(isInstantiationDependent()) matches sizeof(sizeof(T() + T())
AST_MATCHER(Expr, isInstantiationDependent) {
return Node.isInstantiationDependent();
}
@@ -1392,9 +1033,7 @@ AST_MATCHER(Expr, isInstantiationDependent) {
/// x + y;
/// }
/// \endcode
-/// \compile_args{-fno-delayed-template-parsing;-std=c++}
-/// The matcher \matcher{expr(isTypeDependent())}
-/// matches \match{x + y} and \match{x}.
+/// expr(isTypeDependent()) matches x + y
AST_MATCHER(Expr, isTypeDependent) { return Node.isTypeDependent(); }
/// Matches expression that are value-dependent because they contain a
@@ -1405,9 +1044,7 @@ AST_MATCHER(Expr, isTypeDependent) { return Node.isTypeDependent(); }
/// \code
/// template int f() { return Size; }
/// \endcode
-/// \compile_args{-fno-delayed-template-parsing;-std=c++}
-/// The matcher \matcher{expr(isValueDependent())}
-/// matches the return value \match{Size}.
+/// expr(isValueDependent()) matches return Size
AST_MATCHER(Expr, isValueDependent) { return Node.isValueDependent(); }
/// Matches templateSpecializationType, class template specializations,
@@ -1417,21 +1054,18 @@ 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
-/// \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}.
+/// classTemplateSpecializationDecl(hasTemplateArgument(
+/// 1, refersToType(asString("int"))))
+/// matches the specialization \c A
///
-/// The matcher \matcher{functionDecl(hasTemplateArgument(0,
-/// refersToType(asString("int"))))}
-/// matches the specialization of \match{void f() {}}.
+/// functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))
+/// matches the specialization \c f
AST_POLYMORPHIC_MATCHER_P2(
hasTemplateArgument,
AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
@@ -1452,10 +1086,8 @@ AST_POLYMORPHIC_MATCHER_P2(
/// template struct C {};
/// C c;
/// \endcode
-/// \compile_args{-fno-delayed-template-parsing;-std=c++}
-/// The matcher
-/// \matcher{classTemplateSpecializationDecl(templateArgumentCountIs(1))}
-/// matches \match{type=typestr$struct C}.
+/// classTemplateSpecializationDecl(templateArgumentCountIs(1))
+/// matches C.
AST_POLYMORPHIC_MATCHER_P(
templateArgumentCountIs,
AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
@@ -1472,11 +1104,9 @@ AST_POLYMORPHIC_MATCHER_P(
/// template struct A {};
/// A a;
/// \endcode
-/// \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}.
+/// classTemplateSpecializationDecl(hasAnyTemplateArgument(refersToType(
+/// recordType(hasDeclaration(recordDecl(hasName("X")))))))
+/// matches the specialization of \c struct A generated by \c A.
AST_MATCHER_P(TemplateArgument, refersToType,
internal::Matcher, InnerMatcher) {
if (Node.getKind() != TemplateArgument::Type)
@@ -1492,11 +1122,9 @@ AST_MATCHER_P(TemplateArgument, refersToType,
/// template class Y {};
/// X xi;
/// \endcode
-/// \compile_args{-fno-delayed-template-parsing;-std=c++}
-/// The matcher
-/// \matcher{classTemplateSpecializationDecl(hasAnyTemplateArgument(
-/// refersToTemplate(templateName())))}
-/// matches the specialization \match{type=typestr$class X}
+/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
+/// refersToTemplate(templateName())))
+/// matches the specialization \c X
AST_MATCHER_P(TemplateArgument, refersToTemplate,
internal::Matcher, InnerMatcher) {
if (Node.getKind() != TemplateArgument::Template)
@@ -1513,13 +1141,10 @@ AST_MATCHER_P(TemplateArgument, refersToTemplate,
/// template struct A {};
/// A<&B::next> a;
/// \endcode
-/// \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}.
+/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
+/// refersToDeclaration(fieldDecl(hasName("next")))))
+/// matches the specialization \c A<&B::next> with \c fieldDecl(...) matching
+/// \c B::next
AST_MATCHER_P(TemplateArgument, refersToDeclaration,
internal::Matcher, InnerMatcher) {
if (Node.getKind() == TemplateArgument::Declaration)
@@ -1535,13 +1160,10 @@ AST_MATCHER_P(TemplateArgument, refersToDeclaration,
/// template struct A {};
/// A<&B::next> a;
/// \endcode
-/// \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}.
+/// templateSpecializationType(hasAnyTemplateArgument(
+/// isExpr(hasDescendant(declRefExpr(to(fieldDecl(hasName("next"))))))))
+/// matches the specialization \c A<&B::next> with \c fieldDecl(...) matching
+/// \c B::next
AST_MATCHER_P(TemplateArgument, isExpr, internal::Matcher, InnerMatcher) {
if (Node.getKind() == TemplateArgument::Expression)
return InnerMatcher.matches(*Node.getAsExpr(), Finder, Builder);
@@ -1555,12 +1177,10 @@ AST_MATCHER_P(TemplateArgument, isExpr, internal::Matcher, InnerMatcher) {
/// template struct C {};
/// C<42> c;
/// \endcode
-/// \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 .
+/// classTemplateSpecializationDecl(
+/// hasAnyTemplateArgument(isIntegral()))
+/// matches the implicit instantiation of C in C<42>
+/// with isIntegral() matching 42.
AST_MATCHER(TemplateArgument, isIntegral) {
return Node.getKind() == TemplateArgument::Integral;
}
@@ -1572,12 +1192,9 @@ AST_MATCHER(TemplateArgument, isIntegral) {
/// template struct C {};
/// C<42> c;
/// \endcode
-/// \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 .
+/// classTemplateSpecializationDecl(
+/// hasAnyTemplateArgument(refersToIntegralType(asString("int"))))
+/// matches the implicit instantiation of C in C<42>.
AST_MATCHER_P(TemplateArgument, refersToIntegralType,
internal::Matcher, InnerMatcher) {
if (Node.getKind() != TemplateArgument::Integral)
@@ -1596,12 +1213,9 @@ AST_MATCHER_P(TemplateArgument, refersToIntegralType,
/// template struct C {};
/// C<42> c;
/// \endcode
-/// \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 .
+/// classTemplateSpecializationDecl(
+/// hasAnyTemplateArgument(equalsIntegralValue("42")))
+/// matches the implicit instantiation of C in C<42>.
AST_MATCHER_P(TemplateArgument, equalsIntegralValue,
std::string, Value) {
if (Node.getKind() != TemplateArgument::Integral)
@@ -1617,28 +1231,23 @@ AST_MATCHER_P(TemplateArgument, equalsIntegralValue,
/// int x = 0;
/// }
/// \endcode
-/// \compile_args{-ObjC}
-/// The matcher \matcher{autoreleasePoolStmt(stmt())} matches the declaration of
-/// \match{int x = 0} inside the autorelease pool.
+/// autoreleasePoolStmt(stmt()) matches the declaration of "x"
+/// inside the autorelease pool.
extern const internal::VariadicDynCastAllOfMatcher autoreleasePoolStmt;
/// Matches any value declaration.
///
-/// Given
+/// Example matches A, B, C and F
/// \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.
///
-/// Given
+/// Example matches Foo::Foo() and Foo::Foo(int)
/// \code
/// class Foo {
/// public:
@@ -1646,134 +1255,93 @@ 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.
///
-/// Given
+/// Example matches Foo::~Foo()
/// \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.
///
-/// Given
+/// Example matches X
/// \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.
///
-/// Given
+/// Example matches A, B, C
/// \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.
///
-/// Given
+/// Example matches X, Z, U, S, E
/// \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.
///
-/// Given
+/// Example matches y
/// \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.
///
-/// Given
+/// Example matches the operator.
/// \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.
///
-/// Given
+/// Example matches the deduction guide.
/// \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.
///
-/// Given
+/// Example matches integral
/// \code
-/// template concept my_concept = true;
+/// template
+/// concept integral = std::is_integral_v;
/// \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;
@@ -1785,29 +1353,17 @@ 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
-/// int a;
-/// struct Foo {
-/// int x;
-/// };
-/// void bar(int val);
+/// class X { int m; };
/// \endcode
-/// \compile_args{-std=c++}
-/// The matcher \matcher{fieldDecl()}
-/// matches \match{int x}.
+/// fieldDecl()
+/// matches 'm'.
extern const internal::VariadicDynCastAllOfMatcher fieldDecl;
/// Matches indirect field declarations.
@@ -1816,20 +1372,17 @@ extern const internal::VariadicDynCastAllOfMatcher fieldDecl;
/// \code
/// struct X { struct { int a; }; };
/// \endcode
-/// The matcher \matcher{indirectFieldDecl()}
-/// matches \match{a}.
+/// indirectFieldDecl()
+/// matches 'a'.
extern const internal::VariadicDynCastAllOfMatcher
indirectFieldDecl;
/// Matches function declarations.
///
-/// Given
+/// Example matches f
/// \code
/// void f();
/// \endcode
-///
-/// The matcher \matcher{functionDecl()}
-/// matches \match{void f()}.
extern const internal::VariadicDynCastAllOfMatcher
functionDecl;
@@ -1839,10 +1392,6 @@ 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;
@@ -1852,32 +1401,28 @@ extern const internal::VariadicDynCastAllOfMatcher
/// \code
/// class X { friend void foo(); };
/// \endcode
-/// \compile_args{-std=c++}
-/// The matcher \matcher{friendDecl()}
-/// matches \match{friend void foo()}.
+/// friendDecl()
+/// matches 'friend void foo()'.
extern const internal::VariadicDynCastAllOfMatcher friendDecl;
/// Matches statements.
///
/// Given
/// \code
-/// void foo(int a) { { ++a; } }
+/// { ++a; }
/// \endcode
-/// The matcher \matcher{stmt()}
-/// matches the function body itself \match{{ { ++a; } }}, the compound
-/// statement \match{{ ++a; }}, the expression \match{++a} and \match{a}.
+/// stmt()
+/// matches both the compound statement '{ ++a; }' and '++a'.
extern const internal::VariadicAllOfMatcher stmt;
/// Matches declaration statements.
///
/// Given
/// \code
-/// void foo() {
-/// int a;
-/// }
+/// int a;
/// \endcode
-/// The matcher \matcher{declStmt()}
-/// matches \match{int a;}.
+/// declStmt()
+/// matches 'int a'.
extern const internal::VariadicDynCastAllOfMatcher declStmt;
/// Matches member expressions.
@@ -1889,9 +1434,8 @@ extern const internal::VariadicDynCastAllOfMatcher declStmt;
/// int a; static int b;
/// };
/// \endcode
-/// \compile_args{-std=c++}
-/// The matcher \matcher{memberExpr()}
-/// matches \match{this->x}, \match{x}, \match{y.x}, \match{a}, \match{this->b}.
+/// memberExpr()
+/// matches this->x, x, y.x, a, this->b
extern const internal::VariadicDynCastAllOfMatcher memberExpr;
/// Matches unresolved member expressions.
@@ -1904,9 +1448,8 @@ extern const internal::VariadicDynCastAllOfMatcher memberExpr;
/// };
/// template void h() { X x; x.f(); x.g(); }
/// \endcode
-/// \compile_args{-fno-delayed-template-parsing;-std=c++}
-/// The matcher \matcher{unresolvedMemberExpr()}
-/// matches \match{x.f}
+/// unresolvedMemberExpr()
+/// matches x.f
extern const internal::VariadicDynCastAllOfMatcher
unresolvedMemberExpr;
@@ -1917,9 +1460,8 @@ extern const internal::VariadicDynCastAllOfMatcher
/// \code
/// template void f() { T t; t.g(); }
/// \endcode
-/// \compile_args{-fno-delayed-template-parsing;-std=c++}
-/// The matcher \matcher{cxxDependentScopeMemberExpr()}
-/// matches \match{t.g}
+/// cxxDependentScopeMemberExpr()
+/// matches t.g
extern const internal::VariadicDynCastAllOfMatcher
cxxDependentScopeMemberExpr;
@@ -1928,22 +1470,15 @@ extern const internal::VariadicDynCastAllOfMatcher callExpr;
/// Matches call expressions which were resolved using ADL.
///
-/// Given
+/// Example matches y(x) but not y(42) or NS::y(x).
/// \code
/// namespace NS {
/// struct X {};
@@ -1959,46 +1494,25 @@ 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.
///
-/// Given
+/// Example matches [&](){return 5;}
/// \code
-/// void f() {
-/// []() { return 5; };
-/// }
+/// [&](){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.
///
-/// Given
+/// Example matches x.y()
/// \code
-/// struct X {
-/// void y();
-/// void m() { y(); }
-/// };
-/// void f();
-/// void g() {
-/// X x;
-/// x.y();
-/// f();
-/// }
+/// X x;
+/// x.y();
/// \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;
@@ -2011,10 +1525,6 @@ 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;
@@ -2024,7 +1534,6 @@ extern const internal::VariadicDynCastAllOfMatcher
/// \code
/// NSString *s = @"abcd";
/// \endcode
-/// \compile_args{-ObjC}
extern const internal::VariadicDynCastAllOfMatcher
objcStringLiteral;
@@ -2035,7 +1544,6 @@ extern const internal::VariadicDynCastAllOfMatcher
/// @interface Foo
/// @end
/// \endcode
-/// \compile_args{-ObjC}
extern const internal::VariadicDynCastAllOfMatcher
objcInterfaceDecl;
@@ -2046,7 +1554,6 @@ extern const internal::VariadicDynCastAllOfMatcher
/// @implementation Foo
/// @end
/// \endcode
-/// \compile_args{-ObjC}
extern const internal::VariadicDynCastAllOfMatcher
objcImplementationDecl;
@@ -2057,7 +1564,6 @@ extern const internal::VariadicDynCastAllOfMatcher
/// @protocol FooDelegate
/// @end
/// \endcode
-/// \compile_args{-ObjC}
extern const internal::VariadicDynCastAllOfMatcher
objcProtocolDecl;
@@ -2068,7 +1574,6 @@ extern const internal::VariadicDynCastAllOfMatcher
/// @interface Foo (Additions)
/// @end
/// \endcode
-/// \compile_args{-ObjC}
extern const internal::VariadicDynCastAllOfMatcher
objcCategoryDecl;
@@ -2079,7 +1584,6 @@ extern const internal::VariadicDynCastAllOfMatcher
/// @implementation Foo (Additions)
/// @end
/// \endcode
-/// \compile_args{-ObjC}
extern const internal::VariadicDynCastAllOfMatcher
objcCategoryImplDecl;
@@ -2095,7 +1599,6 @@ extern const internal::VariadicDynCastAllOfMatcher
/// - (void)method {}
/// @end
/// \endcode
-/// \compile_args{-ObjC}
extern const internal::VariadicDynCastAllOfMatcher
objcMethodDecl;
@@ -2109,7 +1612,6 @@ extern const internal::VariadicDynCastAllOfMatcher
/// printf("%d", p);
/// })
/// \endcode
-/// \compile_args{-ObjC}
extern const internal::VariadicDynCastAllOfMatcher
blockDecl;
@@ -2122,7 +1624,6 @@ extern const internal::VariadicDynCastAllOfMatcher
/// }
/// @end
/// \endcode
-/// \compile_args{-ObjC}
extern const internal::VariadicDynCastAllOfMatcher
objcIvarDecl;
@@ -2134,7 +1635,6 @@ extern const internal::VariadicDynCastAllOfMatcher