#pragma redefine_extname not exported into precompiled headers
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
I have found that precompiled headers differ from textual headers in that the former do not export `#pragma redefine_extname` directives.
This is significant for a code base I am working on that uses `#pragma redefine_extname` in a header included before all else to implement custom symbol renaming (so that e.g. two different versions of the same library can be linked into the same binary, which is kinda a requirement to provide good interoperability with Rust, as two crates in the dependency tree may depend on different versions of the library).
The issue we get is as follows (simplfied):
`renaming.h`:
```
#ifndef RENAMING_H
#define RENAMING_H
#pragma redefine_extname foo PREFIX_foo
#pragma redefine_extname bar PREFIX_bar
#endif
```
`foo.h`:
```
#ifndef FOO_H
#define FOO_H
#include "renaming.h"
void foo();
#endif
```
`bar.h`:
```
#ifndef BAR_H
#define BAR_H
#include "renaming.h"
void bar();
#endif
```
When now - due to "fun stuff" happen in the larger all encompassing build system - `foo.h` is compiled as part of a PCH, and `bar.h` is not, then the function `bar` will not get renamed.
Repro with the above files:
`main.c`:
```
// #include "foo.h"
// #include "bar.h"
int main() {
foo();
bar();
}
```
Regular compile with all headers textual:
```
$ clang -S -o - main.c -include foo.h -include bar.h | grep call
callq PREFIX_foo@PLT
callq PREFIX_bar@PLT
```
Broken compile with a PCH:
```
$ clang -Xclang -emit-pch -o foo.h.pch foo.h
$ clang -S -o - main.c -include-pch foo.h.pch -include bar.h | grep call
callq PREFIX_foo@PLT
callq bar@PLT
```
The reason why it fails is that `foo.h.pch` contains the `RENAMING_H` include guard, but none of `renaming.h`'s other content.
I already have a patch for it, based on the existing exporting of `#pragma weak`, that I will send in a PR that I will associate with this bug.
Contributor guide
Research direction
Start with the reduced repro in renaming.h, foo.h, bar.h, and main.c, then run the two clang commands comparing textual headers with foo.h.pch. Trace how the PCH preserves the include guard but loses the pragma behavior. Done means the PCH compile emits PREFIX_foo and PREFIX_bar consistently, with a regression test covering the case.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 30/100