Search code examples
c++clang++llvm-clang

How to use Compiler instance and ASTConsumer with clang 3.6


I have a little tool based on clang that create a compiler instance and that was able to parse C header files. This tool worked fine with clang 3.4 and 3.5.

I first created a compiler instance and use it with a new class created from an 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

where myASTConsumerClassInstance is an instance of the class that I created like this (a simplified form):

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;
}

In the HandleTagDeclDefinition method, all the tags declarations where registred in the vector m_my_tags. So after the parsing process, I was able to access to all the tag declarations from myASTConsumerInstance.

Now in the clang 3.6 api, the method clang::CompilerInstance::setASTConsumer requiert a std::unique_ptr<ASTConsumer>. How to adapt my code?


Solution

  • It is easy in fact replace this

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

    with :

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

    or :

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