Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何通过clang-3.9获得objective-c的返回Stmt?_Objective C_Macos_Clang_Llvm_Static Analysis - Fatal编程技术网

如何通过clang-3.9获得objective-c的返回Stmt?

如何通过clang-3.9获得objective-c的返回Stmt?,objective-c,macos,clang,llvm,static-analysis,Objective C,Macos,Clang,Llvm,Static Analysis,我现在是通过clang对objective-c进行静态分析的新手。 我面临一个问题,当我通过RecursiveASTVisitor找到ReturnsMT时,clang有时无法找到ReturnsMT。 RecursiveASTVisitor代码如下: class MyASTVisitor : public RecursiveASTVisitor<MyASTVisitor> { public: MyASTVisitor(Rewriter &R) : TheRewr

我现在是通过clang对objective-c进行静态分析的新手。 我面临一个问题,当我通过RecursiveASTVisitor找到ReturnsMT时,clang有时无法找到ReturnsMT。 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;
    }}
但是第二个找不到它

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)'
|-FunctionDecl 0x5f952e0行:2:5使用了b'int(void)'
|`-CompoundStmt 0x5f95400
|`-ReturnStmt 0x5f953e8
|`-IntegerLiteral 0x5f953c8'int'0
`-FunctionDecl 0x5f95440行:7:5主“int(void)”命令
`-复合材料STMT 0x5f95620
`-返回STMT 0x5f95608
`-调用者0x5f955e0'内部'
`-隐式CASTEXPR 0x5f955c8'内部(*)(无效)'
`-DeclRefExpr 0x5f95570'内部(无效)'左值函数0x5f952e0'b''内部(无效)'
如果您查看函数b的第一个FunctionDecl,它是一个返回整数值0的简单返回语句。但是,现在如果您查看main的FunctionDecl,您可以看到returnStmt调用CallExpr,然后CallExpr从函数b获取返回。这正是您的情况。检测到一个return语句一个不是


在这种情况下,您可以调用
ReturnStmt
,它将为您提供一个
Expr
类型,并且您需要为不同的可能返回情况解析该类型。

让我用一个小示例来解释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)'
|-FunctionDecl 0x5f952e0行:2:5使用了b'int(void)'
|`-CompoundStmt 0x5f95400
|`-ReturnStmt 0x5f953e8
|`-IntegerLiteral 0x5f953c8'int'0
`-FunctionDecl 0x5f95440行:7:5主“int(void)”命令
`-复合材料STMT 0x5f95620
`-返回STMT 0x5f95608
`-调用者0x5f955e0'内部'
`-隐式CASTEXPR 0x5f955c8'内部(*)(无效)'
`-DeclRefExpr 0x5f95570'内部(无效)'左值函数0x5f952e0'b''内部(无效)'
如果您查看函数b的第一个FunctionDecl,它是一个返回整数值0的简单返回语句。但是,现在如果您查看main的FunctionDecl,您可以看到returnStmt调用CallExpr,然后CallExpr从函数b获取返回。这正是您的情况。检测到一个return语句一个不是


在这种情况下,您可以调用
ReturnStmt
,它将为您提供一个
Expr
类型,您需要为不同的可能返回情况解决该问题。

我没有得到您的标记:。我想知道您是否想标记某人。至于问题,我知道为什么会发生,我将很快编译一个答案。我没有得到答案你的标记:。如果你想标记某人。至于这个问题,我知道为什么会发生,我很快会编译一个答案。我已经用另一种方法记录函数的return语句,这个方法可以在.m和.mm文件中使用。像这样#定义return if(log(XXX),1)returnI用另一种方式记录函数的return语句,这种方法可以在.m和.mm文件中使用,如#定义return if(log(XXX),1)return