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