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

Milian Wolff via cfe-dev cfe-dev at lists.llvm.org
Thu Apr 19 03:55:21 PDT 2018


On Donnerstag, 19. April 2018 12:25:00 CEST Manuel Klimek wrote:
> On Wed, Apr 18, 2018 at 9:37 PM Milian Wolff <mail at milianw.de> 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
> 
> Using clang -target arm-eabi seems to do the trick?

It doesn't for me:

```
$ arm-none-eabi-gcc -E -v - < /dev/null
..
Target: arm-none-eabi
..
#include <...> search starts here:
 /usr/lib/gcc/arm-none-eabi/7.3.0/include
 /usr/lib/gcc/arm-none-eabi/7.3.0/include-fixed
 /usr/lib/gcc/arm-none-eabi/7.3.0/../../../../arm-none-eabi/include
$ clang -target arm-none-eabi -E -v - < /dev/null
..
Target: arm-none--eabi
..
#include <...> search starts here:
 /usr/lib/clang/6.0.0/include
```

So we still have to specify the include paths. But if we pass /usr/lib/gcc/
arm-none-eabi/7.3.0/include as an include path, then clang will use the 
x86intrin.h from there, which it won't grog - it's highly GCC specific.

<snip>

> Again, there are multiple levels of builtin includes. If you want the right
> ones for a target platform, you'll need to select that target platform - if
> that doesn't work with clangd, we need to fix it :)

I don't think that setting the target on clang itself is sufficient. We also 
don't want the IDE user to configure clang manually to emulate a compiler. We 
want him to select a compiler (or find that automatically from the build 
system) and then configure clang for him.

One more example:

```
$ wget https://releases.linaro.org/components/toolchain/binaries/latest/arm-linux-gnueabihf/gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabihf.tar.xz

$ unp gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabihf.tar.xz

$ ./gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabihf/bin/arm-linux-
gnueabihf-gcc -E -v - < /dev/null
..
Target: arm-linux-gnueabihf
..
 /home/milian/Downloads/gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabihf/
bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/include
 /home/milian/Downloads/gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabihf/
bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/include-fixed
 /home/milian/Downloads/gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabihf/
bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/../../../../arm-linux-gnueabihf/
include
 /home/milian/Downloads/gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabihf/
bin/../arm-linux-gnueabihf/libc/usr/include
..

$ touch ./gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabihf/bin/../arm-
linux-gnueabihf/libc/usr/include/please_find_this.h

$ cat arm_test.cpp
#ifndef __arm__
#error unsupported platform
#endif

#include <arm_neon.h>
#include <please_find_this.h>

static_assert(sizeof(void*) == 4);

int main() { return 0; }

$ ./gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabihf/bin/arm-linux-
gnueabihf-g++ arm_test.cpp

$ clang++ -target arm-linux-gnueabihf arm_test.cpp
#error "NEON support not enabled"
..
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
```

So clearly, just specifying the target isn't enough. It's also a question of 
the other defaults for the compiler in question...
-- 
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/20180419/bea04b82/attachment.sig>


More information about the cfe-dev mailing list