`inline` variables, `static inline` member variables, and `static` member variables in a class template shouldn't be defined in the LLVM headers
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
The C++ standard guarantees `inline` variables are merged to a single instance, but on Windows, they can't be merged across DLL boundaries unless annotated with `__declspec(dllimport)` explicitly.
We do declare them without `__declspec(dllimport)`, except MSVC with `-DLLVM_BUILD_LLVM_DYLIB_VIS=ON`.
This will cause a practical problem when building a plugin or builds with `-DLLVM_LINK_LLVM_DYLIB=ON` or `-DBUILD_SHARED_LIBS=ON`.
For MSVC, the dylib builds have no problem because they require `-DLLVM_BUILD_LLVM_DYLIB_VIS=ON`.
However, plugins are supported with static builds by `-DLLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON`, so `inline`s will cause a symbol dup.
For MinGW and Cygwin, we currently rely on auto-export (and `-Wl,--export-all-symbols`) to export symbols, so `__declspec(dllimport)` is never attached. The `__declspec(dllexport)`/`__declspec(dllimport)` pair can be used once [the ABI annotation project](https://github.com/llvm/llvm-project/issues/109483) is completed, but not yet.
Anyway, the problem remains for builds with `-DBUILD_SHARED_LIBS` or plugins to static builds with `-DLLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON`.
Non-inline static member variables in a class template follow the same discussion; they can be defined in a header and will be merged by the linker, but can't cross over the DLL boundaries. (Here is one exception: declaring an explicit instantiation declaration manually works fine.)
Therefore, we should avoid defining `inline` variables, `static inline` member variables, and `static` member variables in a class template in the LLVM headers.
Contributor guide
Assessment
This issue has not been assessed yet.