diff --git a/third_party/llvm/workspace.bzl b/third_party/llvm/workspace.bzl index 4731757d05f..c624c15b081 100644 --- a/third_party/llvm/workspace.bzl +++ b/third_party/llvm/workspace.bzl @@ -4,8 +4,8 @@ load("//third_party:repo.bzl", "tf_http_archive") def repo(name): """Imports LLVM.""" - LLVM_COMMIT = "6e1acdcdc1b33c8d3cccf09b8d38279eef2ba69e" - LLVM_SHA256 = "6e6514c637a012fa88e9a584772916b6e82799b0ad5a70a0783ecc5db7aca409" + LLVM_COMMIT = "b03a747fc0fc27ddcad3b50f2117d8150ee262f1" + LLVM_SHA256 = "04e54670f439d664d09b91f5fecddee6c9a7198be2305584b6db5e3086835053" tf_http_archive( name = name, diff --git a/third_party/shardy/temporary.patch b/third_party/shardy/temporary.patch index 08949280c9c..9b8fac30243 100644 --- a/third_party/shardy/temporary.patch +++ b/third_party/shardy/temporary.patch @@ -1,26000 +1,15 @@ -diff --git a/third_party/llvm/generated.patch b/third_party/llvm/generated.patch -index 2e8413f..509398d 100644 ---- a/third_party/llvm/generated.patch -+++ b/third_party/llvm/generated.patch -@@ -1,25980 +1 @@ - Auto generated patch. Do not edit or delete it, even if empty. --diff -ruN --strip-trailing-cr a/clang/docs/doxygen.cfg.in b/clang/docs/doxygen.cfg.in ----- a/clang/docs/doxygen.cfg.in --+++ b/clang/docs/doxygen.cfg.in --@@ -220,14 +220,7 @@ -- # "Side Effects:". You can put \n's in the value part of an alias to insert -- # newlines. -- ---ALIASES += compile_args{1}="Compiled with \1.\n" ---ALIASES += matcher{1}="\1" ---ALIASES += matcher{2$}="\2" ---ALIASES += match{1}="\1" ---ALIASES += match{2$}="\2" ---ALIASES += nomatch{1}="\1" ---ALIASES += header{1}="\code" ---ALIASES += endheader="\endcode" --+ALIASES = -- -- # This tag can be used to specify a number of word-keyword mappings (TCL only). -- # A mapping has the form "name=value". For example adding "class=itcl::class" --diff -ruN --strip-trailing-cr a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html ----- a/clang/docs/LibASTMatchersReference.html --+++ b/clang/docs/LibASTMatchersReference.html --@@ -586,36 +586,28 @@ -- -- #pragma omp declare simd -- int min(); --- ---The matcher attr() ---matches nodiscard, nonnull, noinline, and ---declare simd. --+attr() --+ matches "nodiscard", "nonnull", "noinline", and the whole "#pragma" line. -- -- -- --
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 @@ -- 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. ---- -- -- 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 @@ -- @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 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). --
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; } --- }; --- --- ---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; } --+}; --
Matches throw expressions. -- ---void foo() { -- try { throw 5; } catch(int i) {} ---} --- ---The matcher cxxThrowExpr() ---matches throw 5 --+cxxThrowExpr() --+ matches 'throw 5' --
Matches try statements. -- ---void foo() { -- try {} catch(int i) {} ---} --- ---The matcher cxxTryStmt() ---matches try {} catch(int i) {} --+cxxTryStmt() --+ matches 'try {}' --
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). --
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) {} --
Matches declaration statements. -- -- Given --- void foo() { --- int a; --- } ---The matcher declStmt() ---matches int a;. --+ int a; --+declStmt() --+ matches 'int a'. --
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:'. --
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>(). --
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 }; --
Matches do statements. -- -- Given ---void foo() { -- do {} while (true); ---} --- ---The matcher doStmt() ---matches do {} while (true) --+doStmt() --+ matches 'do {} while(true)' --
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 @@ -- 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 @@ -- 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); --- } --+Example matches a || b (matcher = binaryOperator(hasOperatorName("||"))) --+ !(a || b) -- ---The matcher binaryOperator(hasOperatorName("||")) ---matches 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 @@ ---- -- --@@ -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). ---- -- --@@ -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); ---- -- -- 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 @@ -- -- 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 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 }. --
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 @@ -- 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 @@ -- 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 @@ -- 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 @@ -- 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 @@ -- 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); --- } --+Example matches a || b (matcher = binaryOperator(hasOperatorName("||"))) --+ !(a || b) -- ---The matcher binaryOperator(hasOperatorName("||")) ---matches 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 @@ -- 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 @@ -- 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 @@ -- 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 {}. ---- -- --@@ -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("-")) ---- -- -- 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 < s2 ---- -- --@@ -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); ---- -- --@@ -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); ---- -- --@@ -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); ---- -- -- 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 @@ -- 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 @@ -- 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 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 @@ ---- -- --@@ -5468,11 +4061,9 @@ -- child statements. -- -- Example: Given ---void foo() { -- { for (;;) {} } ---} ---The matcher compoundStmt(statementCountIs(0)) ---{} --+compoundStmt(statementCountIs(0))) --+ matches '{}' -- but does not match the outer compound statement. -- 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 @@ -- Given -- template<typename T> struct C {}; -- C<int> c; --- ---The matcher -- classTemplateSpecializationDecl(templateArgumentCountIs(1)) ---matches struct C<int>. --+ matches C<int>. --
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 @@ ---- 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> ---- 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> ---- Matcher<Decl> isImplicit -- -- --@@ -5678,14 +4214,11 @@ -- 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 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 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 @@ -- "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 @@ -- 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 {}. ---- -- --@@ -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); ---- -- --@@ -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); ---- -- -- 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 in ---- 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 @@ ---- 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 @@ -- 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 @@ -- - (void)ma {} -- @end -- ---The matcher objcMethodDecl(isDefinition()) ---matches - (void)ma {} --- -- Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>, -- Matcher<ObjCMethodDecl> -- 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; @end ---- 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 @@ -- 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 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) {} --- --- ---The matcher ---parmVarDecl(hasInitializer(integerLiteral(equals(42)))), ---matches int val = 42. --+void x(int val = 7) {} --+void y(int val = 42) {} --+parmVarDecl(hasInitializer(integerLiteral(equals(42)))) --+ matches the parameter of y --+ --+A matcher such as --+ parmVarDecl(hasInitializer(anything())) --+is equivalent to parmVarDecl(hasDefaultArgument()). --
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 @@ ---- 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> ---- Matcher<Stmt> isExpansionInSystemHeader --@@ -7500,18 +5571,14 @@ -- -- 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 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> --
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 @@ ---- 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> ---- Matcher<TypeLoc> isExpansionInSystemHeader --@@ -7773,9 +5765,8 @@ -- -- Given -- struct S { bool func(); }; --- ---The matcher functionDecl(returns(booleanType())) ---func --+functionDecl(returns(booleanType())) --+ matches "bool func();" -- 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> --
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); --- } --+Example matches a || b (matcher = binaryOperator(hasOperatorName("||"))) --+ !(a || b) -- ---The matcher binaryOperator(hasOperatorName("||")) ---matches 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 @@ -- 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 @@ -- 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 @@ -- 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 @@ ---- -- --@@ -8548,9 +6355,7 @@ -- -- 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 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())). --
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 @@ -- - 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 @@ -- 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; ---} --- ---The matcher binaryOperator(hasRHS(expr().bind("rhs"))) ---matches a || b, ---with expr() ---matching b. --+Example matches b (matcher = binaryOperator(hasRHS())) --+ a || b --
Matches the DecompositionDecl the binding belongs to. -- ---Given --+For example, in: -- void foo() -- { -- int arr[3]; --@@ -8932,10 +6638,10 @@ -- -- f = 42; -- } --- ---The matcher bindingDecl(hasName("f"), --- forDecomposition(decompositionDecl())) ---matches f in 'auto &[f, s, t]'. --+The matcher: --+ bindingDecl(hasName("f"), --+ forDecomposition(decompositionDecl()) --+matches 'f' in 'auto &[f, s, t]'. --
Matches if the type location of a node matches the inner matcher. -- ---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 @@ -- -- 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 @@ ---- 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 @@ -- 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> ---- -- --@@ -9156,10 +6820,8 @@ -- 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 @@ -- -- 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 @@ -- 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 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 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 @@ -- - 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 @@ -- -- 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. --+declaratorDecl(hasTypeLoc(loc(asString("int")))) --+ matches int x -- ---Given ---struct point { point(double, double); }; ---point p = point(1.0, -1.0); --+auto x = int(3); --+cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) --+ matches int(3) -- ---The matcher ---cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point")))) ---matches point(1.0, -1.0). --- ---Given -- struct Foo { Foo(int, int); }; ---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 @@ -- 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 @@ -- 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 @@ -- 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 @@ -- 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. --+declaratorDecl(hasTypeLoc(loc(asString("int")))) --+ matches int x -- ---Given ---struct point { point(double, double); }; ---point p = point(1.0, -1.0); --+auto x = int(3); --+cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) --+ matches int(3) -- ---The matcher ---cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point")))) ---matches point(1.0, -1.0). --- ---Given -- struct Foo { Foo(int, int); }; ---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 @@ -- 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 @@ -- - 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 @@ ---- 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 @@ -- -- 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 -- 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. --+declaratorDecl(hasTypeLoc(loc(asString("int")))) --+ matches int x -- ---Given ---struct point { point(double, double); }; ---point p = point(1.0, -1.0); --+auto x = int(3); --+cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) --+ matches int(3) -- ---The matcher ---cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point")))) ---matches point(1.0, -1.0). --- ---Given -- struct Foo { Foo(int, int); }; ---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 @@ ---- 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 || 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 ---- Matcher<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 || b ---- Matcher<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)))) --+ !true ---- Matcher<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. ---- 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 Proxy ---- Matcher<CXXRecordDecl> hasMethod Matcher<CXXMethodDecl> InnerMatcher -- -- --@@ -10088,29 +7519,22 @@ -- 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> -- 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. --
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. --+declaratorDecl(hasTypeLoc(loc(asString("int")))) --+ matches int x -- ---Given ---struct point { point(double, double); }; ---point p = point(1.0, -1.0); --- ---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 @@ -- 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 @@ -- 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 @@ -- - 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 @@ -- 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; ---} --- ---The matcher ---opaqueValueExpr(hasSourceExpression( --- implicitCastExpr(has( --- implicitCastExpr(has(declRefExpr())))))) ---matches b twice, for the conditiona and the true expression. --+Example 1: matches "a string" --+(matcher = castExpr(hasSourceExpression(cxxConstructExpr()))) --+class URL { URL(string); }; --+URL url = "a string"; --+ --+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. --+declaratorDecl(hasTypeLoc(loc(asString("int")))) --+ matches int x -- ---Given ---struct point { point(double, double); }; ---point p = point(1.0, -1.0); --+auto x = int(3); --+cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) --+ matches int(3) -- ---The matcher ---cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point")))) ---matches point(1.0, -1.0). --- ---Given -- struct Foo { Foo(int, int); }; ---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 @@ -- 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 @@ -- - 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 @@ -- 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. --+declaratorDecl(hasTypeLoc(loc(asString("int")))) --+ matches int x -- ---Given ---struct point { point(double, double); }; ---point p = point(1.0, -1.0); --- ---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 @@ -- } -- } -- --- ---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 @@ -- -- 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 @@ -- } -- 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 @@ -- - 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 @@ -- -- (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. --+declaratorDecl(hasTypeLoc(loc(asString("int")))) --+ matches int x -- ---Given ---struct point { point(double, double); }; ---point p = point(1.0, -1.0); --- ---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 @@ -- 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 @@ -- 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 @@ -- - 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 @@ -- ---- Matcher<LabelStmt> hasDeclaration Matcher<Decl> InnerMatcher -- -- --@@ -12142,18 +9133,13 @@ -- -- 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 --@@ -12086,25 +9089,17 @@ -- - 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 @@ -- 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`. --
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 @@ -- - 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 @@ -- 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. --
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. --+declaratorDecl(hasTypeLoc(loc(asString("int")))) --+ matches int x -- ---Given ---struct point { point(double, double); }; ---point p = point(1.0, -1.0); --+auto x = int(3); --+cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) --+ matches int(3) -- ---The matcher ---cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point")))) ---matches point(1.0, -1.0). --- ---Given -- struct Foo { Foo(int, int); }; ---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 @@ ---- -- --@@ -12704,11 +9581,9 @@ -- 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 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; ---} --- ---The matcher ---opaqueValueExpr(hasSourceExpression( --- implicitCastExpr(has( --- implicitCastExpr(has(declRefExpr())))))) ---matches b twice, for the conditiona and the true expression. --+Example 1: matches "a string" --+(matcher = castExpr(hasSourceExpression(cxxConstructExpr()))) --+class URL { URL(string); }; --+URL url = "a string"; --+ --+Example 2: matches 'b' (matcher = --+opaqueValueExpr(hasSourceExpression(implicitCastExpr(declRefExpr()))) --+int a = b ?: 1; --
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 @@ -- - 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 @@ -- 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. ---- -- --@@ -12899,18 +9728,16 @@ -- `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 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. --
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 @@ -- - 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 @@ -- 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 @@ -- 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 @@ -- - 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 @@ ---- Matcher<TemplateArgumentLoc> hasTypeLoc Matcher<TypeLoc> Inner -- -- --@@ -13275,13 +10023,10 @@ -- 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 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 @@ -- 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::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 @@ -- - 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 @@ -- -- 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 @@ -- - 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 @@ ---- 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. --+declaratorDecl(hasTypeLoc(loc(asString("int")))) --+ matches int x -- ---Given ---struct point { point(double, double); }; ---point p = point(1.0, -1.0); --+auto x = int(3); --+cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) --+ matches int(3) -- ---The matcher ---cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("point")))) ---matches point(1.0, -1.0). --- ---Given -- struct Foo { Foo(int, int); }; ---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 @@ ---- -- -- 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 @@ -- -- 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) -- 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 @@ -- - 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 @@ -- 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. ---- Matcher<UnaryOperator> hasUnaryOperand Matcher<Expr> InnerMatcher -- -- --@@ -13698,20 +10362,17 @@ -- 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 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)))) --+ !true --
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 @@ -- - 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 @@ -- 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 @@
-- /// 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 @@
-- /// 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 @@
-- /// 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 @@
-- /// 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 @@
-- /// 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
---/// \code
---/// #include "Y.h"
---/// typedef int my_main_file_int;
---/// my_main_file_int a = 0;
---/// my_header_int b = 1;
---/// \endcode
---///
---/// The matcher \matcher{typedefDecl(isExpansionInMainFile())}
---/// matches \match{typedef int my_main_file_int},
---/// but does not match \nomatch{typedef int my_header_int}.
--+/// Example matches X but not Y
--+/// (matcher = cxxRecordDecl(isExpansionInMainFile())
--+/// \code
--+/// #include
--+/// class X {};
--+/// \endcode
--+/// Y.h:
--+/// \code
--+/// class Y {};
--+/// \endcode
-- ///
-- /// Usable as: Matcher, Matcher, Matcher
-- AST_POLYMORPHIC_MATCHER(isExpansionInMainFile,
--@@ -420,21 +253,16 @@
--
-- /// 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 @@
-- /// 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 @@
-- /// 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 @@
--
-- /// 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 @@
-- /// \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; };
--+/// struct S {
--+/// union {
--+/// int i;
--+/// } U;
--+/// };
-- /// \endcode
---/// The matcher \matcher{namedDecl()}
---/// matches \match{typedef int X},
---/// \match{std=c$struct S { union { int i; } U; }}, \match{int i},
---/// the unnamed union\match{type=name$} and the variable
---/// \match{union { int i; } U},
---/// with \match{type=name;count=2;std=c++$S} matching twice in C++.
---/// Once for the implicit class declaration and once for the declaration itself.
-- extern const internal::VariadicDynCastAllOfMatcher namedDecl;
--
-- /// Matches a declaration of label.
-- ///
-- /// Given
-- /// \code
---/// 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 @@
-- /// 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 @@
-- /// 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 @@
-- /// 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 @@
-- /// 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 @@
-- /// \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 @@
-- /// \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 @@
-- /// 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 @@
-- /// 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 @@
-- /// 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 @@
-- ///
-- /// 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 @@
-- /// \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 @@
-- /// \code
-- /// template 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 @@
-- /// \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 @@
-- /// Matches public C++ declarations and C++ base specifers that specify public
-- /// inheritance.
-- ///
---/// Given
--+/// Examples:
-- /// \code
-- /// class C {
---/// public: int a;
--+/// public: int a; // fieldDecl(isPublic()) matches 'a'
-- /// protected: int b;
-- /// private: int c;
-- /// };
-- /// \endcode
---/// \compile_args{-std=c++}
---/// The matcher \matcher{fieldDecl(isPublic())}
---/// matches \match{int a}.
-- ///
---/// Given
-- /// \code
-- /// class Base {};
---/// class Derived1 : public Base {};
---/// struct Derived2 : Base {};
--+/// class Derived1 : public Base {}; // matches 'Base'
--+/// struct Derived2 : Base {}; // matches 'Base'
-- /// \endcode
---/// \compile_args{-std=c++}
---/// The matcher
---/// \matcher{cxxRecordDecl(hasAnyBase(cxxBaseSpecifier(isPublic()).bind("base")))}
---/// matches \match{class Derived1 : public Base {}} and
---/// \match{struct Derived2 : Base {}},
---/// with \matcher{type=sub$cxxBaseSpecifier(isPublic())} matching
---/// \match{sub=base$public Base} and \match{sub=base$Base}.
-- AST_POLYMORPHIC_MATCHER(isPublic,
-- AST_POLYMORPHIC_SUPPORTED_TYPES(Decl,
-- CXXBaseSpecifier)) {
--@@ -909,28 +637,19 @@
-- /// Matches protected C++ declarations and C++ base specifers that specify
-- /// protected inheritance.
-- ///
---/// Given
--+/// Examples:
-- /// \code
-- /// class C {
-- /// public: int a;
---/// protected: int b;
--+/// protected: int b; // fieldDecl(isProtected()) matches 'b'
-- /// private: int c;
-- /// };
-- /// \endcode
---/// \compile_args{-std=c++}
---/// The matcher \matcher{fieldDecl(isProtected())}
---/// matches \match{int b}.
-- ///
-- /// \code
-- /// class Base {};
---/// class Derived : protected Base {};
--+/// class Derived : protected Base {}; // matches 'Base'
-- /// \endcode
---/// \compile_args{-std=c++}
---/// The matcher
---/// \matcher{cxxRecordDecl(hasAnyBase(cxxBaseSpecifier(isProtected()).bind("base")))}
---/// matches \match{class Derived : protected Base {}}, with
---/// \matcher{type=sub$cxxBaseSpecifier(isProtected())} matching
---/// \match{sub=base$Base}.
-- AST_POLYMORPHIC_MATCHER(isProtected,
-- AST_POLYMORPHIC_SUPPORTED_TYPES(Decl,
-- CXXBaseSpecifier)) {
--@@ -940,30 +659,20 @@
-- /// Matches private C++ declarations and C++ base specifers that specify private
-- /// inheritance.
-- ///
---/// Given
--+/// Examples:
-- /// \code
-- /// class C {
-- /// public: int a;
-- /// protected: int b;
---/// private: int c;
--+/// private: int c; // fieldDecl(isPrivate()) matches 'c'
-- /// };
-- /// \endcode
---/// \compile_args{-std=c++}
---/// The matcher \matcher{fieldDecl(isPrivate())}
---/// matches \match{int c}.
-- ///
-- /// \code
-- /// struct Base {};
---/// struct Derived1 : private Base {}; // \match{Base}
---/// class Derived2 : Base {}; // \match{Base}
--+/// struct Derived1 : private Base {}; // matches 'Base'
--+/// class Derived2 : Base {}; // matches 'Base'
-- /// \endcode
---/// \compile_args{-std=c++}
---/// The matcher
---/// \matcher{cxxRecordDecl(hasAnyBase(cxxBaseSpecifier(isPrivate()).bind("base")))}
---/// matches \match{struct Derived1 : private Base {}} and
---/// \match{class Derived2 : Base {}}, with
---/// \matcher{type=sub$cxxBaseSpecifier(isPrivate())} matching
---/// \match{sub=base;count=2$Base} each time.
-- AST_POLYMORPHIC_MATCHER(isPrivate,
-- AST_POLYMORPHIC_SUPPORTED_TYPES(Decl,
-- CXXBaseSpecifier)) {
--@@ -979,11 +688,11 @@
-- /// int b;
-- /// };
-- /// \endcode
---/// \compile_args{-std=c++}
---/// The matcher \matcher{fieldDecl(isBitField())}
---/// matches \match{int a : 2},
---/// but does not match \nomatch{int b}.
---AST_MATCHER(FieldDecl, isBitField) { return Node.isBitField(); }
--+/// fieldDecl(isBitField())
--+/// matches 'int a;' but not 'int b;'.
--+AST_MATCHER(FieldDecl, isBitField) {
--+ return Node.isBitField();
--+}
--
-- /// Matches non-static data members that are bit-fields of the specified
-- /// bit width.
--@@ -996,10 +705,8 @@
-- /// int c : 2;
-- /// };
-- /// \endcode
---/// \compile_args{-std=c++}
---/// The matcher \matcher{fieldDecl(hasBitWidth(2))}
---/// matches \match{int a : 2} and \match{int c : 2},
---/// but not \nomatch{int b : 4}.
--+/// fieldDecl(hasBitWidth(2))
--+/// matches 'int a;' and 'int c;' but not 'int b;'.
-- AST_MATCHER_P(FieldDecl, hasBitWidth, unsigned, Width) {
-- return Node.isBitField() &&
-- Node.getBitWidthValue(Finder->getASTContext()) == Width;
--@@ -1015,14 +722,10 @@
-- /// 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 @@
--
-- /// 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 @@
--
-- /// 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 @@
-- /// 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 @@
-- /// }
-- /// \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 @@
-- /// 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 @@
-- /// 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 @@
-- /// 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 @@
-- /// 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 @@
-- /// 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 @@
-- /// 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 @@
-- /// 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 @@
-- /// 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 @@
-- /// \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 @@
-- /// 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}.
---///
---/// The matcher \matcher{functionDecl(hasTemplateArgument(0,
---/// refersToType(asString("int"))))}
---/// matches the specialization of \match{void f() {}}.
--+/// classTemplateSpecializationDecl(hasTemplateArgument(
--+/// 1, refersToType(asString("int"))))
--+/// matches the specialization \c A
--+///
--+/// 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 @@
-- /// 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 @@
-- /// 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 @@
-- /// 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 @@
-- /// 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 @@
-- /// 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 @@
-- /// 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 @@
-- /// 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 @@
-- /// 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 @@
-- /// 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 @@
-- /// 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 @@
-- /// 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 @@
-- /// \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 @@
-- /// \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 @@
-- /// \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 @@
-- /// 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 @@
-- /// };
-- /// 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 @@
-- /// \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 @@
-- ///
-- /// Example matches x.y() and y()
-- /// \code
---/// struct X { void foo(); };
---/// void bar();
---/// void foobar() {
---/// X x;
---/// x.foo();
---/// bar();
---/// }
--+/// X x;
--+/// x.y();
--+/// y();
-- /// \endcode
---/// \compile_args{-std=c++}
---/// The matcher \matcher{callExpr()}
---/// matches \match{x.foo()} and \match{bar()};
-- 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 @@
-- /// 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 @@
-- /// \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 @@
-- /// \code
-- /// NSString *s = @"abcd";
-- /// \endcode
---/// \compile_args{-ObjC}
-- extern const internal::VariadicDynCastAllOfMatcher
-- objcStringLiteral;
--
--@@ -2035,7 +1544,6 @@
-- /// @interface Foo
-- /// @end
-- /// \endcode
---/// \compile_args{-ObjC}
-- extern const internal::VariadicDynCastAllOfMatcher
-- objcInterfaceDecl;
--
--@@ -2046,7 +1554,6 @@
-- /// @implementation Foo
-- /// @end
-- /// \endcode
---/// \compile_args{-ObjC}
-- extern const internal::VariadicDynCastAllOfMatcher
-- objcImplementationDecl;
--
--@@ -2057,7 +1564,6 @@
-- /// @protocol FooDelegate
-- /// @end
-- /// \endcode
---/// \compile_args{-ObjC}
-- extern const internal::VariadicDynCastAllOfMatcher
-- objcProtocolDecl;
--
--@@ -2068,7 +1574,6 @@
-- /// @interface Foo (Additions)
-- /// @end
-- /// \endcode
---/// \compile_args{-ObjC}
-- extern const internal::VariadicDynCastAllOfMatcher
-- objcCategoryDecl;
--
--@@ -2079,7 +1584,6 @@
-- /// @implementation Foo (Additions)
-- /// @end
-- /// \endcode
---/// \compile_args{-ObjC}
-- extern const internal::VariadicDynCastAllOfMatcher
-- objcCategoryImplDecl;
--
--@@ -2095,7 +1599,6 @@
-- /// - (void)method {}
-- /// @end
-- /// \endcode
---/// \compile_args{-ObjC}
-- extern const internal::VariadicDynCastAllOfMatcher
-- objcMethodDecl;
--
--@@ -2109,7 +1612,6 @@
-- /// printf("%d", p);
-- /// })
-- /// \endcode
---/// \compile_args{-ObjC}
-- extern const internal::VariadicDynCastAllOfMatcher
-- blockDecl;
--
--@@ -2122,7 +1624,6 @@
-- /// }
-- /// @end
-- /// \endcode
---/// \compile_args{-ObjC}
-- extern const internal::VariadicDynCastAllOfMatcher
-- objcIvarDecl;
--
--@@ -2134,7 +1635,6 @@
-- /// @property BOOL enabled;
-- /// @end
-- /// \endcode
---/// \compile_args{-ObjC}
-- extern const internal::VariadicDynCastAllOfMatcher
-- objcPropertyDecl;
--
--@@ -2144,7 +1644,6 @@
-- /// \code
-- /// @throw obj;
-- /// \endcode
---/// \compile_args{-ObjC}
-- extern const internal::VariadicDynCastAllOfMatcher
-- objcThrowStmt;
--
--@@ -2155,7 +1654,6 @@
-- /// @try {}
-- /// @catch (...) {}
-- /// \endcode
---/// \compile_args{-ObjC}
-- extern const internal::VariadicDynCastAllOfMatcher
-- objcTryStmt;
--
--@@ -2166,7 +1664,6 @@
-- /// @try {}
-- /// @catch (...) {}
-- /// \endcode
---/// \compile_args{-ObjC}
-- extern const internal::VariadicDynCastAllOfMatcher
-- objcCatchStmt;
--
--@@ -2177,7 +1674,6 @@
-- /// @try {}
-- /// @finally {}
-- /// \endcode
---/// \compile_args{-ObjC}
-- extern const internal::VariadicDynCastAllOfMatcher
-- objcFinallyStmt;
--
--@@ -2186,21 +1682,8 @@
-- ///
-- /// Example matches std::string()
-- /// \code
---/// struct A { ~A(); };
---/// void f(A);
---/// void g(A&);
---/// void h() {
---/// A a = A{};
---/// f(A{});
---/// f(a);
---/// g(a);
---/// }
--+/// const std::string str = std::string();
-- /// \endcode
---/// \compile_args{-std=c++11-or-later}
---///
---/// The matcher \matcher{exprWithCleanups()} matches \match{A{}},
---/// \match{f(A{})} and \match{f(a)},
---/// but does not match passing \nomatch{g(a)}.
-- extern const internal::VariadicDynCastAllOfMatcher
-- exprWithCleanups;
--
--@@ -2210,29 +1693,17 @@
-- /// \code
-- /// int a[] = { 1, 2 };
-- /// struct B { int x, y; };
---/// struct B b = { 5, 6 };
--+/// B b = { 5, 6 };
-- /// \endcode
---/// The matcher \matcher{initListExpr()}
---/// matches \match{{ 1, 2 }} and \match{{ 5, 6 }}
--+/// initListExpr()
--+/// matches "{ 1, 2 }" and "{ 5, 6 }"
-- extern const internal::VariadicDynCastAllOfMatcher
-- initListExpr;
--
-- /// Matches the syntactic form of init list expressions
-- /// (if expression have it).
---///
---/// Given
---/// \code
---/// int a[] = { 1, 2 };
---/// struct B { int x, y; };
---/// struct B b = { 5, 6 };
---/// \endcode
---/// \compile_args{-std=c}
---///
---/// The matcher
---/// \matcher{initListExpr(hasSyntacticForm(expr().bind("syntactic")))}
---/// matches \match{{ 1, 2 }} and \match{{ 5, 6 }}.
---AST_MATCHER_P(InitListExpr, hasSyntacticForm, internal::Matcher,
--- InnerMatcher) {
--+AST_MATCHER_P(InitListExpr, hasSyntacticForm,
--+ internal::Matcher, InnerMatcher) {
-- const Expr *SyntForm = Node.getSyntacticForm();
-- return (SyntForm != nullptr &&
-- InnerMatcher.matches(*SyntForm, Finder, Builder));
--@@ -2242,26 +1713,13 @@
-- ///
-- /// Given
-- /// \code
---/// namespace std {
---/// template
---/// class initializer_list {
---/// const T* begin;
---/// const T* end;
---/// };
---/// }
---/// template class vector {
---/// public: vector(std::initializer_list) {}
---/// };
---///
---/// vector a({ 1, 2, 3 });
---/// vector b = { 4, 5 };
--+/// std::vector a({ 1, 2, 3 });
--+/// std::vector b = { 4, 5 };
-- /// int c[] = { 6, 7 };
---/// struct pair { int x; int y; };
---/// pair d = { 8, 9 };
--+/// std::pair d = { 8, 9 };
-- /// \endcode
---/// \compile_args{-fno-delayed-template-parsing;-std=c++11-or-later,-nostdinc++}
---/// The matcher \matcher{cxxStdInitializerListExpr()}
---/// matches \match{{ 1, 2, 3 }} and \match{{ 4, 5 }}.
--+/// cxxStdInitializerListExpr()
--+/// matches "{ 1, 2, 3 }" and "{ 4, 5 }"
-- extern const internal::VariadicDynCastAllOfMatcher
-- cxxStdInitializerListExpr;
--@@ -2270,12 +1728,10 @@
-- ///
-- /// Given
-- /// \code
---/// struct point { double x; double y; };
---/// struct point pt = { .x = 42.0 };
--+/// point ptarray[10] = { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 };
-- /// \endcode
---/// The matcher
---/// \matcher{initListExpr(has(implicitValueInitExpr().bind("implicit")))}
---/// matches \match{{ .x = 42.0 }}.
--+/// implicitValueInitExpr()
--+/// matches "[0].y" (implicitly)
-- extern const internal::VariadicDynCastAllOfMatcher
-- implicitValueInitExpr;
--
--@@ -2292,12 +1748,8 @@
-- /// }
-- /// };
-- /// \endcode
---/// \compile_args{-fno-delayed-template-parsing;-std=c++}
---/// The matcher \matcher{parenListExpr()}
---/// matches \match{(*this)},
---/// but does not match \nomatch{(a, b)}
---/// because (a, b) has a predefined type and is a ParenExpr, not a
---/// ParenListExpr.
--+/// parenListExpr() matches "*this" but NOT matches (a, b) because (a, b)
--+/// has a predefined type and is a ParenExpr, not a ParenListExpr.
-- extern const internal::VariadicDynCastAllOfMatcher
-- parenListExpr;
--
--@@ -2309,9 +1761,8 @@
-- /// struct A { static const int n = N; };
-- /// struct B : public A<42> {};
-- /// \endcode
---/// \compile_args{-fno-delayed-template-parsing;-std=c++}
---/// The matcher \matcher{substNonTypeTemplateParmExpr()}
---/// matches \match{N} in the right-hand side of "static const int n = N;"
--+/// substNonTypeTemplateParmExpr()
--+/// matches "N" in the right-hand side of "static const int n = N;"
-- extern const internal::VariadicDynCastAllOfMatcher
-- substNonTypeTemplateParmExpr;
--@@ -2323,21 +1774,19 @@
-- /// namespace X { int x; }
-- /// using X::x;
-- /// \endcode
---/// \compile_args{-std=c++11-or-later}
---/// The matcher \matcher{usingDecl()}
---/// matches \match{using X::x}
--+/// usingDecl()
--+/// matches \code using X::x \endcode
-- extern const internal::VariadicDynCastAllOfMatcher usingDecl;
--
-- /// Matches using-enum declarations.
-- ///
-- /// Given
-- /// \code
---/// namespace X { enum x { val1, val2 }; }
--+/// namespace X { enum x {...}; }
-- /// using enum X::x;
-- /// \endcode
---/// \compile_args{-std=c++11-or-later}
---/// The matcher \matcher{usingEnumDecl()}
---/// matches \match{using enum X::x}
--+/// usingEnumDecl()
--+/// matches \code using enum X::x \endcode
-- extern const internal::VariadicDynCastAllOfMatcher
-- usingEnumDecl;
--
--@@ -2348,9 +1797,8 @@
-- /// namespace X { int x; }
-- /// using namespace X;
-- /// \endcode
---/// \compile_args{-std=c++11-or-later}
---/// The matcher \matcher{usingDirectiveDecl()}
---/// matches \match{using namespace X}
--+/// usingDirectiveDecl()
--+/// matches \code using namespace X \endcode
-- extern const internal::VariadicDynCastAllOfMatcher
-- usingDirectiveDecl;
--
--@@ -2366,9 +1814,8 @@
-- /// foo();
-- /// }
-- /// \endcode
---/// \compile_args{-fno-delayed-template-parsing;-std=c++}
---/// The matcher \matcher{unresolvedLookupExpr()}
---/// matches \match{foo}.
--+/// unresolvedLookupExpr()
--+/// matches \code foo() \endcode
-- extern const internal::VariadicDynCastAllOfMatcher
-- unresolvedLookupExpr;
--
--@@ -2381,9 +1828,8 @@
-- /// using X::x;
-- /// };
-- /// \endcode
---/// \compile_args{-fno-delayed-template-parsing;-std=c++}
---/// The matcher \matcher{unresolvedUsingValueDecl()}
---/// matches \match{using X::x}
--+/// unresolvedUsingValueDecl()
--+/// matches \code using X::x \endcode
-- extern const internal::VariadicDynCastAllOfMatcher
-- unresolvedUsingValueDecl;
--@@ -2401,109 +1847,79 @@
-- /// using typename Base::Foo;
-- /// };
-- /// \endcode
---/// \compile_args{-fno-delayed-template-parsing;-std=c++}
---/// The matcher \matcher{unresolvedUsingTypenameDecl()}
---/// matches \match{using typename Base::Foo}
--+/// unresolvedUsingTypenameDecl()
--+/// matches \code using Base::Foo \endcode
-- extern const internal::VariadicDynCastAllOfMatcher
-- unresolvedUsingTypenameDecl;
--
-- /// Matches a constant expression wrapper.
-- ///
---/// Given
--+/// Example matches the constant in the case statement:
--+/// (matcher = constantExpr())
-- /// \code
---/// void f(int a) {
---/// switch (a) {
---/// case 37: break;
---/// }
--+/// switch (a) {
--+/// case 37: break;
-- /// }
-- /// \endcode
---///
---/// The matcher \matcher{constantExpr()} matches \match{37}.
-- extern const internal::VariadicDynCastAllOfMatcher
-- constantExpr;
--
-- /// Matches parentheses used in expressions.
-- ///
---/// Given
--+/// Example matches (foo() + 1)
-- /// \code
-- /// int foo() { return 1; }
---/// int bar() {
---/// int a = (foo() + 1);
---/// }
--+/// int a = (foo() + 1);
-- /// \endcode
---///
---/// The matcher \matcher{parenExpr()} matches \match{(foo() + 1)}.
-- extern const internal::VariadicDynCastAllOfMatcher parenExpr;
--
-- /// Matches constructor call expressions (including implicit ones).
-- ///
---/// Given
--+/// Example matches string(ptr, n) and ptr within arguments of f
--+/// (matcher = cxxConstructExpr())
-- /// \code
---/// struct string {
---/// string(const char*);
---/// string(const char*s, int n);
---/// };
-- /// void f(const string &a, const string &b);
---/// void foo(char *ptr, int n) {
---/// f(string(ptr, n), ptr);
---/// }
--+/// char *ptr;
--+/// int n;
--+/// f(string(ptr, n), ptr);
-- /// \endcode
---/// \compile_args{-std=c++}
---///
---/// The matcher \matcher{cxxConstructExpr()} matches \match{string(ptr, n)}
---/// and \match{ptr} within arguments of \c f .
-- extern const internal::VariadicDynCastAllOfMatcher
-- cxxConstructExpr;
--
-- /// Matches unresolved constructor call expressions.
-- ///
---/// Given
--+/// Example matches T(t) in return statement of f
--+/// (matcher = cxxUnresolvedConstructExpr())
-- /// \code
-- /// template
-- /// void f(const T& t) { return T(t); }
-- /// \endcode
---/// \compile_args{-fno-delayed-template-parsing;-std=c++}
---///
---/// The matcher \matcher{cxxUnresolvedConstructExpr()} matches
---/// \match{T(t)}.
-- extern const internal::VariadicDynCastAllOfMatcher
-- cxxUnresolvedConstructExpr;
--
-- /// Matches implicit and explicit this expressions.
-- ///
---/// Given
--+/// Example matches the implicit this expression in "return i".
--+/// (matcher = cxxThisExpr())
-- /// \code
---/// struct foo {
---/// int i;
---/// int f() { return i; }
---/// int g() { return this->i; }
---/// };
--+/// struct foo {
--+/// int i;
--+/// int f() { return i; }
--+/// };
-- /// \endcode
---/// \compile_args{-std=c++}
---///
---/// The matcher \matcher{cxxThisExpr()}
---/// matches \match{this} of \c this->i and the implicit \c this expression
---/// of \match{i}.
-- extern const internal::VariadicDynCastAllOfMatcher
-- cxxThisExpr;
--
-- /// Matches nodes where temporaries are created.
-- ///
---/// Given
--+/// Example matches FunctionTakesString(GetStringByValue())
--+/// (matcher = cxxBindTemporaryExpr())
-- /// \code
---/// 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.
---/// }
--+/// FunctionTakesString(GetStringByValue());
--+/// FunctionTakesStringByPointer(GetStringPointer());
-- /// \endcode
---/// \compile_args{-std=c++}
---/// The matcher \matcher{cxxBindTemporaryExpr()}
---/// matches the constructor call \match{S()}.
-- extern const internal::VariadicDynCastAllOfMatcher
-- cxxBindTemporaryExpr;
--
--@@ -2514,19 +1930,17 @@
-- /// struct T {void func();};
-- /// T f();
-- /// void g(T);
---/// void foo() {
---/// T u(f());
---/// g(f());
---/// f().func();
---/// f(); // does not match
---/// }
-- /// \endcode
---/// \compile_args{-std=c++}
---/// The matcher \matcher{materializeTemporaryExpr()} matches
---/// \match{std=c++14-or-earlier;count=3$f()} three times before C++17 and it
---/// matches \match{std=c++17-or-later$f()} one time with C++17 and later for
---/// \c f().func() , but it does not match the \nomatch{f()} in the last line in
---/// any version.
--+/// materializeTemporaryExpr() matches 'f()' in these statements
--+/// \code
--+/// T u(f());
--+/// g(f());
--+/// f().func();
--+/// \endcode
--+/// but does not match
--+/// \code
--+/// f();
--+/// \endcode
-- extern const internal::VariadicDynCastAllOfMatcher
-- materializeTemporaryExpr;
--@@ -2535,34 +1949,20 @@
-- ///
-- /// Given
-- /// \code
---/// void* operator new(decltype(sizeof(void*)));
---/// struct X {};
---/// void foo() {
---/// auto* x = new X;
---/// }
--+/// new X;
-- /// \endcode
---/// \compile_args{-std=c++11-or-later}
---///
---/// The matcher \matcher{cxxNewExpr()}
---/// matches \match{new X}.
--+/// cxxNewExpr()
--+/// matches 'new X'.
-- extern const internal::VariadicDynCastAllOfMatcher cxxNewExpr;
--
-- /// Matches delete expressions.
-- ///
-- /// Given
-- /// \code
---/// void* operator new(decltype(sizeof(void*)));
---/// void operator delete(void*);
---/// struct X {};
---/// void foo() {
---/// auto* x = new X;
---/// delete x;
---/// }
--+/// delete X;
-- /// \endcode
---/// \compile_args{-std=c++11-or-later}
---///
---/// The matcher \matcher{cxxDeleteExpr()}
---/// matches \match{delete x}.
--+/// cxxDeleteExpr()
--+/// matches 'delete X'.
-- extern const internal::VariadicDynCastAllOfMatcher