2016-07-07 1 views
1

Я новичок в статическом анализе объектива-c через clang. У меня проблема с тем, что когда я нахожу ReturnStmt через RecursiveASTVisitor, clang иногда не может найти ReturnStmt. Код RecursiveASTVisitor так:Как я могу получить Return-Stmt объекта-c через 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; 
    }} 

И вот результат Первый результат может найти обратный STMT

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

Но второй не может найти его

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

@Nishant Sharma – CurryChen

+0

Ну, я не получил тэг: [как упоминать тег любого пользователя в сообщении] (http://meta.stackexchange.com/questions/97471/how-to-mention-tag- любой пользователь-в-пост). В случае, если вы хотите пометить кого-то. Что касается вопроса, я могу понять, почему это произойдет, я скоро составу ответ. –

ответ

0

Позвольте мне объясните, как работает clang AST с небольшим примером. Допустим, этот код существует в temp.cpp

int b() 
{ 
    return 0; 
} 

int main() 
{ 
    return b(); 
} 

Теперь давайте посмотрим, что AST представление лязгом о приведенный выше код: (Кстати, это то, что вы можете сделать в любое время вы не видите ваш код делает . что это должно быть на сырье AST, чтобы увидеть, что это не так, чтобы получить сырье AST дамп с лязгом мы будем запускать этот

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

Это дает нам этот выход:..

|-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)' 

Если вы взглянуть на ель st FunctionDecl для функции b, это простой оператор return, который возвращает целочисленное значение 0. Но теперь, если вы посмотрите на FunctionDecl для main, вы увидите, что returnStmt вызывает CallExpr, который затем получает возврат из функции b. Это именно то, что происходит в вашем случае. Один оператор возврата обнаруживается, а другой нет.

Что вы можете сделать в этом случае - это позвонить getRetValue() из ReturnStmt, который предоставит вам тип Expr, и вам нужно решить, что для разных возможных случаев возврата.

+0

Я hava еще один способ зарегистрировать оператор возврата, и этот метод может использоваться в файлах .m и .mm. Подобно этому #define return if (log (XXX), 1) return – CurryChen

Смежные вопросы