| LLVM Interface Export Annotations |
| ================================= |
| Symbols that are part of LLVM's public interface must be explicitly annotated |
| to support shared library builds with hidden default symbol visibility. This |
| document provides background and guidelines for annotating the codebase. |
| |
| LLVM Shared Library |
| ------------------- |
| LLVM builds as a static library by default, but it can also be built as a shared |
| library with the following configuration: |
| |
| :: |
| |
| LLVM_BUILD_LLVM_DYLIB=On |
| LLVM_LINK_LLVM_DYLIB=On |
| |
| There are three shared library executable formats we're interested in: PE |
| Dynamic Link Library (.dll) on Windows, Mach-O Shared Object (.dylib) on Apple |
| systems, and ELF Shared Object (.so) on Linux, BSD and other Unix-like systems. |
| |
| ELF and Mach-O Shared Object files can be built with no additional setup or |
| configuration. This is because all global symbols in the library are exported by |
| default -- the same as when building a static library. However, when building a |
| DLL for Windows, the situation is more complex: |
| |
| - Symbols are not exported from a DLL by default. Symbols must be annotated with |
| ``__declspec(dllexport)`` when building the library to be externally visible. |
| |
| - Symbols imported from a Windows DLL should generally be annotated with |
| ``__declspec(dllimport)`` when compiling clients. |
| |
| - A single Windows DLL can export a maximum of 65,535 symbols. |
| |
| Because of the requirements for Windows DLLs, additional work must be done to |
| ensure the proper set of public symbols is exported and visible to clients. |
| |
| Annotation Macros |
| ----------------- |
| The distinct DLL import and export annotations required for Windows DLLs |
| typically lead developers to define a preprocessor macro for annotating exported |
| symbols in header public files. The custom macro resolves to the _export_ |
| annotation when building the library and the _import_ annotation when building |
| the client. |
| |
| We have defined the `LLVM_ABI` macro in `llvm/Support/Compiler.h |
| <https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/Support/Compiler.h#L152>`__ |
| for this purpose: |
| |
| .. code:: cpp |
| |
| #if defined(LLVM_EXPORTS) |
| #define LLVM_ABI __declspec(dllexport) |
| #else |
| #define LLVM_ABI __declspec(dllimport) |
| #endif |
| |
| Windows DLL symbol visibility requirements are approximated on ELF and Mach-O |
| shared library builds by setting default symbol visibility to hidden |
| (``-fvisibility-default=hidden``) when building with the following |
| configuration: |
| |
| :: |
| |
| LLVM_BUILD_LLVM_DYLIB_VIS=On |
| |
| For an ELF or Mach-O platform with this setting, the ``LLVM_ABI`` macro is |
| defined to override the default hidden symbol visibility: |
| |
| .. code:: cpp |
| |
| #define LLVM_ABI __attribute__((visibility("default"))) |
| |
| In addition to ``LLVM_ABI``, there are a few other macros for use in less |
| common cases described below. |
| |
| Export macros are used to annotate symbols only within their intended shared |
| library. This is necessary because of the way Windows handles import/export |
| annotations. |
| |
| For example, ``LLVM_ABI`` resolves to ``__declspec(dllexport)`` only when |
| building source that is part of the LLVM shared library (e.g. source under |
| ``llvm-project/llvm``). If ``LLVM_ABI`` were incorrectly used to annotate a |
| symbol from a different LLVM project (such as Clang) it would always resolve to |
| ``__declspec(dllimport)`` and the symbol would not be properly exported. |
| |
| Annotating Symbols |
| ------------------ |
| Functions |
| ~~~~~~~~~ |
| Exported function declarations in header files must be annotated with |
| ``LLVM_ABI``. |
| |
| .. code:: cpp |
| |
| #include "llvm/Support/Compiler.h" |
| |
| LLVM_ABI void exported_function(int a, int b); |
| |
| Global Variables |
| ~~~~~~~~~~~~~~~~ |
| Exported global variables must be annotated with ``LLVM_ABI`` at their |
| ``extern`` declarations. |
| |
| .. code:: cpp |
| |
| #include "llvm/Support/Compiler.h" |
| |
| LLVM_ABI extern int exported_global_variable; |
| |
| Classes, Structs, and Unions |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| Classes, structs, and unions can be annotated with ``LLVM_ABI`` at their |
| declaration, but this option is generally discouraged because it will |
| export every class member, vtable, and type information. Instead, ``LLVM_ABI`` |
| should be applied to individual class members that require export. |
| |
| In the most common case, public and protected methods without a body in the |
| class declaration must be annotated with ``LLVM_ABI``. |
| |
| .. code:: cpp |
| |
| #include "llvm/Support/Compiler.h" |
| |
| class ExampleClass { |
| public: |
| // Public methods defined externally must be annotatated. |
| LLVM_ABI int sourceDefinedPublicMethod(int a, int b); |
| |
| // Methods defined in the class definition do not need annotation. |
| int headerDefinedPublicMethod(int a, int b) { |
| return a + b; |
| } |
| |
| // Constructors and destructors must be annotated if defined externally. |
| ExampleClass() {} |
| LLVM_ABI ~ExampleClass(); |
| |
| // Public static methods defined externally must be annotatated. |
| LLVM_ABI static int sourceDefinedPublicStaticMethod(int a, int b); |
| }; |
| |
| Additionally, public and protected static fields that are not initialized at |
| declaration must be annotated with ``LLVM_ABI``. |
| |
| .. code:: cpp |
| |
| #include "llvm/Support/Compiler.h" |
| |
| class ExampleClass { |
| public: |
| // Public static fields defined externally must be annotated. |
| LLVM_ABI static int mutableStaticField; |
| LLVM_ABI static const int constStaticField; |
| |
| // Static members initialized at declaration do not need to be annotated. |
| static const int initializedConstStaticField = 0; |
| static constexpr int initializedConstexprStaticField = 0; |
| }; |
| |
| Private methods may also require ``LLVM_ABI`` annotation in certain cases. This |
| situation occurs when a method defined in a header calls the private method. The |
| private method call may be from within the class, a parent class, or a friend |
| class. |
| |
| .. code:: cpp |
| |
| #include "llvm/Support/Compiler.h" |
| |
| class ExampleClass { |
| private: |
| // Private methods must be annotated if referenced by a public method defined a |
| // header file. |
| LLVM_ABI int privateMethod(int a, int b); |
| |
| public: |
| // Inlineable method defined in the class definition calls a private method |
| // defined externally. If the private method is not annotated for export, this |
| // method will fail to link. |
| int publicMethod(int a, int b) { |
| return privateMethod(a, b); |
| } |
| }; |
| |
| There are less common cases where you may also need to annotate an inline |
| function even though it is fully defined in a header. Annotating an inline |
| function for export does not prevent it being inlined into client code. However, |
| it does ensure there is a single, stable address for the function exported from |
| the shared library. |
| |
| .. code:: cpp |
| |
| #include "llvm/Support/Compiler.h" |
| |
| // Annotate the function so it is exported from the library at a fixed |
| // address. |
| LLVM_ABI inline int inlineFunction(int a, int b) { |
| return a + b; |
| } |
| |
| Similarly, if a stable pointer-to-member function address is required for a |
| method in a C++ class, it may be annotated for export. |
| |
| .. code:: cpp |
| |
| #include "llvm/Support/Compiler.h" |
| |
| class ExampleClass { |
| public: |
| // Annotate the method so it is exported from the library at a fixed |
| // address. |
| LLVM_ABI inline int inlineMethod(int a, int b) { |
| return a + b; |
| } |
| }; |
| |
| .. note:: |
| |
| When an inline function is annotated for export, the header containing the |
| function definition **must** be included by at least one of the library's |
| source files or the function will never be compiled with the export |
| annotation. |
| |
| Friend Functions |
| ~~~~~~~~~~~~~~~~ |
| Friend functions declared in a class, struct or union should be annotated with |
| ``LLVM_ABI_FRIEND`` if the corresponding function declaration is annotated with |
| ``LLVM_ABI``. This requirement applies even when the class containing the friend |
| declaration is annotated with ``LLVM_ABI``. |
| |
| .. code:: cpp |
| |
| #include "llvm/Support/Compiler.h" |
| |
| // An exported function that has friend access to ExampleClass internals. |
| LLVM_ABI int friend_function(ExampleClass &obj); |
| |
| class ExampleClass { |
| // Friend declaration of a function must be annotated the same as the actual |
| // function declaration. |
| LLVM_ABI_FRIEND friend int friend_function(ExampleClass &obj); |
| }; |
| |
| .. note:: |
| |
| Annotating the friend declaration avoids an “inconsistent dll linkage” |
| compiler error when building a DLL for Windows. The ``LLVM_ABI_FRIEND`` |
| annotation is a no-op when building ELF or Mach-O shared libraries. |
| |
| Virtual Table and Type Info |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| Classes and structs with exported virtual methods, or child classes that export |
| overridden virtual methods, must also export their vtable for ELF and Mach-O |
| builds. This can be achieved by annotating the class rather than individual |
| class members. |
| |
| .. code:: cpp |
| |
| #include "llvm/Support/Compiler.h" |
| |
| class ParentClass { |
| public: |
| virtual int virtualMethod(int a, int b); |
| virtual int anotherVirtualMethod(int a, int b); |
| virtual ~ParentClass(); |
| }; |
| |
| // Annotating the class exports vtable and type information as well as all |
| // class members. |
| class LLVM_ABI ChildClass : public ParentClass { |
| public: |
| // Inline method override does not require the class be annotated. |
| int virtualMethod(int a, int b) override { |
| return ParentClass::virtualMethod(a, b); |
| } |
| |
| // Overriding a virtual method from the parent requires the class be |
| // annotated. The parent class may require annotation as well. |
| int pureVirtualMethod(int a, int b) override; |
| ~ChildClass(); |
| }; |
| |
| If annotating a type with ``LLVM_ABI`` causes compilation issues such as those |
| described |
| `here <https://devblogs.microsoft.com/oldnewthing/20190927-00/?p=102932>`__, |
| the class may require modification. Often, explicitly deleting the copy |
| constructor and copy assignment operator will resolve the issue. |
| |
| .. code:: cpp |
| |
| #include "llvm/Support/Compiler.h" |
| |
| #include <vector> |
| |
| class LLVM_ABI ExportedClass { |
| public: |
| // Explicitly delete the copy constructor and assignment operator. |
| ExportedClass(ExportedClass const&) = delete; |
| ExportedClass& operator=(ExportedClass const&) = delete; |
| }; |
| |
| Templates |
| ~~~~~~~~~ |
| Most template classes are entirely header-defined and do not need to be exported |
| because they will be instantiated and compiled into the client as needed. Such |
| template classes require no export annotations. However, there are some less |
| common cases where annotations are required for templates. |
| |
| Specialized Template Functions |
| ++++++++++++++++++++++++++++++ |
| As with any other exported function, an exported specialization of a template |
| function not defined in a header file must have its declaration annotated with |
| ``LLVM_ABI``. |
| |
| .. code:: cpp |
| |
| #include "llvm/Support/Compiler.h" |
| |
| template <typename T> T templateMethod(T a, T b) { |
| return a + b; |
| } |
| |
| // The explicitly specialized definition of templateMethod for int is located in |
| // a source file. This declaration must be annotated with LLVM_ABI to export it. |
| template <> LLVM_ABI int templateMethod(int a, int b); |
| |
| Similarly, an exported specialization of a method in a template class must have |
| its declaration annotated with ``LLVM_ABI``. |
| |
| .. code:: cpp |
| |
| #include "llvm/Support/Compiler.h" |
| |
| template <typename T> class TemplateClass { |
| public: |
| int method(int a, int b) { |
| return a + b; |
| } |
| }; |
| |
| // The explicitly specialized definition of method for int is defined in a |
| // source file. The declaration must be annotated with LLVM_ABI to export it. |
| template <> LLVM_ABI int TemplateStruct<int>::method(int a, int b); |
| |
| Explicitly Instantiated Template Classes |
| ++++++++++++++++++++++++++++++++++++++++ |
| Explicitly instantiated template classes must be annotated with |
| template-specific annotations at both declaration and definition. |
| |
| An extern template instantiation in a header file must be annotated with |
| ``LLVM_TEMPLATE_ABI``. This will typically be located in a header file. |
| |
| .. code:: cpp |
| |
| #include "llvm/Support/Compiler.h" |
| |
| template <typename T> class TemplateClass { |
| public: |
| TemplateClass(T val) : val_(val) {} |
| |
| T get() const { return val_; } |
| |
| private: |
| const T val_; |
| }; |
| |
| // Explicitly instantiate and export TempalateClass for int type. |
| extern template class LLVM_TEMPLATE_ABI TemplateClass<int>; |
| |
| The corresponding definition of the template instantiation must be annotated |
| with ``LLVM_EXPORT_TEMPLATE``. This will typically be located in a source file. |
| |
| .. code:: cpp |
| |
| #include "TemplateClass.h" |
| |
| // Explicitly instantiate and export TempalateClass for int type. |
| template class LLVM_EXPORT_TEMPLATE TemplateClass<int>; |