Howto build clang tools using cmake

Hello,

Sorry if this question has already been asked. I am trying to compile the "How to write RecursiveASTVisitor based ASTFrontedActions" tutorial located here http://clang.llvm.org/docs/RAVFrontendAction.html by using CMake.

In order to do this, I created a new "mytool" directory in the clang source tree containing the source code provided in the tutorial:

~/llvm/tools/clang/tools/mytool

The directory contains the CMakeLists.txt and FindClassDecls.cpp provided in the tutorial.

I have also updated the CMakeLists.txt file located at ~/llvm/tools/clang/tools/ so that the mytool directory is included in the CMake build process.

However when I try to build the tool, I get the following errors (I suspect the clangTooling library is not found).

[ 98%] Building CXX object tools/clang/tools/mytool/CMakeFiles/find-class-decls.dir/FindClassDecls.cpp.o
/Users/aludin/clang-llvm/llvm/tools/clang/tools/mytool/FindClassDecls.cpp:17:43: error: member access into incomplete type
      'clang::ASTContext'
      FullSourceLoc FullLocation = Context->getFullLoc(Declaration->getLocStart());
                                          ^
/Users/aludin/clang-llvm/llvm/tools/clang/include/clang/AST/ASTConsumer.h:20:9: note: forward declaration of
      'clang::ASTContext'
  class ASTContext;
        ^
/Users/aludin/clang-llvm/llvm/tools/clang/tools/mytool/FindClassDecls.cpp:36:33: error: member access into incomplete type
      'clang::ASTContext'
    Visitor.TraverseDecl(Context.getTranslationUnitDecl());
                                ^
/Users/aludin/clang-llvm/llvm/tools/clang/include/clang/AST/ASTConsumer.h:20:9: note: forward declaration of
      'clang::ASTContext'
  class ASTContext;
        ^
/Users/aludin/clang-llvm/llvm/tools/clang/tools/mytool/FindClassDecls.cpp:44:31: error: virtual function 'CreateASTConsumer'
      has a different return type ('clang::ASTConsumer *') than the function it overrides (which has return type
      'std::unique_ptr<ASTConsumer>')
  virtual clang::ASTConsumer *CreateASTConsumer(
                              ^
/Users/aludin/clang-llvm/llvm/tools/clang/include/clang/Frontend/FrontendAction.h:64:40: note: overridden virtual function is
      here
  virtual std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
                                       ^
3 errors generated.
make[2]: *** [tools/clang/tools/mytool/CMakeFiles/find-class-decls.dir/FindClassDecls.cpp.o] Error 1
make[1]: *** [tools/clang/tools/mytool/CMakeFiles/find-class-decls.dir/all] Error 2
make: *** [all] Error 2

Any help on how to build this would be greatly appreciated.

Thanks!

Anwar

Have you read this http://clang.llvm.org/docs/LibASTMatchersTutorial.html#step-1-create-a-clangtool

Hi Nikola,

Thanks for the pointer. Moved the sources to ~/llvm/tools/clang/tools/extra/mytool and updated the CMakeLists.txt to reflect the link you provided, but I am getting the exact same build errors.
Are the docs in synch with the current Clang API (3.5)? Am I missing a library?

Content of my CMakeLists.txt:

set(LLVM_LINK_COMPONENTS support)
set(LLVM_USED_LIBS clangTooling clangBasic clangAST)

add_clang_executable(find-class-decls FindClassDecls.cpp)

target_link_libraries(find-class-decls
clangTooling
clangBasic
clangASTMatchers
)

Compiler errors:

[100%] Building CXX object tools/clang/tools/extra/mytool/CMakeFiles/find-class-decls.dir/FindClassDecls.cpp.o
/Users/aludin/clang-llvm/llvm/tools/clang/tools/extra/mytool/FindClassDecls.cpp:17:43: error: member access into incomplete
type ‘clang::ASTContext’
FullSourceLoc FullLocation = Context->getFullLoc(Declaration->getLocStart());
^
/Users/aludin/clang-llvm/llvm/tools/clang/include/clang/AST/ASTConsumer.h:20:9: note: forward declaration of
‘clang::ASTContext’
class ASTContext;
^
/Users/aludin/clang-llvm/llvm/tools/clang/tools/extra/mytool/FindClassDecls.cpp:36:33: error: member access into incomplete
type ‘clang::ASTContext’
Visitor.TraverseDecl(Context.getTranslationUnitDecl());
^
/Users/aludin/clang-llvm/llvm/tools/clang/include/clang/AST/ASTConsumer.h:20:9: note: forward declaration of
‘clang::ASTContext’
class ASTContext;
^
/Users/aludin/clang-llvm/llvm/tools/clang/tools/extra/mytool/FindClassDecls.cpp:44:31: error: virtual function
‘CreateASTConsumer’ has a different return type (‘clang::ASTConsumer *’) than the function it overrides (which has
return type ‘std::unique_ptr’)
virtual clang::ASTConsumer *CreateASTConsumer(
^
/Users/aludin/clang-llvm/llvm/tools/clang/include/clang/Frontend/FrontendAction.h:64:40: note: overridden virtual function is
here
virtual std::unique_ptr CreateASTConsumer(CompilerInstance &CI,

Thanks!

Anwar

OK finally managed to compile the code in the tutorial.

The errors are probably due to Clang API changes. Is there a way to notify the clang guys so that they update the tutorial in order to reflect the latest API?

  • needed to add the include: #include “clang/AST/ASTContext.h”

  • Changed FindNamedClassAction::CreateASTConsumer() to return a std::unique_ptr instead of a raw pointer ASTConsumer*.

  • Here is the updated code:

#include “clang/AST/ASTContext.h”
#include “clang/AST/ASTConsumer.h”
#include “clang/AST/RecursiveASTVisitor.h”
#include “clang/Frontend/CompilerInstance.h”
#include “clang/Frontend/FrontendAction.h”
#include “clang/Tooling/Tooling.h”

using namespace clang;

class FindNamedClassVisitor
: public RecursiveASTVisitor {
public:
explicit FindNamedClassVisitor(ASTContext *Context)
: Context(Context) {}

bool VisitCXXRecordDecl(CXXRecordDecl *Declaration) {
if (Declaration->getQualifiedNameAsString() == “n::m::C”) {
FullSourceLoc FullLocation = Context->getFullLoc(Declaration->getLocStart());
if (FullLocation.isValid())
llvm::outs() << "Found declaration at "
<< FullLocation.getSpellingLineNumber() << “:”
<< FullLocation.getSpellingColumnNumber() << “\n”;
}
return true;
}

private:
ASTContext *Context;
};

class FindNamedClassConsumer : public clang::ASTConsumer {
public:
explicit FindNamedClassConsumer(ASTContext *Context)
: Visitor(Context) {}

virtual void HandleTranslationUnit(clang::ASTContext &Context) {
Visitor.TraverseDecl(Context.getTranslationUnitDecl());
}
private:
FindNamedClassVisitor Visitor;
};

class FindNamedClassAction : public clang::ASTFrontendAction {
public:
virtual std::unique_ptr CreateASTConsumer(
clang::CompilerInstance &Compiler, llvm::StringRef InFile) {
return std::unique_ptr(new FindNamedClassConsumer(&Compiler.getASTContext()));
}
};

int main(int argc, char **argv) {
if (argc > 1) {
clang::tooling::runToolOnCode(new FindNamedClassAction, argv[1]);
}
}

Corresponding CMakeLists.txt:

set(LLVM_LINK_COMPONENTS support)
set(LLVM_USED_LIBS clangTooling clangBasic clangAST)

add_clang_executable(find-class-decls FindClassDecls.cpp)

target_link_libraries(find-class-decls
clangTooling
clangBasic
clangASTMatchers
)

The most awesomest way would be to send a patch for the docs :smiley: otherwise this is the right venue. Thanks for reporting!