Skip to content

Commit 3b91030

Browse files
[llvm] add documentation for public interface annotations (LLVM_ABI, etc)
## Purpose Add documentation for the existing family of `LLVM_ABI` annotation macros defined in llvm/Support/Compiler.h. These annotations are used to describe LLVM's public interface. ## Background This documentation is in support of the annotation effort described [here](https://discourse.llvm.org/t/psa-annotating-llvm-public-interface/85307/). ## Validation Manually inspected rendered ReST document on GitHub. Co-authored-by: Saleem Abdulrasool <[email protected]>
1 parent 9b13d34 commit 3b91030

File tree

2 files changed

+377
-0
lines changed

2 files changed

+377
-0
lines changed
Lines changed: 376 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,376 @@
1+
LLVM Interface Export Annotations
2+
=================================
3+
Symbols that are part of LLVM's public interface must be explicitly annotated
4+
to support shared library builds with hidden default symbol visibility. This
5+
document provides background and guidelines for annotating the codebase.
6+
7+
LLVM Shared Library
8+
-------------------
9+
LLVM builds as a static library by default, but it can also be built as a shared
10+
library with the following configuration:
11+
12+
::
13+
14+
LLVM_BUILD_LLVM_DYLIB=On
15+
LLVM_LINK_LLVM_DYLIB=On
16+
17+
There are three shared library executable formats we're interested in: PE
18+
Dynamic Link Library (.dll) on Windows, Mach-O Shared Object (.dylib) on Apple
19+
systems, and ELF Shared Object (.so) on Linux, BSD and other Unix-like systems.
20+
21+
ELF and Mach-O Shared Object files can be built with no additional setup or
22+
configuration. This is because all global symbols in the library are exported by
23+
default -- the same as when building a static library. However, when building a
24+
DLL for Windows, the situation is more complex:
25+
26+
- Symbols are not exported from a DLL by default. Symbols must be annotated with
27+
``__declspec(dllexport)`` when building the library to be externally visible.
28+
29+
- Symbols imported from a Windows DLL should generally be annotated with
30+
``__declspec(dllimport)`` when compiling clients.
31+
32+
- A single Windows DLL can export a maximum of 65,535 symbols.
33+
34+
Because of the requirements for Windows DLLs, additional work must be done to
35+
ensure the proper set of public symbols is exported and visible to clients.
36+
37+
Annotation Macros
38+
-----------------
39+
The distinct DLL import and export annotations required for Windows DLLs
40+
typically lead developers to define a preprocessor macro for annotating exported
41+
symbols in header public files. The custom macro resolves to the _export_
42+
annotation when building the library and the _import_ annotation when building
43+
the client.
44+
45+
We have defined the `LLVM_ABI` macro in `llvm/Support/Compiler.h
46+
<https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/Support/Compiler.h#L152>`__
47+
for this purpose:
48+
49+
.. code:: cpp
50+
51+
#if defined(LLVM_EXPORTS)
52+
#define LLVM_ABI __declspec(dllexport)
53+
#else
54+
#define LLVM_ABI __declspec(dllimport)
55+
#endif
56+
57+
Windows DLL symbol visibility requirements are approximated on ELF and Mach-O
58+
shared library builds by setting default symbol visibility to hidden
59+
(``-fvisibility-default=hidden``) when building with the following
60+
configuration:
61+
62+
::
63+
64+
LLVM_BUILD_LLVM_DYLIB_VIS=On
65+
66+
For an ELF or Mach-O platform with this setting, the ``LLVM_ABI`` macro is
67+
defined to override the default hidden symbol visibility:
68+
69+
.. code:: cpp
70+
71+
#define LLVM_ABI __attribute__((visibility("default")))
72+
73+
In addition to ``LLVM_ABI``, there are a few other macros for use in less
74+
common cases described below.
75+
76+
Export macros are used to annotate symbols only within their intended shared
77+
library. This is necessary because of the way Windows handles import/export
78+
annotations.
79+
80+
For example, ``LLVM_ABI`` resolves to ``__declspec(dllexport)`` only when
81+
building source that is part of the LLVM shared library (e.g. source under
82+
``llvm-project/llvm``). If ``LLVM_ABI`` were incorrectly used to annotate a
83+
symbol from a different LLVM project (such as Clang) it would always resolve to
84+
``__declspec(dllimport)`` and the symbol would not be properly exported.
85+
86+
Annotating Symbols
87+
------------------
88+
Functions
89+
~~~~~~~~~
90+
Exported function declarations in header files must be annotated with
91+
``LLVM_ABI``.
92+
93+
.. code:: cpp
94+
95+
#include "llvm/Support/Compiler.h"
96+
97+
LLVM_ABI void exported_function(int a, int b);
98+
99+
Global Variables
100+
~~~~~~~~~~~~~~~~
101+
Exported global variables must be annotated with ``LLVM_ABI`` at their
102+
``extern`` declarations.
103+
104+
.. code:: cpp
105+
106+
#include "llvm/Support/Compiler.h"
107+
108+
LLVM_ABI extern int exported_global_variable;
109+
110+
Classes, Structs, and Unions
111+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
112+
Classes, structs, and unions can be annotated with ``LLVM_ABI`` at their
113+
declaration, but this option is generally discouraged because it will
114+
export every class member, vtable, and type information. Instead, ``LLVM_ABI``
115+
should be applied to individual class members that require export.
116+
117+
In the most common case, public and protected methods without a body in the
118+
class declaration must be annotated with ``LLVM_ABI``.
119+
120+
.. code:: cpp
121+
122+
#include "llvm/Support/Compiler.h"
123+
124+
class ExampleClass {
125+
public:
126+
// Public methods defined externally must be annotatated.
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 annotatated.
139+
LLVM_ABI static int sourceDefinedPublicStaticMethod(int a, int b);
140+
};
141+
142+
Additionally, public and protected static fields that are not initialized at
143+
declaration must be annotated with ``LLVM_ABI``.
144+
145+
.. code:: cpp
146+
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+
160+
Private methods may also require ``LLVM_ABI`` annotation in certain cases. This
161+
situation occurs when a method defined in a header calls the private method. The
162+
private method call may be from within the class, a parent class, or a friend
163+
class.
164+
165+
.. code:: cpp
166+
167+
#include "llvm/Support/Compiler.h"
168+
169+
class ExampleClass {
170+
private:
171+
// Private methods must be annotated if referenced by a public method defined a
172+
// header file.
173+
LLVM_ABI int privateMethod(int a, int b);
174+
175+
public:
176+
// Inlineable method defined in the class definition calls a private method
177+
// defined externally. If the private method is not annotated for export, this
178+
// method will fail to link.
179+
int publicMethod(int a, int b) {
180+
return privateMethod(a, b);
181+
}
182+
};
183+
184+
There are less common cases where you may also need to annotate an inline
185+
function even though it is fully defined in a header. Annotating an inline
186+
function for export does not prevent it being inlined into client code. However,
187+
it does ensure there is a single, stable address for the function exported from
188+
the shared library.
189+
190+
.. code:: cpp
191+
192+
#include "llvm/Support/Compiler.h"
193+
194+
// Annotate the function so it is exported from the library at a fixed
195+
// address.
196+
LLVM_ABI inline int inlineFunction(int a, int b) {
197+
return a + b;
198+
}
199+
200+
Similarly, if a stable pointer-to-member function address is required for a
201+
method in a C++ class, it may be annotated for export.
202+
203+
.. code:: cpp
204+
205+
#include "llvm/Support/Compiler.h"
206+
207+
class ExampleClass {
208+
public:
209+
// Annotate the method so it is exported from the library at a fixed
210+
// address.
211+
LLVM_ABI inline int inlineMethod(int a, int b) {
212+
return a + b;
213+
}
214+
};
215+
216+
.. note::
217+
218+
When an inline function is annotated for export, the header containing the
219+
function definition **must** be included by at least one of the library's
220+
source files or the function will never be compiled with the export
221+
annotation.
222+
223+
Friend Functions
224+
~~~~~~~~~~~~~~~~
225+
Friend functions declared in a class, struct or union must be annotated with
226+
``LLVM_ABI`` if the corresponding function declaration is also annotated. This
227+
requirement applies even when the class itself is annotated with ``LLVM_ABI``.
228+
229+
.. code:: cpp
230+
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 actual
238+
// 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 for Windows. This annotation is harmless but not
246+
required when building ELF or Mach-O shared libraries.
247+
248+
Virtual Table and Type Info
249+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
250+
Classes and structs with exported virtual methods, or child classes that export
251+
overridden virtual methods, must also export their vtable for ELF and Mach-O
252+
builds. This can be achieved by annotating the class rather than individual
253+
class members.
254+
255+
.. code:: cpp
256+
257+
#include "llvm/Support/Compiler.h"
258+
259+
class ParentClass {
260+
public:
261+
virtual int virtualMethod(int a, int b);
262+
virtual int anotherVirtualMethod(int a, int b);
263+
virtual ~ParentClass();
264+
};
265+
266+
// Annotating the class exports vtable and type information as well as all
267+
// class members.
268+
class LLVM_ABI ChildClass : public ParentClass {
269+
public:
270+
// Inline method override does not require the class be annotated.
271+
int virtualMethod(int a, int b) override {
272+
return ParentClass::virtualMethod(a, b);
273+
}
274+
275+
// Overriding a virtual method from the parent requires the class be
276+
// annotated. The parent class may require annotation as well.
277+
int pureVirtualMethod(int a, int b) override;
278+
~ChildClass();
279+
};
280+
281+
If annotating a type with ``LLVM_ABI`` causes compilation issues such as those
282+
described
283+
`here <https://devblogs.microsoft.com/oldnewthing/20190927-00/?p=102932>`__,
284+
the class may require modification. Often, explicitly deleting the copy
285+
constructor and copy assignment operator will resolve the issue.
286+
287+
.. code:: cpp
288+
289+
#include "llvm/Support/Compiler.h"
290+
291+
#include <vector>
292+
293+
class LLVM_ABI ExportedClass {
294+
public:
295+
// Explicitly delete the copy constructor and assignment operator.
296+
ExportedClass(ExportedClass const&) = delete;
297+
ExportedClass& operator=(ExportedClass const&) = delete;
298+
};
299+
300+
Templates
301+
~~~~~~~~~
302+
Most template classes are entirely header-defined and do not need to be exported
303+
because they will be instantiated and compiled into the client as needed. Such
304+
template classes require no export annotations. However, there are some less
305+
common cases where annotations are required for templates.
306+
307+
Specialized Template Functions
308+
++++++++++++++++++++++++++++++
309+
As with any other exported function, an exported specialization of a template
310+
function not defined in a header file must have its declaration annotated with
311+
``LLVM_ABI``.
312+
313+
.. code:: cpp
314+
315+
#include "llvm/Support/Compiler.h"
316+
317+
template <typename T> T templateMethod(T a, T b) {
318+
return a + b;
319+
}
320+
321+
// The explicitly specialized definition of templateMethod for int is located in
322+
// a source file. This declaration must be annotated with LLVM_ABI to export it.
323+
template <> LLVM_ABI int templateMethod(int a, int b);
324+
325+
Similarly, an exported specialization of a method in a template class must have
326+
its declaration annotated with ``LLVM_ABI``.
327+
328+
.. code:: cpp
329+
330+
#include "llvm/Support/Compiler.h"
331+
332+
template <typename T> class TemplateClass {
333+
public:
334+
int method(int a, int b) {
335+
return a + b;
336+
}
337+
};
338+
339+
// The explicitly specialized definition of method for int is defined in a
340+
// source file. The declaration must be annotated with LLVM_ABI to export it.
341+
template <> LLVM_ABI int TemplateStruct<int>::method(int a, int b);
342+
343+
Explicitly Instantiated Template Classes
344+
++++++++++++++++++++++++++++++++++++++++
345+
Explicitly instantiated template classes must be annotated with
346+
template-specific annotations at both declaration and definition.
347+
348+
An extern template instantiation in a header file must be annotated with
349+
``LLVM_TEMPLATE_ABI``. This will typically be located in a header file.
350+
351+
.. code:: cpp
352+
353+
#include "llvm/Support/Compiler.h"
354+
355+
template <typename T> class TemplateClass {
356+
public:
357+
TemplateClass(T val) : val_(val) {}
358+
359+
T get() const { return val_; }
360+
361+
private:
362+
const T val_;
363+
};
364+
365+
// Explicitly instantiate and export TempalateClass for int type.
366+
extern template class LLVM_TEMPLATE_ABI TemplateClass<int>;
367+
368+
The corresponding definition of the template instantiation must be annotated
369+
with ``LLVM_EXPORT_TEMPLATE``. This will typically be located in a source file.
370+
371+
.. code:: cpp
372+
373+
#include "TemplateClass.h"
374+
375+
// Explicitly instantiate and export TempalateClass for int type.
376+
template class LLVM_EXPORT_TEMPLATE TemplateClass<int>;

llvm/docs/Reference.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ LLVM and API reference documentation.
3131
HowToSetUpLLVMStyleRTTI
3232
HowToUseAttributes
3333
InAlloca
34+
InterfaceExportAnnotations
3435
LangRef
3536
LibFuzzer
3637
MarkedUpDisassembly

0 commit comments

Comments
 (0)