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