I am new to clang-tidy and the following is practice so I can move to more complex matchers and tools.
Lets say we have
typedef int my_type;
void foo()
{
int x = 0;//this should be identified as need to be fixed
my_type z = 0;
if( x == z){
//match this case
}
}
My goal is to identify variables that are compared against "my_type" in order to fix their declarations by changing their types to my_type.
Right now I am tryng to do the following
auto my_type_decl = varDecl(hasType(asString("my_type")));
auto my_type_decl_exp= declRefExpr(to(my_type_decl));
auto binop = binaryOperator(has(implicitCastExpr(has(my_type_decl_exp))));
auto other_decl_exp = declRefExpr(hasAncestor(binop), unless(to(my_type_decl)));
//get ancestor functionDecl
//get descendant varDecls that match the other_decl_exp
The problem here is that I disregard context. What would be the correct way to go about something like this?
You can bind node matchers to a name, and then retrieve those nodes from the match result.
For example:
// Match binary operators
binaryOperator(
// that are equality comparisons,
hasOperatorName("=="),
// where one side refers to a variable
hasEitherOperand(ignoringImpCasts(declRefExpr(to(varDecl(
// whose type is a typedef or type alias
hasType(typedefNameDecl(
// named "::my_type"
hasName("::my_type"),
// that aliases any type, which is bound to the name "aliased",
hasType(type().bind("aliased"))))))))),
// and where one side refers to a variable
hasEitherOperand(ignoringImpCasts(declRefExpr(to(varDecl(
// whose type is the same as the type bound to "aliased",
// which is bound to the name "declToChange".
hasType(type(equalsBoundNode("aliased")))).bind("declToChange"))))));
And then:
const auto *declToChange = result.Nodes.getNodeAs<VarDecl>("declToChange");
Note that this matches the equality comparisons, so declToChange
might point to the same VarDecl
in multiple matches.
In the following example, this matcher would produce two matches with declToChange
bound to x
, and none with declToChange
bound to y
:
typedef int my_type;
void foo() {
int x = 0;
int y = 0;
my_type z = 0;
if (x == z) {
}
if (z == x) {
}
}