I have seen that clang embeds some specif lookup code for Gentoo paths so I am posting this issue here. I have noticed that the headers search list is not the same when trying to compile the same source by using directly clang or its library libclang. The parsing of the test code would require to load the stddef.h header which is located in two positions. The first copy is in /usr/lib/gcc/x86_64-pc-linux-gnu/12/include but this directory is not included in the default clang include search path. The other copy is in /usr/lib/llvm/17/bin/../../../../lib/clang/17/include which is found only from command line. Moreover I would expect stddef.h to be loaded from the gcc includes. I see also the error ignoring nonexistent directory "/usr/lib/gcc/x86_64-pc-linux-gnu/12/../../../../x86_64-pc-linux-gnu/include" so clang is trying to load a missing gcc include path from the wrong location. I am using this simple test code. $ cat test.cpp #include <cstddef> $ When using command line there are no errors $ clang -fsyntax-only --language c++ -v test.cpp clang version 17.0.6 Target: x86_64-pc-linux-gnu Thread model: posix InstalledDir: /usr/lib/llvm/17/bin Configuration file: /etc/clang/x86_64-pc-linux-gnu-clang.cfg System configuration file directory: /etc/clang Selected GCC installation: /usr/lib/gcc/x86_64-pc-linux-gnu/12 Candidate multilib: .;@m64 Candidate multilib: 32;@m32 Selected multilib: .;@m64 (in-process) "/usr/lib/llvm/17/bin/clang-17" -cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name test2.cpp -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -v -fcoverage-compilation-dir=/home/<USERNAME> -resource-dir /usr/lib/llvm/17/bin/../../../../lib/clang/17 -include /usr/include/gentoo/fortify.h -include /usr/include/gentoo/maybe-stddefs.h -internal-isystem /usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12 -internal-isystem /usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12/x86_64-pc-linux-gnu -internal-isystem /usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12/backward -internal-isystem /usr/lib/llvm/17/bin/../../../../lib/clang/17/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-pc-linux-gnu/12/../../../../x86_64-pc-linux-gnu/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdeprecated-macro -fdebug-compilation-dir=/home/<USERNAME> -ferror-limit 19 -stack-protector 2 -fstack-clash-protection -fcf-protection=none -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -fcolor-diagnostics -D__GCC_HAVE_DWARF2_CFI_ASM=1 -x c++ /tmp/test2.cpp clang -cc1 version 17.0.6 based upon LLVM 17.0.6 default target x86_64-pc-linux-gnu ignoring nonexistent directory "/usr/local/include" ignoring nonexistent directory "/usr/lib/gcc/x86_64-pc-linux-gnu/12/../../../../x86_64-pc-linux-gnu/include" ignoring nonexistent directory "/include" #include "..." search starts here: #include <...> search starts here: /usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12 /usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12/x86_64-pc-linux-gnu /usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12/backward /usr/lib/llvm/17/bin/../../../../lib/clang/17/include /usr/include End of search list. To use libclang I have exploited the python bindings. The following is the python code used for the test: $ cat test.py import clang.cindex as cidx ix = cidx.Index.create() tu = ix.parse('test.cpp',args=[ '-v', '-fsyntax-only','--language','c++']) print(list(tu.diagnostics)) and the result is clang version 17.0.6 Target: x86_64-pc-linux-gnu Thread model: posix InstalledDir: Configuration file: /etc/clang/x86_64-pc-linux-gnu-clang.cfg System configuration file directory: /etc/clang Selected GCC installation: /usr/lib/gcc/x86_64-pc-linux-gnu/12 Candidate multilib: .;@m64 Candidate multilib: 32;@m32 Selected multilib: .;@m64 ignoring nonexistent directory "../../../../lib/clang/17/include" ignoring nonexistent directory "/usr/local/include" ignoring nonexistent directory "/usr/lib/gcc/x86_64-pc-linux-gnu/12/../../../../x86_64-pc-linux-gnu/include" ignoring nonexistent directory "/include" #include "..." search starts here: #include <...> search starts here: /usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12 /usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12/x86_64-pc-linux-gnu /usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12/backward /usr/include End of search list. [<Diagnostic severity 4, location <SourceLocation file '/usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12/cstddef', line 50, column 10>, spelling "'stddef.h' file not found">] In this case libclang is not able to find the stddef.h file because the clang include path used above is not correctly added to the search list. Also in this case is present the error related to one of the gcc include dirs.
Ah, I wonder if this explains bug 811723...
It partly does, as in that both are the result of failed resource dir lookup. Causes are different though. You will need to pass: '-resource-dir', '${LLVM_ROOT}' e.g '-resource-dir', '/usr/lib/clang/18' in args, clang does this for calls to clang on it's own. Changing that is really up to upstream imho. Added bonus that if you are less than 5 levels deep, "../../../../lib/clang/17/include" will resolve to "lib/clang/17/include", and that is symlinked to "/usr/lib" on merged-usr.