A couple of months ago, I started the process of updating my CMake scripts to allow my compiler to be compiled with clang. I quickly ran into a problem calling the LLVM libraries, which is that I would get segfaults when calling LLVM API functions. I posted about this on both the clang and llvm-dev lists, but there was no response, so I decided to put the clang-related work on hold.
Last week I decided to pick this up again. My motivation for doing so is that it’s much easier to work with clang’s error diagnostics, and coding is generally more productive. However, I once again observed the same problem, which I will now attempt to describe in some detail:
I start with a fresh checkout of both llvm and clang. Both get compiled with gcc (this is on the most recent version of Ubuntu, 64-bit although I’ve seen the same problem on other OS configurations.) Then I compile my compiler with clang, and link it against the llvm libs. Everything works fine up to a point - that is, I’m able to use all of the ADT classes, derived types, and so on - until I get into the code generation phase, at which point things blow up. Specifically, I get a segfault in DIBuilder::createPointerType() (well, actually the segfault is several stack levels down from that.)
Looking in gdb, it appears that there is some sort of calling convention mismatch - my code is calling createPointerType() with an empty StringRef(), but when I attempt to look at the StringRef argument from within the createPointerType() function, the field values are garbage. This is exactly at the point where execution is transitioning from clang-compiled code to gcc-compiled code.
If I instead compile my frontend with gcc, everything works fine.
If you want to see what command-line flags I’m passing to clang, here’s what my CMakeLists.txt looks like: