For example, how to match the reference to const here:
// references_match.cpp
int main() {
const int a = 5;
int b = 5;
const auto& b_ref1 = b; // <-- this one
auto& b_ref2 = b;
}
Then, if I match varDecl()
and look at their types, only a
will pass isConstQualified()
:
$ clang-query ./references_match.cpp
clang-query> set output dump
clang-query> match varDecl( )
Match #1:
Binding for "root":
VarDecl 0x5bd04b2fa390 <.../references_match.cpp:3:2, col:18> col:14 a 'const int' cinit
`-IntegerLiteral 0x5bd04b2fa3f8 <col:18> 'int' 5
...
Match #3:
Binding for "root":
VarDecl 0x5bd04b2fa5c0 <.../references_match.cpp:5:2, col:23> col:14 b_ref1 'const int &' cinit
`-ImplicitCastExpr 0x5bd04b2fa820 <col:23> 'const int' lvalue <NoOp>
`-DeclRefExpr 0x5bd04b2fa628 <col:23> 'int' lvalue Var 0x5bd04b2fa4a0 'b' 'int'
...
clang-query> match varDecl( hasType(isConstQualified()) )
Match #1:
Binding for "root":
VarDecl 0x5bd04b2fa390 <.../references_match.cpp:3:2, col:18> col:14 a 'const int' cinit
`-IntegerLiteral 0x5bd04b2fa3f8 <col:18> 'int' 5
1 match.
I.e. varDecl()
dump gets this string 'const int &'
with the const in the referred type: b_ref1 'const int &' cinit
. But, I guess, b_ref1
does not pass isConstQualified()
because const
qualifies the object, not the reference. Which matcher would match the object of the reference then? Can it be done on varDecl()
node itself or the descendants should be matched, like ImplicitCastExpr
?
The isConstQualified
matcher
checks for const
applied at the top level of the type only. The type
of b_ref1
is "reference to constant auto
", where the auto
is
inferred to mean int
. For isConstQualified
to match, it would have
to be "constant reference to ..." (which, incidentally, is not allowed in C++).
To match based on what the reference refers to, one must use the
pointee
matcher to dig down one level. (The term "pointee" originates
from the close relationship between pointers and references.)
For example, this matcher:
varDecl( # Match a variable declaration
hasType( # whose type
referenceType( # is a reference
pointee( # to
isConstQualified() # something that is const-qualified.
)
)
)
)
when used with clang-query
on your example reports:
Match #1:
$PWD\test.cc:7:5: note: "root"
binds here
7 | const auto& b_ref1 = b; // <-- this one
| ^~~~~~~~~~~~~~~~~~~~~~
1 match.