[cfe-dev] clangd/libclang: how to emulate other compilers?

Milian Wolff via cfe-dev cfe-dev at lists.llvm.org
Wed Apr 18 13:25:25 PDT 2018


On Mittwoch, 18. April 2018 21:37:15 CEST Milian Wolff via cfe-dev wrote:
> On Mittwoch, 18. April 2018 12:25:40 CEST Manuel Klimek wrote:
> > On Tue, Apr 17, 2018 at 8:02 PM Milian Wolff via cfe-dev <
> > 
> > cfe-dev at lists.llvm.org> wrote:
> > > Hey all,
> > > 
> > > how does clangd or other users of the libclang handle situations where
> > > you
> > > want to parse code that is dependent on a certain other compiler or
> > > compiler
> > > environment? The most common scenario being embedded projects that rely
> > > on
> > > the
> > > compiler-builtin defines and include paths to find the sysroot include
> > > paths
> > > and such.
> > 
> > I'm not sure I understand what you mean - do you mean the compiler has
> > builtins that clang doesn't provide and relies on their existence?
> 
> Take this example code:
> 
> ```
> #ifndef __arm__
> #error unsupported platform
> #endif
> 
> #include <foobar.h>
> 
> static_assert(sizeof(void*) == 4);
> ```
> 
> How can I parse this with libclang, such that it emulates my arm-none-eabi-
> gcc?
> 
> - __arm__ should be defined, but not __x86_64__
> - foobar.h should be found in the default include paths for the
> arm-none-eabi- gcc compiler, not in the default include paths of libclang
> - it should be 32bit by default
> 
> Now, we can get there to some degree via -nostdinc and -nostdinc++. But once
> you do that for all compilers, you get into nasty issues when you replace
> the libclang builtin headers with headers from a different clang version or
> even a different compiler like GCC. They will be compiler specific and not
> portable, thus not parsable by libclang.

An example for this:

```
$ cat test.cpp
#include <x86intrin.h>

int main() { return 0; }

$ gcc -v -E - < /dev/null
..
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-pc-linux-gnu/7.3.1/include
 /usr/local/include
 /usr/lib/gcc/x86_64-pc-linux-gnu/7.3.1/include-fixed
 /usr/include

$ clang -nostdinc  -xc++ -isystem /usr/lib/gcc/x86_64-pc-linux-gnu/7.3.1/
include -isystem/usr/local/include -isystem/usr/lib/gcc/x86_64-pc-linux-gnu/
7.3.1/include-fixed -isystem/usr/include test.cpp
In file included from test.cpp:1:
In file included from /usr/lib/gcc/x86_64-pc-linux-gnu/7.3.1/include/
x86intrin.h:27:
/usr/lib/gcc/x86_64-pc-linux-gnu/7.3.1/include/ia32intrin.h:41:10: error: use 
of undeclared identifier '__builtin_ia32_bsrsi'
  return __builtin_ia32_bsrsi (__X);
..
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.

> > Generally, you'll want to use the builtin defines and includes from clang
> > (at the point at which you compiled libclang), but the standard library
> > and
> > so forth that the system is using. Clang should be able to find that given
> > the right flags.
> 
> Can you tell us what the right flags would be? I just looked at the man page
> again and found -nostdlibinc, which may resolve this partially - I'll
> check.

I tried it with the example above but it doesn't seem to make any 
difference... The reason seems to be that we explicitly add the path for the 
GCC builtin headers to the system include path, and that then takes precedence 
over the libclang provided ones. Now we could try to blacklist the paths for 
the GCC builtin headers, but we'll need heuristics to find them. If I remove 
"/usr/lib/gcc/x86_64-pc-linux-gnu/7.3.1/include" above, -nostdlibinc seems to 
help.

Bye
-- 
Milian Wolff
mail at milianw.de
http://milianw.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20180418/2280f991/attachment.sig>


More information about the cfe-dev mailing list