0

私はそれがシングルマッチャと、ネストされたループの任意のレベルを扱うことができるかどうかわからない、ネストされたループ内の変数にクランAST StatementMatcherでネストされたループを見つける

for(i=0;i<10;i++) 
    for(j=0;j<10;j++) 
    //I have i and j 

を見つけることStatementMatcher打ち鳴らすを使用しようとしていますそれができればそれは素晴らしいだろう。

今のところ、複数のネストされたループと変数(llvmの例から得たもの)を処理できない以下のマッチャーでループを見つけることができます。誰かがこれを手伝うことができれば感謝します。

StatementMatcher LoopMatcher = 
    forStmt(hasLoopInit(declStmt(
hasSingleDecl(varDecl(hasInitializer(integerLiteral(equals(0)))) 
           .bind("initVarName")))), 
     hasIncrement(unaryOperator(
      hasOperatorName("++"), 
      hasUnaryOperand(declRefExpr(
       to(varDecl(hasType(isInteger())).bind("incVarName")))))), 
     hasCondition(binaryOperator(
      hasOperatorName("<"), 
      hasLHS(ignoringParenImpCasts(declRefExpr(
       to(varDecl(hasType(isInteger())).bind("condVarName"))))), 
      hasRHS(expr(hasType(isInteger())))))).bind("forLoop"); 

PS:それはそれが簡単にノー{}内部ループの周りで上記のような完璧なネストされたループを探していますならば。

答えて

0

Nネストされたforループと一致させる方法はありませんが、一致させたい深さNごとにN個のマッチャを作成する必要はありません。 など。

StatementMatcher forLoopLevel2 = forStmt(<someMatcher>, hasDescendant(forStmt())).bind("loop2"); 

間違いやって価値がない

StatementMatcher forLoopLevel3 = forStmt(<someMatcher>, hasDescendant(forStmt(<someMatcher>,hasDescendant(forStmt())))).bind("loop3"); 

私がアドバイスするのは、単一のforループのためのマッチャーを作成することです。コールバックはNレベルのネストforループ(各forループごとに1回)に対してN回だけ呼び出されます。これらのコールバックインスタンスのそれぞれから変数名を取得することができ、それはどんな深さでも機能します。ここで、ループ初期化し、conditionalizesを確保する

int main(int argc, const char **argv) { 

    MyPrinter Printer; 
    MatchFinder Finder; 

    StatementMatcher forLoopMatcher = forStmt(hasLoopInit(declStmt(hasSingleDecl(varDecl().bind("initVar")))), 
    hasCondition(binaryOperator(hasLHS(ignoringParenImpCasts(declRefExpr(to(varDecl().bind("condVar"))))))), 
    hasIncrement(unaryOperator(hasUnaryOperand(declRefExpr(to(varDecl().bind("incVar")))))) 
).bind("loop"); 

    Finder.addMatcher(forLoopMatcher, &Printer); 

    return Tool.run(newFrontendActionFactory(&Finder).get()); 
} 

メインメソッドのコードは..であり、同じ変数をインクリメントします。

static bool areSameVariable(const ValueDecl *First, const ValueDecl *Second) { 
    return First && Second && First->getCanonicalDecl() == Second->getCanonicalDecl(); 
} 

文の

class MyPrinter : public MatchFinder::MatchCallback { 
public: 
    virtual void run(const MatchFinder::MatchResult &Result) { 
     ASTContext *context = Result.Context; 

     if(const ForStmt *F = Result.Nodes.getNodeAs<clang::ForStmt>("loop")){ 
     const VarDecl *initVar = Result.Nodes.getNodeAs<clang::VarDecl>("initVar"); 
     const VarDecl *condVar = Result.Nodes.getNodeAs<clang::VarDecl>("condVar"); 
     const VarDecl *incVar = Result.Nodes.getNodeAs<clang::VarDecl>("incVar"); 

     if(areSameVariable(initVar,condVar) && areSameVariable(initVar, incVar)){ 
      string name = initVar->getNameAsString(); 
      outs() << "Variable name is: " + name + "\n"; 
     } 
     } 
    } 
}; 

サンプル入力ファイルが見つかりされるたびにマッチコールバック:

int main(void) { 
    for(int a=0; a<10; a++){ 
     for(int b=0; b<10; b++){ 

     } 
    } 
    return 0; 
} 

出力

Variable name is: a 
Variable name is: b 
関連する問題