如何使用编译器实例和ASTConsumer与clang 3.6

时间:2015-04-02 10:47:49

标签: c++ clang++ llvm-clang

我有一个基于clang的小工具,可以创建一个编译器实例并且能够解析C头文件。这个工具适用于clang 3.4和3.5。

我首先创建了一个编译器实例,并将它与从ASTConsumer创建的新类一起使用:

ci = new clang::CompilerInstance()
ci.createDiagnostics();
ci.createFileManager();
ci.createSourceManager(ci.getFileManager());
std::shared_ptr<clang::TargetOptions> pto = std::make_shared<clang::TargetOptions>();
pto->Triple = llvm::sys::getDefaultTargetTriple();
clang::TargetInfo *pti = clang::TargetInfo::CreateTargetInfo(m_ci.getDiagnostics(), pto);
ci.setTarget(pti);
ci.createPreprocessor(clang::TU_Complete);
...     
//add source file and the headers paths
...
MyASTConsumer * myASTConsumerClassInstance = new MyASTConsumer;
ci.setASTConsumer(myASTConsumerClassInstance);
...
//parse the header file

其中myASTConsumerClassInstance是我创建的类的实例(简化形式):

class MyASTConsumer : public clang::ASTConsumer
{
    MyASTConsumer()
    ~MyASTConsumer() {};
    virtual bool HandleTopLevelDecl( clang::DeclGroupRef d);
    virtual void HandleTagDeclDefinition( clang::TagDecl * d);
    private:
    std::vector<clang::TagDecl *> m_my_tags;
}

HandleTagDeclDefinition方法中,所有标记声明都在向量m_my_tags中注册。因此,在解析过程之后,我能够访问myASTConsumerInstance中的所有标记声明。

现在在clang 3.6 api中,方法clang::CompilerInstance::setASTConsumer需要std::unique_ptr<ASTConsumer>。如何调整我的代码?

1 个答案:

答案 0 :(得分:2)

实际上很容易替换这个

MyASTConsumer * myASTConsumerClassInstance = new MyASTConsumer;
ci.setASTConsumer(myASTConsumerClassInstance);

with:

ci.setASTConsumer(llvm::make_unique<MyASTConsumer>());

或:

MyASTConsumer * myASTConsumerClassInstance = new MyASTConsumer;
ci.setASTConsumer(llvm::make_unique<clang::ASTConsumer>(*myASTConsumerClassInstance));