0

Ich versuche Klirren zu verwenden StatementMatcher Variablen in einer verschachtelten Schleifeverschachtelte Schleifen mit Clang AST StatementMatcher findet

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

Ich bin nicht sicher, zu finden, wenn es jede Ebene der verschachtelten Schleife mit einzelnen Matcher verarbeiten kann aber es wäre großartig, wenn es könnte.

Im Moment kann ich Schleifen mit Matcher unten finden, die nicht mehrere verschachtelte Schleife und Variablen verarbeiten können (habe dies aus llvm Beispiel). Ich schätze es, wenn jemand dabei helfen kann.

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: wenn es macht es einfacher, denn ich bin auf der Suche perfekt verschachtelte Schleifen wie oben ohne {} um innere Schleifen.

Antwort

0

Es gibt keine Möglichkeit (soweit mir bekannt ist), N-geschachtelte for-Schleifen zu verknüpfen, ohne N Matchings für jede mögliche Tiefe N zu erstellen, die Sie abgleichen möchten. Zum Beispiel

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

und

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

Welche tun auf jeden Fall nicht wert ist!

Was ich rate ist es, einen Matcher für eine einzelne for-Schleife zu erstellen, und der Callback wird einfach N-mal für eine geschachtelte N-Level-Schleife ausgelöst (einmal für jede Schleife). Sie können dann den Variablennamen von jeder dieser Callback-Instanzen abrufen, der für jede Tiefe funktioniert. Hier ist ein Code ..

Haupt

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()); 
} 

Methode die Schleife initialisiert, conditionalizes und erhöht die gleiche Variable zu gewährleisten.

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

Das Spiel Rückruf, wenn ein für Anweisung gefunden wird

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"; 
     } 
     } 
    } 
}; 

Beispieleingabedatei:

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

     } 
    } 
    return 0; 
} 

Ausgabe

Variable name is: a 
Variable name is: b 
Verwandte Themen