]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - docs/LTOVisibility.rst
Vendor import of clang release_40 branch r294803:
[FreeBSD/FreeBSD.git] / docs / LTOVisibility.rst
1 ==============
2 LTO Visibility
3 ==============
4
5 *LTO visibility* is a property of an entity that specifies whether it can be
6 referenced from outside the current LTO unit. A *linkage unit* is a set of
7 translation units linked together into an executable or DSO, and a linkage
8 unit's *LTO unit* is the subset of the linkage unit that is linked together
9 using link-time optimization; in the case where LTO is not being used, the
10 linkage unit's LTO unit is empty. Each linkage unit has only a single LTO unit.
11
12 The LTO visibility of a class is used by the compiler to determine which
13 classes the virtual function call optimization and control flow integrity
14 features apply to. These features use whole-program information, so they
15 require the entire class hierarchy to be visible in order to work correctly.
16
17 If any translation unit in the program uses either of the virtual function
18 call optimization or control flow integrity features, it is effectively an
19 ODR violation to define a class with hidden LTO visibility in multiple linkage
20 units. A class with public LTO visibility may be defined in multiple linkage
21 units, but the tradeoff is that the virtual function call optimization and
22 control flow integrity features can only be applied to classes with hidden LTO
23 visibility. A class's LTO visibility is treated as an ODR-relevant property
24 of its definition, so it must be consistent between translation units.
25
26 In translation units built with LTO, LTO visibility is based on the
27 class's symbol visibility as expressed at the source level (i.e. the
28 ``__attribute__((visibility("...")))`` attribute, or the ``-fvisibility=``
29 flag) or, on the Windows platform, the dllimport and dllexport attributes. When
30 targeting non-Windows platforms, classes with a visibility other than hidden
31 visibility receive public LTO visibility. When targeting Windows, classes
32 with dllimport or dllexport attributes receive public LTO visibility. All
33 other classes receive hidden LTO visibility. Classes with internal linkage
34 (e.g. classes declared in unnamed namespaces) also receive hidden LTO
35 visibility.
36
37 A class defined in a translation unit built without LTO receives public
38 LTO visibility regardless of its object file visibility, linkage or other
39 attributes.
40
41 This mechanism will produce the correct result in most cases, but there are
42 two cases where it may wrongly infer hidden LTO visibility.
43
44 1. As a corollary of the above rules, if a linkage unit is produced from a
45    combination of LTO object files and non-LTO object files, any hidden
46    visibility class defined in both a translation unit built with LTO and
47    a translation unit built without LTO must be defined with public LTO
48    visibility in order to avoid an ODR violation.
49
50 2. Some ABIs provide the ability to define an abstract base class without
51    visibility attributes in multiple linkage units and have virtual calls
52    to derived classes in other linkage units work correctly. One example of
53    this is COM on Windows platforms. If the ABI allows this, any base class
54    used in this way must be defined with public LTO visibility.
55
56 Classes that fall into either of these categories can be marked up with the
57 ``[[clang::lto_visibility_public]]`` attribute. To specifically handle the
58 COM case, classes with the ``__declspec(uuid())`` attribute receive public
59 LTO visibility. On Windows platforms, clang-cl's ``/MT`` and ``/MTd``
60 flags statically link the program against a prebuilt standard library;
61 these flags imply public LTO visibility for every class declared in the
62 ``std`` and ``stdext`` namespaces.
63
64 Example
65 =======
66
67 The following example shows how LTO visibility works in practice in several
68 cases involving two linkage units, ``main`` and ``dso.so``.
69
70 .. code-block:: none
71
72     +-----------------------------------------------------------+  +----------------------------------------------------+
73     | main (clang++ -fvisibility=hidden):                       |  | dso.so (clang++ -fvisibility=hidden):              |
74     |                                                           |  |                                                    |
75     |  +-----------------------------------------------------+  |  |  struct __attribute__((visibility("default"))) C { |
76     |  | LTO unit (clang++ -fvisibility=hidden -flto):       |  |  |    virtual void f();                               |
77     |  |                                                     |  |  |  }                                                 |
78     |  |  struct A { ... };                                  |  |  |  void C::f() {}                                    |
79     |  |  struct [[clang::lto_visibility_public]] B { ... }; |  |  |  struct D {                                        |
80     |  |  struct __attribute__((visibility("default"))) C {  |  |  |    virtual void g() = 0;                           |
81     |  |    virtual void f();                                |  |  |  };                                                |
82     |  |  };                                                 |  |  |  struct E : D {                                    |
83     |  |  struct [[clang::lto_visibility_public]] D {        |  |  |    virtual void g() { ... }                        |
84     |  |    virtual void g() = 0;                            |  |  |  };                                                |
85     |  |  };                                                 |  |  |  __attribute__(visibility("default"))) D *mkE() {  |
86     |  |                                                     |  |  |    return new E;                                   |
87     |  +-----------------------------------------------------+  |  |  }                                                 |
88     |                                                           |  |                                                    |
89     |  struct B { ... };                                        |  +----------------------------------------------------+
90     |                                                           |
91     +-----------------------------------------------------------+
92
93 We will now describe the LTO visibility of each of the classes defined in
94 these linkage units.
95
96 Class ``A`` is not defined outside of ``main``'s LTO unit, so it can have
97 hidden LTO visibility. This is inferred from the object file visibility
98 specified on the command line.
99
100 Class ``B`` is defined in ``main``, both inside and outside its LTO unit. The
101 definition outside the LTO unit has public LTO visibility, so the definition
102 inside the LTO unit must also have public LTO visibility in order to avoid
103 an ODR violation.
104
105 Class ``C`` is defined in both ``main`` and ``dso.so`` and therefore must
106 have public LTO visibility. This is correctly inferred from the ``visibility``
107 attribute.
108
109 Class ``D`` is an abstract base class with a derived class ``E`` defined
110 in ``dso.so``.  This is an example of the COM scenario; the definition of
111 ``D`` in ``main``'s LTO unit must have public LTO visibility in order to be
112 compatible with the definition of ``D`` in ``dso.so``, which is observable
113 by calling the function ``mkE``.