How to determine clang's system include dirs, to set in ASTVisitor?

If I use llvm-config --cxxflags, it gives me, among other stuff the -I path for clangs headers.

Is there a way to get the system includes paths that clang uses internally, either programatically (query set of default system includes for the target) or on the command line using something like llvm-config, so that I can set those same paths in my ASTVisitor. Without that I get include failures with various system headers:

In file included from xx.C:1:
/vbs/common/osse/core/inc/osstype.h:29:10: fatal error: ‘stdlib.h’ file not found
#include <stdlib.h>
^

Alternately, is there a way to include the system includes paths by default? Looking in

http://clang.llvm.org/doxygen/HeaderSearchOptions_8h_source.html

it appears that UseStandardSystemIncludes, and UseStandardCXXIncludes both default to true, which explains why setting those didn’t make a difference. Are those fields not being respected for some reason?

This is probably the #1 issue that people run into when using the
clang libraries.

I forget exactly which are the magic functions that will get things to
"kind of" work. I think you can use something like
`clang::createInvocationFromCommandLine` which will set up "most"
things for you (it calls into `CompilerInvocation::CreateFromArgs`
which might be all you need).

Ultimately, you will run into a big problem, which is that some
critical headers that are needed for basically everything (e.g.
<stddef.h>) are currently found in a really nasty way which relies on
finding the headers in a specific directory *relative to the
executable*, which means that unless your executable is embedded in a
particular directory structure it will fail to find these (for the
details, see `CompilerInvocation::GetResourcesPath` and its
callsites).

This special directory is usually passed by clang to `clang -cc1`
through its `-resource-dir` command line argument. If you feel like
hardcoding this, you can look at the argument to `-resource-dir` with

clang++ '-###' -c foo.c 2>&1 | tr ' ' '\n' | grep -A1 resource

(the file foo.c must actually exist, but need not contain anything
meaningful). Alternatively, you can copy the special headers into
their special directory structure relative to your executable (this
might be the easiest thing to do). In the clang source distribution,
you can find the headers in lib/Headers/, and otherwise you can grab
them from the resource dir printed by the above command. Note that if
you build your program as an executable within the llvm/clang build
system, the built executable will be put inside the "special"
directory structure (however, having to drag around (and build!) all
of llvm/clang along with your tool is probably more annoying than the
other two options I mentioned.

Yes, having to hardcode this this is a pain in the ***. Unfortunately,
it is a pretty nasty problem to solve. Probably the most palatable
option currently is to embed the headers inside the clang libraries
(in the binaries) and have it fall back on those if the current
"hardcoded" lookup fails. But that requires messing around with the
build system; nobody has stepped up to do that.

-- Sean Silva

And there’s also a concern that if someone gets an error message referencing stddef.h, they might want to actually open and read it. But that’s impossible if the header is embedded in the executable.

Dmitri

Well, we do already have that problem for predefines, but at least people don’t expect those to be files. Still, at least there’d be a workaround: “echo ‘#include <stddef.h>’ | clang -E”

Jordan

If I use llvm-config --cxxflags, it gives me, among other stuff the -I
path for clangs headers.

Is there a way to get the system includes paths that clang uses
internally, either programatically (query set of default system includes
for the target) or on the command line using something like llvm-config, so
that I can set those same paths in my ASTVisitor. Without that I get
include failures with various system headers:

In file included from xx.C:1:
/vbs/common/osse/core/inc/osstype.h:29:10: fatal error: 'stdlib.h' file
not found
#include <stdlib.h>
         ^

Alternately, is there a way to include the system includes paths by
default? Looking in

http://clang.llvm.org/doxygen/HeaderSearchOptions_8h_source.html

it appears that UseStandardSystemIncludes, and UseStandardCXXIncludes both
default to true, which explains why setting those didn't make a difference.
Are those fields not being respected for some reason?

By the way, the LibTooling stuff (as well as writing a clang plugin) solves
the system include paths in general,
and the builtin include path (which is your problem) when you put the tool
next to a clang executable.

Cheers,
/Manuel