简体   繁体   中英

AST MATCHER:How to match un init double param in constructor

I 'm having a question to match uninit double field in constructor. Given the code below

class un_init_double {
  public:
    un_init_double() {
      init_param_ = 0;
    }
    bool compare(un_init_double& other) {
      if (other.un_init_param_ == un_init_param_) {
        return true;
      }
      return false;
    }
  private:
    double un_init_param_;
    double init_param_;
};

I want to match the un_init_param_ field, which didn't call binary operator = in constructor. But I don't find the method to do that.

I type below command in clang-query

clang-query> match cxxRecordDecl(
has(fieldDecl(hasType(asString("double"))).bind("double_field")), has(cxxConstructorDecl(hasDescendant(binaryOperator(hasEitherOperand(memberExpr()))))))

But how to specify memberExpr is related with prew part fieldDecl? In another word, how to specify the connection of fieldDecl and the memberExpr?

I find a method to match init_param_, but how to find no match field?


clang-query> match cxxRecordDecl(has(cxxConstructorDecl(hasDescendant(binaryOperator(hasEitherOperand(memberExpr(hasDeclaration(fieldDecl(hasType(asString("double"))))).bind("member")))))))

Match #1:

~/code_test/ast_matcher/test.cc:9:7: note: "member" binds here
      init_param_ = 0;
      ^~~~~~~~~~~
~/code_test/ast_matcher/test.cc:6:1: note: "root" binds here
class un_init_double {
^~~~~~~~~~~~~~~~~~~~~~
1 match.
clang-query>

When debuging, I write a complicated method to perform this check

// match record
cxxRecordDecl(
  has(
    // constuctor has init double fieldDecl with binaryoperator = , bind to init_double_field
    cxxConstructorDecl(
      hasDescendant(
        binaryOperator(
          hasOperatorName("="),
          hasEitherOperand(memberExpr(hasDeclaration(fieldDecl(hasType(asString("double"))).bind("init_double_field"))))
        )
      )
    )
  ),
  has(
    // match double field which didn't call binaryoperator = in constructor
    fieldDecl(hasType(asString("double")), unless(equalsBoundNode("init_double_field"))).bind("un_init_double_field")
  )
)

It seems work, but if i add a sentence: "un_init_param_ = 1;" in constructor, it still take un_init_param_ as uninit_field. Find that it's caused by ast matcher will only match first one rather than match all. So I modify matcher to

cxxRecordDecl(
  has(
    cxxConstructorDecl(
      forEachDescendant(
        binaryOperator(
          hasOperatorName("="),
          hasEitherOperand(memberExpr(hasDeclaration(fieldDecl(hasType(asString("double"))).bind("init_double_field"))))
        )
      )
    )
  ), 
  has(
      fieldDecl(hasType(asString("double")), unless(equalsBoundNode("init_double_field"))).bind("un_init_double_field")
  )
)

I modify original test.cpp to

int f(int x) {
  int result = (x / 42);
  return result;
}

class un_init_double {
  public:
    un_init_double() {
      init_param_0_ = 0;
      init_param_1_ = 0;
    }
    bool compare(un_init_double& other) {
      if (other.un_init_param_ == un_init_param_) {
        return true;
      }
      return false;
    }
  private:
    double un_init_param_;
    double init_param_0_;
    double init_param_1_;
};

new ast matcher can match it as below

Match #1:

/home/qcraft/code_test/ast_dump/test.cpp:20:5: note: "init_double_field" binds here
    double init_param_0_;
    ^~~~~~~~~~~~~~~~~~~~
/home/qcraft/code_test/ast_dump/test.cpp:6:1: note: "root" binds here
class un_init_double {
^~~~~~~~~~~~~~~~~~~~~~
/home/qcraft/code_test/ast_dump/test.cpp:19:5: note: "un_init_double_field" binds here
    double un_init_param_;
    ^~~~~~~~~~~~~~~~~~~~~

Match #2:

/home/qcraft/code_test/ast_dump/test.cpp:21:5: note: "init_double_field" binds here
    double init_param_1_;
    ^~~~~~~~~~~~~~~~~~~~
/home/qcraft/code_test/ast_dump/test.cpp:6:1: note: "root" binds here
class un_init_double {
^~~~~~~~~~~~~~~~~~~~~~
/home/qcraft/code_test/ast_dump/test.cpp:19:5: note: "un_init_double_field" binds here
    double un_init_param_;
    ^~~~~~~~~~~~~~~~~~~~~
2 matches.
clang-query> 

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