Skip to content

inline variables, static inline member variables, and static member variables in a class template shouldn't be defined in the LLVM headers #167085

@kikairoya

Description

@kikairoya

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 inlines 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 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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions