[cfe-dev] Include Default C++ paths

Mehdi AMINI mehdi.amini at silkan.com
Thu Oct 18 10:55:57 PDT 2012


Hi all,


>
> The problem that you are having is probably the #1 most annoying thing
> for me about clang. When I was getting started with clang I spent more
> time than I wish to admit on exactly what you are trying to do now,
> and basically my conclusion was that Clang does not support this use
> case currently (i.e., using clang as a library to simply parse an
> arbitrary C++ file and then do stuff with the AST or whatever).
> libTooling was not around back then, so libTooling might be a way to
> accomplish what you want. You are going to waste a lot of time if you
> try to manually do this though---I certainly did.


Same for me. Spent a far too long time on that particular issue.

>
> Someday, we may be able to say ParseFile("foo.cpp") which just gives
> you the ASTContext for the parsed file, but we currently do not, and
> it is a *really*, **really** hard problem to be able to make something
> like that "just work".


I'm thinking about shipping the lib/clang/X.Y/include with my tool to be 
independent of a clang installation.

I managed to parse and load an AST for a given file using a code like 
the following:

   void Compiler::parseFile(std::string InputFile) {
     const char *clangInclude = get_the_aforementioned_include_path();
     ::setenv("COMPILER_PATH", clangInclude, 0);
     const char *args[] = { "-fno-spell-checking", "-I", clangInclude,
         InputFile.c_str() };
     int nargs = sizeof(args) / sizeof(args[0]);

     // Initialize diagnostic engine
     clang::DiagnosticConsumer* DiagClient = new 
clang::TextDiagnosticPrinter(
         m_DiagnosticStream, m_DiagOpts);
     llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagID(
         new clang::DiagnosticIDs());
     clang::DiagnosticsEngine *DiagEngine = new 
clang::DiagnosticsEngine(DiagID,
         DiagClient);
     llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diag = &DiagEngine;

     // Now parse the file to a Translation Unit
     clang::ASTUnit *TU = clang::ASTUnit::LoadFromCommandLine(&args[0], 
&args[nargs],
         diag, m_ClangResourcePath);

     // do whatever you want with the TU, for instance...

     // Dump all top-level definitions
     for (clang::ASTUnit::top_level_iterator i = TU->top_level_begin(), 
e = TU->top_level_end(); i != e; ++i) {
       clang::Decl *D = (*i);
       if (TU->getSourceManager().isFromMainFile(D->getLocation())) {
         DumpASTVisitor DumpVisitor;
         DumpVisitor.TraverseDecl(D);
       }
     }
  }



If anyone has a better way to do this, I would be happy to read about it :-)


Mehdi Amini




More information about the cfe-dev mailing list