2016-07-07 15 views
1

Ich bin ein Anfänger in der statischen Analyse von Ziel-c durch Clang jetzt. Ich habe ein Problem, dass, wenn ich die ReturnStmt durch RecursiveASTVisitor finde, Clang manchmal die ReturnStmt nicht finden kann. Der RecursiveASTVisitor Code wie folgt:Wie bekomme ich die Return Stmt von Ziel-c durch clang-3.9?

class MyASTVisitor : public RecursiveASTVisitor<MyASTVisitor> { 
public: 
    MyASTVisitor(Rewriter &R) : TheRewriter(R) {} 
    ......... 
     else if(isa<ReturnStmt>(s)){ 
      //The Return Stmt find block 
      ReturnStmt *returnStat = cast<ReturnStmt>(s); 
      TheRewriter.InsertText(returnStat->getLocStart(),"//the return stmt\n",true,true); 
     } 
     return true; 
    }} 

Und das ist das Ergebnis Das erste Ergebnis die Rückkehr Anw

int main (int argc, const char* argv[]) { 
@autoreleasepool { 
    //the func--->NSLog() begin called! 
    NSLog (@"Programming is fun!"); 
} 
//the return stmt 
return 0; } 

Aber die zweite es mich finden kann nicht finden,

int main(int argc, char * argv[]) { 
@autoreleasepool { 
    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 
}} 
+0

@Nishant Sharma – CurryChen

+0

Nun, ich habe Ihr Tag nicht bekommen: [Wie zu erwähnen, jeden Benutzer in einem Beitrag Tag] (http://meta.stackexchange.com/questions/97471/how-to-mention-tag- Jeder-Benutzer-in-einem-Post). Ich möchte Sie jemanden markieren. Was die Frage betrifft, kann ich sehen, warum das passieren würde, ich werde in Kürze eine Antwort zusammenstellen. –

Antwort

0

Lassen erklären, wie CLAng mit einem kleinen Beispiel arbeitet. Angenommen, dieser Code in temp.cpp Jetzt

int b() 
{ 
    return 0; 
} 

int main() 
{ 
    return b(); 
} 

lassen Sie uns sehen, was existiert die AST Darstellung des obigen Codes des Klanges ist: (By the way, ist dies etwas, das Sie jederzeit tun können Sie nicht sehen, den Code zu tun ., was es sollte am rohen AST Schauen Sie, um zu sehen, was falsch ist, um die rohe AST-Dump von Klirren bekommen wir diese laufen

clang -Xclang -ast-dump -fsyntax-only temp.cpp 

diese uns diese Ausgabe gibt..

|-FunctionDecl 0x5f952e0 <t.cpp:2:1, line:5:1> line:2:5 used b 'int (void)' 
| `-CompoundStmt 0x5f95400 <line:3:1, line:5:1> 
| `-ReturnStmt 0x5f953e8 <line:4:2, col:9> 
|  `-IntegerLiteral 0x5f953c8 <col:9> 'int' 0 
`-FunctionDecl 0x5f95440 <line:7:1, line:10:1> line:7:5 main 'int (void)' 
    `-CompoundStmt 0x5f95620 <line:8:1, line:10:1> 
    `-ReturnStmt 0x5f95608 <line:9:2, col:11> 
     `-CallExpr 0x5f955e0 <col:9, col:11> 'int' 
     `-ImplicitCastExpr 0x5f955c8 <col:9> 'int (*)(void)' <FunctionToPointerDecay> 
      `-DeclRefExpr 0x5f95570 <col:9> 'int (void)' lvalue Function 0x5f952e0 'b' 'int (void)' 

Wenn Sie sieh dir die Tanne an st FunctionDecl für die Funktion b, es ist eine einfache return-Anweisung, die den Integer-Wert 0 zurückgibt. Aber jetzt, wenn Sie den FunctionDecl für main betrachten, können Sie sehen, dass returnStmt CallExpr aufruft, das dann die Rückgabe von der Funktion b erhält. Genau das passiert in Ihrem Fall. Eine Return-Anweisung wird erkannt und eine nicht.

Was Sie in diesem Fall tun können, ist Anruf getRetValue() von ReturnStmt, die Ihnen einen Expr geben wird, und Sie müssen das für verschiedene mögliche Rückkehrfälle auflösen.

+0

Ich have einen anderen Weg, um die Rückkehr Erklärung der Funktion zu protokollieren, und diese Methode kann in .m und .mm-Datei verwenden. Wie diese # define zurück, wenn (log (XXX), 1) zurückgeben – CurryChen