我想使用clang从iOS应用程序预处理目标C文件。我查看了源代码,并尝试实现基于RecursiveASTVisitor类的预处理器。但是,我似乎遇到了许多我无法解决的问题。我开发了一个预处理器来添加一个" Enter"在每个方法的开头调用一个"退出"最后打电话。我还添加了一个"退出"在每个return语句之前调用。我使用以下代码来执行检测:
class ExampleVisitor : public RecursiveASTVisitor<ExampleVisitor> {
private:
ASTContext *astContext; // used for getting additional AST info
std::string funcName;
public:
explicit ExampleVisitor(CompilerInstance *CI)
: astContext(&(CI->getASTContext())) // initialize private members
{
rewriter.setSourceMgr(astContext->getSourceManager(), astContext->getLangOpts());
}
virtual bool VisitObjCMethodDecl(ObjCMethodDecl *ND) {
funcName = ND->getDeclName().getAsString();
errs() << "Testing function: " << funcName << "\n";
if (ND->hasBody()) {
rewriter.InsertText(ND->getBody()->getSourceRange().getBegin().getLocWithOffset(1), "\nEnter(\""+funcName+"\");\n");
rewriter.InsertText(ND->getBody()->getSourceRange().getEnd(),"Exit(\""+funcName+"\");\n");
}
return true;
}
virtual bool VisitReturnStmt(ReturnStmt *ret) {
rewriter.InsertText(ret->getSourceRange().getBegin(), "\nExit(\""+funcName+"\");\n");
errs() << "** Rewrote ReturnStmt\n";
return true;
}
virtual ~ExampleVisitor() {}
};
class ExampleASTConsumer : public ASTConsumer {
private:
ExampleVisitor *visitor; // doesn't have to be private
public:
// override the constructor in order to pass CI
explicit ExampleASTConsumer(CompilerInstance *CI)
: visitor(new ExampleVisitor(CI)) // initialize the visitor
{ }
// override this to call our ExampleVisitor on the entire source file
virtual void HandleTranslationUnit(ASTContext &Context) {
/* we can use ASTContext to get the TranslationUnitDecl, which is
a single Decl that collectively represents the entire source file */
visitor->TraverseDecl(Context.getTranslationUnitDecl());
}
};
代码编译。我创建了一个命令行可执行文件&#34; instrument&#34;。然后我使用以下命令在Xcode生成的简单Objective C程序上运行它:
仪器AppDelegate.m -
我遇到两个问题。首先,我得到错误:&#39; UIKit / UIKit.h&#39;文件未找到。这是Xcode生成的包含之一。其次,我只看到文件中正在处理的一些返回语句。有人能给我一些有关正在发生的事情的见解吗?
我使用的是llvm的3.7.0版本。