Running clang programmatically

Hello,

I have some trouble invoking clang_createTranslationUnitFromSourceFile. Here is the sequence of functions I use. (Note that I assembled that from various comments in the code, and may likely have missed some important bits):

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

   char const *args[] = { "-Xclang"};
   CXTranslationUnit TU = clang_createTranslationUnitFromSourceFile(idx, input_file,
                                    1, args, 0, 0);
   clang_visitChildren(clang_getTranslationUnitCursor(TU), translate, 0);
   clang_disposeTranslationUnit(TU);
   clang_disposeIndex(idx);

This results in an error output, plus a subsequent segfault:

error: unable to handle compilation, expected exactly one compiler job in ' "/usr/local/bin/clang" "-cc1" "-triple" "x86_64-unknown-linux-gnu" "-S" "-disable-free" "-main-file-name" "test.cc" "-mrelocation-model" "static" "-mdisable-fp-elim" "-mconstructor-aliases" "-munwind-tables" "-target-cpu" "x86-64" "-resource-dir" "/lib/clang/1.1" "-fmessage-length" "183" "-fexceptions" "-fgnu-runtime" "-fdiagnostics-show-option" "-fcolor-diagnostics" "-fsyntax-only" "-o" "/tmp/cc-GyUGlM.s" "-x" "c++" "/home/stefan/projects/Synopsis/test.cc"; "/usr/bin/gcc" "-Xclang" "-fsyntax-only" "-c" "-m64" "-o" "/tmp/cc-fWJsot.o" "-x" "assembler" "/tmp/cc-GyUGlM.s"; "/usr/bin/gcc" "-Xclang" "-fsyntax-only" "-m64" "-o" "a.out" "/tmp/cc-fWJsot.o"; '

My questions:

1) Is the function call sequence above (approximately) correct ? (If not, what is wrong ?)
2) Where is the current error emitted, and how may I intercept it programmatically ?
3) What is the error trying to tell me ?

Thanks for helping me getting started with CLang !

     Stefan

Hello,

I have some trouble invoking clang_createTranslationUnitFromSourceFile.
Here is the sequence of functions I use. (Note that I assembled that
from various comments in the code, and may likely have missed some
important bits):

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

  char const *args[] = { "-Xclang"};
  CXTranslationUnit TU = clang_createTranslationUnitFromSourceFile(idx,
input_file,
                                   1, args, 0, 0);
  clang_visitChildren(clang_getTranslationUnitCursor(TU), translate, 0);
  clang_disposeTranslationUnit(TU);
  clang_disposeIndex(idx);

This results in an error output, plus a subsequent segfault:

error: unable to handle compilation, expected exactly one compiler job
in ' "/usr/local/bin/clang" "-cc1" "-triple" "x86_64-unknown-linux-gnu"
"-S" "-disable-free" "-main-file-name" "test.cc" "-mrelocation-model"
"static" "-mdisable-fp-elim" "-mconstructor-aliases" "-munwind-tables"
"-target-cpu" "x86-64" "-resource-dir" "/lib/clang/1.1"
"-fmessage-length" "183" "-fexceptions" "-fgnu-runtime"
"-fdiagnostics-show-option" "-fcolor-diagnostics" "-fsyntax-only" "-o"
"/tmp/cc-GyUGlM.s" "-x" "c++" "/home/stefan/projects/Synopsis/test.cc";
"/usr/bin/gcc" "-Xclang" "-fsyntax-only" "-c" "-m64" "-o"
"/tmp/cc-fWJsot.o" "-x" "assembler" "/tmp/cc-GyUGlM.s"; "/usr/bin/gcc"
"-Xclang" "-fsyntax-only" "-m64" "-o" "a.out" "/tmp/cc-fWJsot.o"; '

My questions:

1) Is the function call sequence above (approximately) correct ? (If
not, what is wrong ?)

Do not pass -Xclang. It is for internal use only, and misuse will confuse the driver. You don't need to pass any arguments.

2) Where is the current error emitted, and how may I intercept it
programmatically ?

Driver errors can't easily be intercepted at the moment, so they go to standard error. In the near future, all diagnostics will go through the diagnostic interface of CIndex.

3) What is the error trying to tell me ?

That you really, really shouldn't pass -Xclang :slight_smile:

Hello,

I have some trouble invoking clang_createTranslationUnitFromSourceFile.
Here is the sequence of functions I use. (Note that I assembled that
from various comments in the code, and may likely have missed some
important bits):

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

char const *args[] = { "-Xclang"};

Why are you passing -Xclang?

This amounts to trying to run
  clang -Xclang foo.c
which won't do what you want.

CXTranslationUnit TU = clang_createTranslationUnitFromSourceFile(idx,
input_file,
1, args, 0, 0);
clang_visitChildren(clang_getTranslationUnitCursor(TU), translate, 0);
clang_disposeTranslationUnit(TU);
clang_disposeIndex(idx);

This results in an error output, plus a subsequent segfault:

error: unable to handle compilation, expected exactly one compiler job
in ' "/usr/local/bin/clang" "-cc1" "-triple" "x86_64-unknown-linux-gnu"
"-S" "-disable-free" "-main-file-name" "test.cc" "-mrelocation-model"
"static" "-mdisable-fp-elim" "-mconstructor-aliases" "-munwind-tables"
"-target-cpu" "x86-64" "-resource-dir" "/lib/clang/1.1"
"-fmessage-length" "183" "-fexceptions" "-fgnu-runtime"
"-fdiagnostics-show-option" "-fcolor-diagnostics" "-fsyntax-only" "-o"
"/tmp/cc-GyUGlM.s" "-x" "c++" "/home/stefan/projects/Synopsis/test.cc";
"/usr/bin/gcc" "-Xclang" "-fsyntax-only" "-c" "-m64" "-o"
"/tmp/cc-fWJsot.o" "-x" "assembler" "/tmp/cc-GyUGlM.s"; "/usr/bin/gcc"
"-Xclang" "-fsyntax-only" "-m64" "-o" "a.out" "/tmp/cc-fWJsot.o"; '

My questions:

1) Is the function call sequence above (approximately) correct ? (If
not, what is wrong ?)

Yes.

2) Where is the current error emitted, and how may I intercept it
programmatically ?

We don't have full support for this yet.

3) What is the error trying to tell me ?

That the driver ran, but the command line didn't end up as a single
job invoking clang. In this case, it ended up with no jobs:

Doug, Daniel,

thanks for your help.

1) Is the function call sequence above (approximately) correct ? (If
not, what is wrong ?)

Do not pass -Xclang. It is for internal use only, and misuse will confuse the driver. You don't need to pass any arguments.

OK, I have removed that, and the error as well as the segfault went away.

2) Where is the current error emitted, and how may I intercept it
programmatically ?

Driver errors can't easily be intercepted at the moment, so they go to standard error. In the near future, all diagnostics will go through the diagnostic interface of CIndex.

OK, thanks.

Is there any reason why I should use the current C API, instead of C++ ? I'd expect C++ to give me a much more structured API with a more fine-grained control over the preprocessing and parsing process, instead of having to pass options as string arguments. That almost looks like shell scripting ! :slight_smile:

Thanks,
         Stefan

Doug, Daniel,

thanks for your help.

1) Is the function call sequence above (approximately) correct ? (If
not, what is wrong ?)

Do not pass -Xclang. It is for internal use only, and misuse will
confuse the driver. You don't need to pass any arguments.

OK, I have removed that, and the error as well as the segfault went away.

2) Where is the current error emitted, and how may I intercept it
programmatically ?

Driver errors can't easily be intercepted at the moment, so they go to
standard error. In the near future, all diagnostics will go through
the diagnostic interface of CIndex.

OK, thanks.

Is there any reason why I should use the current C API, instead of C++ ?

So we won't constantly be breaking your client code. The C API is
stable(ish), the C++ API is not.

We have also put more effort into making the C API "sane", the C++ API
(especially once you dig deeper) has many warts which you might end up
having to grovel through yourself, as opposed to reading the C API
documentation.

- Daniel

I still have trouble running clang programmatically, and I'm not quite sure what goes wrong. I have attached a minimal test case demonstrating the problem:

I compiled it as "g++ -o clang clang.cc -lCIndex", then invoke that on a little test C++ input, via "./clang test.cc".

I then attempt to print the location of the first traversed cursor, but get nonsense. (The reported cursor type also seems incorrect, as I get a CXCursor_StructDecl, with an input file not containing any struct.)

Can anybody please help me figure out what I'm doing wrong ?

Thanks,
         Stefan

I still have trouble running clang programmatically, and I'm not quite sure what goes wrong. I have attached a minimal test case demonstrating the problem:

I compiled it as "g++ -o clang clang.cc -lCIndex", then invoke that on a little test C++ input, via "./clang test.cc".

I then attempt to print the location of the first traversed cursor, but get nonsense. (The reported cursor type also seems incorrect, as I get a CXCursor_StructDecl, with an input file not containing any struct.)

Can anybody please help me figure out what I'm doing wrong ?

(And this time with attachment. Sorry for the noise.)

Thanks,
         Stefan

clang.cc (1.26 KB)

I still have trouble running clang programmatically, and I'm not quite sure what goes wrong. I have attached a minimal test case demonstrating the problem:

I compiled it as "g++ -o clang clang.cc -lCIndex", then invoke that on a little test C++ input, via "./clang test.cc".

I then attempt to print the location of the first traversed cursor, but get nonsense. (The reported cursor type also seems incorrect, as I get a CXCursor_StructDecl, with an input file not containing any struct.)

That's probably __va_list_tag, which is defined in the predefines buffer for every source file (hence, a location that looks invalid). Get the cursor's spelling to see the name.

Can anybody please help me figure out what I'm doing wrong ?

Looks like to me.

  - Doug