如何通过 clang-3.9 获取 objective-c 的 Return Stmt?
How do I get the Return Stmt of objective-c through clang-3.9?
我现在是通过 clang 对 objective-c 进行静态分析的菜鸟。
我遇到一个问题,当我通过 RecursiveASTVisitor 找到 ReturnStmt 时,clang 有时找不到 ReturnStmt。
RecursiveASTVisitor 代码如下:
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;
}}
这就是结果
第一个结果可以找到return 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]));
}}
让我用一个小例子来解释 clang AST 是如何工作的。假设此代码存在于 temp.cpp
int b()
{
return 0;
}
int main()
{
return b();
}
现在让我们看看上面代码的 clang AST 表示是什么:(顺便说一句,这是您可以随时做的事情,您看不到您的代码在做它应该做的事情。查看原始 AST 以看看有什么问题。要从 clang 中获取原始 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)'
如果您查看函数 b 的第一个 FunctionDecl,它是一个简单的 return 语句,其中 return 是整数值 0。但是,现在如果您查看 main 的 FunctionDecl,您可以看到 returnStmt 调用 CallExpr,然后从函数 b 中获取 return。这正是您的情况。一个 return 语句被检测到,一个没有。
在这种情况下你可以做的是调用 ReturnStmt
的 getRetValue(),这会给你一个 Expr
类型,你需要为不同的可能 return 解决这个问题案例。
我现在是通过 clang 对 objective-c 进行静态分析的菜鸟。 我遇到一个问题,当我通过 RecursiveASTVisitor 找到 ReturnStmt 时,clang 有时找不到 ReturnStmt。 RecursiveASTVisitor 代码如下:
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;
}}
这就是结果 第一个结果可以找到return 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]));
}}
让我用一个小例子来解释 clang AST 是如何工作的。假设此代码存在于 temp.cpp
int b()
{
return 0;
}
int main()
{
return b();
}
现在让我们看看上面代码的 clang AST 表示是什么:(顺便说一句,这是您可以随时做的事情,您看不到您的代码在做它应该做的事情。查看原始 AST 以看看有什么问题。要从 clang 中获取原始 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)'
如果您查看函数 b 的第一个 FunctionDecl,它是一个简单的 return 语句,其中 return 是整数值 0。但是,现在如果您查看 main 的 FunctionDecl,您可以看到 returnStmt 调用 CallExpr,然后从函数 b 中获取 return。这正是您的情况。一个 return 语句被检测到,一个没有。
在这种情况下你可以做的是调用 ReturnStmt
的 getRetValue(),这会给你一个 Expr
类型,你需要为不同的可能 return 解决这个问题案例。