ASTs of multiple files - C API clang


I am building a program in which I need to have the ASTs of multiple source files.
Except the main file that I give to clang and using the ASTConsumer, etc. for getting the AST context, I need to do the same for other files since my main file usually contains functions calls, where the functions are defined on other files. So, I need the AST of the other files in order to find the function bodies that are missing. I have the following code which seems ok since it compiles and runs without crashing. However, I am not sure if it does what I want to do.
The code is the following (which are inside a class):

//visit AST
static CXChildVisitResult TranslationUnitVisitor(CXCursor, CXCursor, CXClientData data)
return CXChildVisit_Recurse; // visit complete AST recursivly

void VisitTranslationUnitWithPCH()
//create function pointer
CXChildVisitResult (*pTranslationUnitVisitor)(CXCursor, CXCursor, CXClientData) = TranslationUnitVisitor;

//excludeDeclsFromPCH = 1, displayDiagnostics=1
CXIndex cx_idx = clang_createIndex(1, 1);

//IndexTest.pch was produced with the following command:
//“clang -x c test.h -emit-ast -o test.pch”
system("/home/socrates/llvm/Debug+Asserts/bin/clang -x c test.h -emit-ast -o test.pch");
CXTranslationUnit TU = clang_createTranslationUnit(cx_idx, “test.pch”);

//This will load all the symbols from ‘test.pch’
clang_visitChildren(clang_getTranslationUnitCursor(TU), pTranslationUnitVisitor, 0);

//This will load all the symbols from ‘test.c’, excluding symbols
//from ‘test.pch’.
char *args[] = { “-include”, “test.pch” };
TU = clang_createTranslationUnitFromSourceFile(cx_idx, “test.c”, 2, args, 0, 0);

clang_visitChildren(clang_getTranslationUnitCursor(TU), pTranslationUnitVisitor,0);

//print AST
CXString cx_str = clang_getTranslationUnitSpelling(TU);
std::cout << clang_getCString(cx_str);


At the end of the code I want to print the AST buy it does not return anything which makes me suspicious and also I get the following many many times:
test.pch:1:1: error: unknown type name ‘CPCH’
test.pch:1:5: error: expected identifier or ‘(’
test.pch:1:7: warning: null character ignored [-Wnull-character]
test.pch:1:8: warning: null character ignored [-Wnull-character]
test.pch:1:11: warning: null character ignored [-Wnull-character]
test.pch:1:12: warning: null character ignored [-Wnull-character]
test.pch:31:2: warning: missing terminating ‘"’ character
test.pch:34:2: warning: missing terminating ‘"’ character
test.pch:42:8: warning: null character ignored [-Wnull-character]
test.pch:47:107: warning: null character ignored [-Wnull-character]
test.pch:47:110: warning: null character ignored [-Wnull-character]
test.pch:51:2: warning: null character ignored [-Wnull-character]
test.pch:60:5: warning: null character ignored [-Wnull-character]

Is there anything that I am missing ? Am I doing some thing wrong in order to get the AST ? Is there any other way to do what I am looking for ?
In addition, from the CXTranslationUnit can I get somehow the context ?

I would be really grateful for some help with this.


Hi Socrates:


I am building a program in which I need to have the ASTs of multiple source files.

Do you mean multiple cpp files or a single cpp file that includes multiple headers? Your example below is the later. If that's all you want to do, just create the tu for the cpp file and pass the necessary include file paths to pick up the included files via argc/argv. Please note that PCH's are an optimization, not a requirement.

However, if you truly want to deal with multiple cpp files, i.e., multiple translation units, then process the set of files as mentioned above and place the globals on a symbol table you create for that purpose (in your visitor). Saving and disposing of each tu as you go.

Then you can reload the tu files one at a time and resolve the inter-tu definitions based on the symbol table.

I've written a doxygen-like tool based on libclang that does this. If you're interested, I'd be happy to share. All it currently does is spit out an html file (iterating over the tokens) for each source file, including the appropriate cross tu links.

I plan to contribute it once it's complete.