brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.3 KiB · ec1f907 Raw
401 lines · plain
1LLVM Interface Export Annotations2=================================3Symbols that are part of LLVM's public interface must be explicitly annotated4to support shared library builds with hidden default symbol visibility. This5document provides background and guidelines for annotating the codebase.6 7LLVM Shared Library8-------------------9LLVM builds as a static library by default, but it can also be built as a shared10library with the following configuration:11 12::13 14   LLVM_BUILD_LLVM_DYLIB=On15   LLVM_LINK_LLVM_DYLIB=On16 17There are three shared library executable formats we're interested in: PE18Dynamic Link Library (.dll) on Windows, Mach-O Shared Object (.dylib) on Apple19systems, and ELF Shared Object (.so) on Linux, BSD and other Unix-like systems.20 21ELF and Mach-O Shared Object files can be built with no additional setup or22configuration. This is because all global symbols in the library are exported by23default -- the same as when building a static library. However, when building a24DLL for Windows, the situation is more complex:25 26- Symbols are not exported from a DLL by default. Symbols must be annotated with27  ``__declspec(dllexport)`` when building the library to be externally visible.28 29- Symbols imported from a Windows DLL should generally be annotated with30  ``__declspec(dllimport)`` when compiling clients.31 32- A single Windows DLL can export a maximum of 65,535 symbols.33 34Because of the requirements for Windows DLLs, additional work must be done to35ensure the proper set of public symbols is exported and visible to clients.36 37Annotation Macros38-----------------39The distinct DLL import and export annotations required for Windows DLLs40typically lead developers to define a preprocessor macro for annotating41exported symbols in header public files. The custom macro resolves to the42**export** annotation when building the library and the **import** annotation43when building the client.44 45We have defined the ``LLVM_ABI`` macro in `llvm/Support/Compiler.h46<https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/Support/Compiler.h#L152>`__47for this purpose:48 49.. code:: cpp50 51   #if defined(LLVM_EXPORTS)52   #define LLVM_ABI __declspec(dllexport)53   #else54   #define LLVM_ABI __declspec(dllimport)55   #endif56 57Windows DLL symbol visibility requirements are approximated on ELF and Mach-O58shared library builds by setting default symbol visibility to hidden59(``-fvisibility-default=hidden``) when building with the following60configuration:61 62::63 64   LLVM_BUILD_LLVM_DYLIB_VIS=On65 66For an ELF or Mach-O platform with this setting, the ``LLVM_ABI`` macro is67defined to override the default hidden symbol visibility:68 69.. code:: cpp70 71   #define LLVM_ABI __attribute__((visibility("default")))72 73In addition to ``LLVM_ABI``, there are a few other macros for use in less74common cases described below.75 76Export macros are used to annotate symbols only within their intended shared77library. This is necessary because of the way Windows handles import/export78annotations.79 80For example, ``LLVM_ABI`` resolves to ``__declspec(dllexport)`` only when81building source that is part of the LLVM shared library (e.g. source under82``llvm-project/llvm``). If ``LLVM_ABI`` were incorrectly used to annotate a83symbol from a different LLVM project (such as Clang) it would always resolve to84``__declspec(dllimport)`` and the symbol would not be properly exported.85 86How to Annotate Symbols87-----------------------88Functions89~~~~~~~~~90Exported function declarations in header files must be annotated with91``LLVM_ABI``.92 93.. code:: cpp94 95   #include "llvm/Support/Compiler.h"96 97   LLVM_ABI void exported_function(int a, int b);98 99Global Variables100~~~~~~~~~~~~~~~~101Exported global variables must be annotated with ``LLVM_ABI`` at their102``extern`` declarations.103 104.. code:: cpp105 106   #include "llvm/Support/Compiler.h"107 108   LLVM_ABI extern int exported_global_variable;109 110Classes, Structs, and Unions111~~~~~~~~~~~~~~~~~~~~~~~~~~~~112Classes, structs, and unions can be annotated with ``LLVM_ABI`` at their113declaration, but this option is generally discouraged because it will114export every class member, vtable, and type information. Instead, ``LLVM_ABI``115should be applied to individual class members that require export.116 117In the most common case, public and protected methods without a body in the118class declaration must be annotated with ``LLVM_ABI``.119 120.. code:: cpp121 122   #include "llvm/Support/Compiler.h"123 124   class ExampleClass {125   public:126     // Public methods defined externally must be annotated.127     LLVM_ABI int sourceDefinedPublicMethod(int a, int b);128 129     // Methods defined in the class definition do not need annotation.130     int headerDefinedPublicMethod(int a, int b) {131       return a + b;132     }133 134     // Constructors and destructors must be annotated if defined externally.135     ExampleClass() {}136     LLVM_ABI ~ExampleClass();137 138     // Public static methods defined externally must be annotated.139     LLVM_ABI static int sourceDefinedPublicStaticMethod(int a, int b);140   };141 142Additionally, public and protected static fields that are not initialized at143declaration must be annotated with ``LLVM_ABI``.144 145.. code:: cpp146 147   #include "llvm/Support/Compiler.h"148 149   class ExampleClass {150   public:151     // Public static fields defined externally must be annotated.152     LLVM_ABI static int mutableStaticField;153     LLVM_ABI static const int constStaticField;154 155     // Static members initialized at declaration do not need to be annotated.156     static const int initializedConstStaticField = 0;157     static constexpr int initializedConstexprStaticField = 0;158   };159 160Private methods may also require ``LLVM_ABI`` annotation. This situation occurs161when a method defined in a header calls the private method. The private method162call may be from within the class or a friend class or method.163 164.. code:: cpp165 166   #include "llvm/Support/Compiler.h"167 168   class ExampleClass {169   private:170     // Private methods must be annotated if referenced by a public method defined a171     // header file.172     LLVM_ABI int privateMethod(int a, int b);173 174   public:175     // Inlineable method defined in the class definition calls a private method176     // defined externally. If the private method is not annotated for export, this177     // method will fail to link.178     int publicMethod(int a, int b) {179       return privateMethod(a, b);180     }181   };182 183There are less common cases where you may also need to annotate an inline184function even though it is fully defined in a header. Annotating an inline185function for export does not prevent it being inlined into client code. However,186it does ensure there is a single, stable address for the function exported from187the shared library.188 189.. code:: cpp190 191   #include "llvm/Support/Compiler.h"192 193   // Annotate the function so it is exported from the library at a fixed194   // address.195   LLVM_ABI inline int inlineFunction(int a, int b) {196     return a + b;197   }198 199Similarly, if a stable pointer-to-member function address is required for a200method in a C++ class, it may be annotated for export.201 202.. code:: cpp203 204   #include "llvm/Support/Compiler.h"205 206   class ExampleClass {207   public:208     // Annotate the method so it is exported from the library at a fixed209     // address.210     LLVM_ABI inline int inlineMethod(int a, int b) {211       return a + b;212     }213   };214 215.. note::216 217   When an inline function is annotated for export, the header containing the218   function definition **must** be included by at least one of the library's219   source files or the function will never be compiled with the export220   annotation.221 222Friend Functions223~~~~~~~~~~~~~~~~224Friend functions declared in a class, struct or union must be annotated with225``LLVM_ABI`` if the corresponding function declaration is annotated with226``LLVM_ABI``. This requirement applies even when the class containing the friend227declaration is annotated with ``LLVM_ABI``.228 229.. code:: cpp230 231   #include "llvm/Support/Compiler.h"232 233   // An exported function that has friend access to ExampleClass internals.234   LLVM_ABI int friend_function(ExampleClass &obj);235 236   class ExampleClass {237     // Friend declaration of a function must be annotated the same as the actual238     // function declaration.239     LLVM_ABI friend int friend_function(ExampleClass &obj);240   };241 242.. note::243 244   Annotating the friend declaration avoids an “inconsistent dll linkage”245   compiler error when building a DLL for Windows.246 247Virtual Table and Type Info248~~~~~~~~~~~~~~~~~~~~~~~~~~~249Classes and structs with exported virtual methods, including child classes that250export overridden virtual methods, must also export their vtable for ELF and251Mach-O builds. This can be achieved by annotating the class rather than252individual class members.253 254The general rule here is to annotate at the class level if any out-of-line255method is declared ``virtual`` or ``override``.256 257.. code:: cpp258 259   #include "llvm/Support/Compiler.h"260 261   // Annotating the class exports vtable and type information as well as all262   // class members.263   class LLVM_ABI ParentClass {264   public:265     virtual int virtualMethod(int a, int b);266     virtual int anotherVirtualMethod(int a, int b);267     virtual ~ParentClass();268   };269 270   class LLVM_ABI ChildClass : public ParentClass {271   public:272     // Inline method override does not require the class be annotated.273     int virtualMethod(int a, int b) override {274       return ParentClass::virtualMethod(a, b);275     }276 277     // Overriding a virtual method from the parent requires the class be278     // annotated.279     int pureVirtualMethod(int a, int b) override;280 281     ~ChildClass();282   };283 284.. note::285 286   If a class is annotated, none of its members may be annotated. If class- and287   member-level annotations are combined on a class, it will fail compilation on288   Windows.289 290Compilation Errors291++++++++++++++++++292Annotating a class with ``LLVM_ABI`` causes the compiler to fully instantiate293the class at compile time. This requires exporting every method that could be294potentially used by a client even though no existing clients may actually use295them. This can cause compilation errors that were not previously present.296 297The most common type of error occurs when the compiler attempts to instantiate298and export a class' implicit copy constructor and copy assignment operator. If299the class contains move-only members that cannot be copied (``std::unique_ptr``300for example), the compiler will fail to instantiate these implicit301methods.302 303This problem is easily addressed by explicitly deleting the class' copy304constructor and copy assignment operator:305 306.. code:: cpp307 308   #include "llvm/Support/Compiler.h"309 310   class LLVM_ABI ExportedClass {311   public:312     ExportedClass() = default;313 314     // Explicitly delete the copy constructor and assignment operator.315     ExportedClass(ExportedClass const&) = delete;316     ExportedClass& operator=(ExportedClass const&) = delete;317   };318 319We know this modification is harmless because any clients attempting to use320these methods already would fail to compile. For a more detailed explanation,321see `this Microsoft dev blog322<https://devblogs.microsoft.com/oldnewthing/20190927-00/?p=102932>`__.323 324Templates325~~~~~~~~~326Most template classes are entirely header-defined and do not need to be exported327because they will be instantiated and compiled into the client as needed. Such328template classes require no export annotations. However, there are some less329common cases where annotations are required for templates.330 331Specialized Template Functions332++++++++++++++++++++++++++++++333As with any other exported function, an exported specialization of a template334function not defined in a header file must have its declaration annotated with335``LLVM_ABI``.336 337.. code:: cpp338 339   #include "llvm/Support/Compiler.h"340 341   template <typename T> T templateMethod(T a, T b) {342     return a + b;343   }344 345   // The explicitly specialized definition of templateMethod for int is located in346   // a source file. This declaration must be annotated with LLVM_ABI to export it.347   template <> LLVM_ABI int templateMethod(int a, int b);348 349Similarly, an exported specialization of a method in a template class must have350its declaration annotated with ``LLVM_ABI``.351 352.. code:: cpp353 354   #include "llvm/Support/Compiler.h"355 356   template <typename T> class TemplateClass {357   public:358     int method(int a, int b) {359       return a + b;360     }361   };362 363   // The explicitly specialized definition of method for int is defined in a364   // source file. The declaration must be annotated with LLVM_ABI to export it.365   template <> LLVM_ABI int TemplateStruct<int>::method(int a, int b);366 367Explicitly Instantiated Template Classes368++++++++++++++++++++++++++++++++++++++++369Explicitly instantiated template classes must be annotated with370template-specific annotations at both declaration and definition.371 372An extern template instantiation in a header file must be annotated with373``LLVM_TEMPLATE_ABI``. This will typically be located in a header file.374 375.. code:: cpp376 377   #include "llvm/Support/Compiler.h"378 379   template <typename T> class TemplateClass {380   public:381     TemplateClass(T val) : val_(val) {}382 383     T get() const { return val_;  }384 385   private:386     const T val_;387   };388 389   // Explicitly instantiate and export TempalateClass for int type.390   extern template class LLVM_TEMPLATE_ABI TemplateClass<int>;391 392The corresponding definition of the template instantiation must be annotated393with ``LLVM_EXPORT_TEMPLATE``. This will typically be located in a source file.394 395.. code:: cpp396 397   #include "TemplateClass.h"398 399   // Explicitly instantiate and export TempalateClass for int type.400   template class LLVM_EXPORT_TEMPLATE TemplateClass<int>;401