简体   繁体   中英

Clang AST matcher for variables compared to different variable types

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) {
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM