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.
12 The LTO visibility of a class is used by the compiler to determine which
13 classes the whole-program devirtualization (``-fwhole-program-vtables``) and
14 control flow integrity (``-fsanitize=cfi-vcall`` and ``-fsanitize=cfi-mfcall``)
15 features apply to. These features use whole-program information, so they
16 require the entire class hierarchy to be visible in order to work correctly.
18 If any translation unit in the program uses either of the whole-program
19 devirtualization or control flow integrity features, it is effectively an ODR
20 violation to define a class with hidden LTO visibility in multiple linkage
21 units. A class with public LTO visibility may be defined in multiple linkage
22 units, but the tradeoff is that the whole-program devirtualization and
23 control flow integrity features can only be applied to classes with hidden LTO
24 visibility. A class's LTO visibility is treated as an ODR-relevant property
25 of its definition, so it must be consistent between translation units.
27 In translation units built with LTO, LTO visibility is based on the
28 class's symbol visibility as expressed at the source level (i.e. the
29 ``__attribute__((visibility("...")))`` attribute, or the ``-fvisibility=``
30 flag) or, on the Windows platform, the dllimport and dllexport attributes. When
31 targeting non-Windows platforms, classes with a visibility other than hidden
32 visibility receive public LTO visibility. When targeting Windows, classes
33 with dllimport or dllexport attributes receive public LTO visibility. All
34 other classes receive hidden LTO visibility. Classes with internal linkage
35 (e.g. classes declared in unnamed namespaces) also receive hidden LTO
38 During the LTO link, all classes with public LTO visibility but not marked with
39 ``[[clang::lto_visibility_public]]`` (see below) will be refined to hidden LTO
40 visibility when the ``--lto-whole-program-visibility`` lld linker option is
41 applied (``-plugin-opt=whole-program-visibility`` for gold). This flag can be
42 used to defer specifying whether classes have hidden LTO visibility until link
43 time, to allow bitcode objects to be shared by different LTO links. Due to an
44 implementation limitation, symbols associated with classes with hidden LTO
45 visibility may still be exported from the binary when using this flag. It is
46 unsafe to refer to these symbols, and their visibility may be relaxed to hidden
47 in a future compiler release.
49 A class defined in a translation unit built without LTO receives public
50 LTO visibility regardless of its object file visibility, linkage or other
53 This mechanism will produce the correct result in most cases, but there are
54 two cases where it may wrongly infer hidden LTO visibility.
56 1. As a corollary of the above rules, if a linkage unit is produced from a
57 combination of LTO object files and non-LTO object files, any hidden
58 visibility class defined in both a translation unit built with LTO and
59 a translation unit built without LTO must be defined with public LTO
60 visibility in order to avoid an ODR violation.
62 2. Some ABIs provide the ability to define an abstract base class without
63 visibility attributes in multiple linkage units and have virtual calls
64 to derived classes in other linkage units work correctly. One example of
65 this is COM on Windows platforms. If the ABI allows this, any base class
66 used in this way must be defined with public LTO visibility.
68 Classes that fall into either of these categories can be marked up with the
69 ``[[clang::lto_visibility_public]]`` attribute. To specifically handle the
70 COM case, classes with the ``__declspec(uuid())`` attribute receive public
71 LTO visibility. On Windows platforms, clang-cl's ``/MT`` and ``/MTd``
72 flags statically link the program against a prebuilt standard library;
73 these flags imply public LTO visibility for every class declared in the
74 ``std`` and ``stdext`` namespaces.
79 The following example shows how LTO visibility works in practice in several
80 cases involving two linkage units, ``main`` and ``dso.so``.
84 +-----------------------------------------------------------+ +----------------------------------------------------+
85 | main (clang++ -fvisibility=hidden): | | dso.so (clang++ -fvisibility=hidden): |
87 | +-----------------------------------------------------+ | | struct __attribute__((visibility("default"))) C { |
88 | | LTO unit (clang++ -fvisibility=hidden -flto): | | | virtual void f(); |
90 | | struct A { ... }; | | | void C::f() {} |
91 | | struct [[clang::lto_visibility_public]] B { ... }; | | | struct D { |
92 | | struct __attribute__((visibility("default"))) C { | | | virtual void g() = 0; |
93 | | virtual void f(); | | | }; |
94 | | }; | | | struct E : D { |
95 | | struct [[clang::lto_visibility_public]] D { | | | virtual void g() { ... } |
96 | | virtual void g() = 0; | | | }; |
97 | | }; | | | __attribute__((visibility("default"))) D *mkE() { |
98 | | | | | return new E; |
99 | +-----------------------------------------------------+ | | } |
101 | struct B { ... }; | +----------------------------------------------------+
103 +-----------------------------------------------------------+
105 We will now describe the LTO visibility of each of the classes defined in
108 Class ``A`` is not defined outside of ``main``'s LTO unit, so it can have
109 hidden LTO visibility. This is inferred from the object file visibility
110 specified on the command line.
112 Class ``B`` is defined in ``main``, both inside and outside its LTO unit. The
113 definition outside the LTO unit has public LTO visibility, so the definition
114 inside the LTO unit must also have public LTO visibility in order to avoid
117 Class ``C`` is defined in both ``main`` and ``dso.so`` and therefore must
118 have public LTO visibility. This is correctly inferred from the ``visibility``
121 Class ``D`` is an abstract base class with a derived class ``E`` defined
122 in ``dso.so``. This is an example of the COM scenario; the definition of
123 ``D`` in ``main``'s LTO unit must have public LTO visibility in order to be
124 compatible with the definition of ``D`` in ``dso.so``, which is observable
125 by calling the function ``mkE``.