xref: /freebsd/contrib/llvm-project/clang/include/clang/Basic/TargetCXXABI.h (revision c1d255d3ffdbe447de3ab875bf4e7d7accc5bfc5)
1 //===--- TargetCXXABI.h - C++ ABI Target Configuration ----------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// Defines the TargetCXXABI class, which abstracts details of the
11 /// C++ ABI that we're targeting.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_CLANG_BASIC_TARGETCXXABI_H
16 #define LLVM_CLANG_BASIC_TARGETCXXABI_H
17 
18 #include "clang/Basic/LLVM.h"
19 #include "llvm/Support/ErrorHandling.h"
20 
21 namespace clang {
22 
23 /// The basic abstraction for the target C++ ABI.
24 class TargetCXXABI {
25 public:
26   /// The basic C++ ABI kind.
27   enum Kind {
28     /// The generic Itanium ABI is the standard ABI of most open-source
29     /// and Unix-like platforms.  It is the primary ABI targeted by
30     /// many compilers, including Clang and GCC.
31     ///
32     /// It is documented here:
33     ///   http://www.codesourcery.com/public/cxx-abi/
34     GenericItanium,
35 
36     /// The generic ARM ABI is a modified version of the Itanium ABI
37     /// proposed by ARM for use on ARM-based platforms.
38     ///
39     /// These changes include:
40     ///   - the representation of member function pointers is adjusted
41     ///     to not conflict with the 'thumb' bit of ARM function pointers;
42     ///   - constructors and destructors return 'this';
43     ///   - guard variables are smaller;
44     ///   - inline functions are never key functions;
45     ///   - array cookies have a slightly different layout;
46     ///   - additional convenience functions are specified;
47     ///   - and more!
48     ///
49     /// It is documented here:
50     ///    http://infocenter.arm.com
51     ///                    /help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf
52     GenericARM,
53 
54     /// The iOS ABI is a partial implementation of the ARM ABI.
55     /// Several of the features of the ARM ABI were not fully implemented
56     /// in the compilers that iOS was launched with.
57     ///
58     /// Essentially, the iOS ABI includes the ARM changes to:
59     ///   - member function pointers,
60     ///   - guard variables,
61     ///   - array cookies, and
62     ///   - constructor/destructor signatures.
63     iOS,
64 
65     /// The iOS 64-bit and macOS 64-bit ARM ABI follows ARM's published 64-bit
66     /// ABI more closely, but we don't guarantee to follow it perfectly.
67     ///
68     /// It is documented here:
69     ///    http://infocenter.arm.com
70     ///                  /help/topic/com.arm.doc.ihi0059a/IHI0059A_cppabi64.pdf
71     AppleARM64,
72 
73     /// WatchOS is a modernisation of the iOS ABI, which roughly means it's
74     /// the AppleARM64 ABI ported to 32-bits. The primary difference from
75     /// AppleARM64 is that RTTI objects must still be unique at the moment.
76     WatchOS,
77 
78     /// The generic AArch64 ABI is also a modified version of the Itanium ABI,
79     /// but it has fewer divergences than the 32-bit ARM ABI.
80     ///
81     /// The relevant changes from the generic ABI in this case are:
82     ///   - representation of member function pointers adjusted as in ARM.
83     ///   - guard variables  are smaller.
84     GenericAArch64,
85 
86     /// The generic Mips ABI is a modified version of the Itanium ABI.
87     ///
88     /// At the moment, only change from the generic ABI in this case is:
89     ///   - representation of member function pointers adjusted as in ARM.
90     GenericMIPS,
91 
92     /// The WebAssembly ABI is a modified version of the Itanium ABI.
93     ///
94     /// The changes from the Itanium ABI are:
95     ///   - representation of member function pointers is adjusted, as in ARM;
96     ///   - member functions are not specially aligned;
97     ///   - constructors and destructors return 'this', as in ARM;
98     ///   - guard variables are 32-bit on wasm32, as in ARM;
99     ///   - unused bits of guard variables are reserved, as in ARM;
100     ///   - inline functions are never key functions, as in ARM;
101     ///   - C++11 POD rules are used for tail padding, as in AppleARM64.
102     ///
103     /// TODO: At present the WebAssembly ABI is not considered stable, so none
104     /// of these details is necessarily final yet.
105     WebAssembly,
106 
107     /// The Fuchsia ABI is a modified version of the Itanium ABI.
108     ///
109     /// The relevant changes from the Itanium ABI are:
110     ///   - constructors and destructors return 'this', as in ARM.
111     Fuchsia,
112 
113     /// The XL ABI is the ABI used by IBM xlclang compiler and is a modified
114     /// version of the Itanium ABI.
115     ///
116     /// The relevant changes from the Itanium ABI are:
117     ///   - static initialization is adjusted to use sinit and sterm functions;
118     XL,
119 
120     /// The Microsoft ABI is the ABI used by Microsoft Visual Studio (and
121     /// compatible compilers).
122     ///
123     /// FIXME: should this be split into Win32 and Win64 variants?
124     ///
125     /// Only scattered and incomplete official documentation exists.
126     Microsoft
127   };
128 
129 private:
130   // Right now, this class is passed around as a cheap value type.
131   // If you add more members, especially non-POD members, please
132   // audit the users to pass it by reference instead.
133   Kind TheKind;
134 
135 public:
136   /// A bogus initialization of the platform ABI.
137   TargetCXXABI() : TheKind(GenericItanium) {}
138 
139   TargetCXXABI(Kind kind) : TheKind(kind) {}
140 
141   void set(Kind kind) {
142     TheKind = kind;
143   }
144 
145   Kind getKind() const { return TheKind; }
146 
147   /// Does this ABI generally fall into the Itanium family of ABIs?
148   bool isItaniumFamily() const {
149     switch (getKind()) {
150     case AppleARM64:
151     case Fuchsia:
152     case GenericAArch64:
153     case GenericItanium:
154     case GenericARM:
155     case iOS:
156     case WatchOS:
157     case GenericMIPS:
158     case WebAssembly:
159     case XL:
160       return true;
161 
162     case Microsoft:
163       return false;
164     }
165     llvm_unreachable("bad ABI kind");
166   }
167 
168   /// Is this ABI an MSVC-compatible ABI?
169   bool isMicrosoft() const {
170     switch (getKind()) {
171     case AppleARM64:
172     case Fuchsia:
173     case GenericAArch64:
174     case GenericItanium:
175     case GenericARM:
176     case iOS:
177     case WatchOS:
178     case GenericMIPS:
179     case WebAssembly:
180     case XL:
181       return false;
182 
183     case Microsoft:
184       return true;
185     }
186     llvm_unreachable("bad ABI kind");
187   }
188 
189   /// Are member functions differently aligned?
190   ///
191   /// Many Itanium-style C++ ABIs require member functions to be aligned, so
192   /// that a pointer to such a function is guaranteed to have a zero in the
193   /// least significant bit, so that pointers to member functions can use that
194   /// bit to distinguish between virtual and non-virtual functions. However,
195   /// some Itanium-style C++ ABIs differentiate between virtual and non-virtual
196   /// functions via other means, and consequently don't require that member
197   /// functions be aligned.
198   bool areMemberFunctionsAligned() const {
199     switch (getKind()) {
200     case WebAssembly:
201       // WebAssembly doesn't require any special alignment for member functions.
202       return false;
203     case AppleARM64:
204     case Fuchsia:
205     case GenericARM:
206     case GenericAArch64:
207     case GenericMIPS:
208       // TODO: ARM-style pointers to member functions put the discriminator in
209       //       the this adjustment, so they don't require functions to have any
210       //       special alignment and could therefore also return false.
211     case GenericItanium:
212     case iOS:
213     case WatchOS:
214     case Microsoft:
215     case XL:
216       return true;
217     }
218     llvm_unreachable("bad ABI kind");
219   }
220 
221   /// Are arguments to a call destroyed left to right in the callee?
222   /// This is a fundamental language change, since it implies that objects
223   /// passed by value do *not* live to the end of the full expression.
224   /// Temporaries passed to a function taking a const reference live to the end
225   /// of the full expression as usual.  Both the caller and the callee must
226   /// have access to the destructor, while only the caller needs the
227   /// destructor if this is false.
228   bool areArgsDestroyedLeftToRightInCallee() const {
229     return isMicrosoft();
230   }
231 
232   /// Does this ABI have different entrypoints for complete-object
233   /// and base-subobject constructors?
234   bool hasConstructorVariants() const {
235     return isItaniumFamily();
236   }
237 
238   /// Does this ABI allow virtual bases to be primary base classes?
239   bool hasPrimaryVBases() const {
240     return isItaniumFamily();
241   }
242 
243   /// Does this ABI use key functions?  If so, class data such as the
244   /// vtable is emitted with strong linkage by the TU containing the key
245   /// function.
246   bool hasKeyFunctions() const {
247     return isItaniumFamily();
248   }
249 
250   /// Can an out-of-line inline function serve as a key function?
251   ///
252   /// This flag is only useful in ABIs where type data (for example,
253   /// vtables and type_info objects) are emitted only after processing
254   /// the definition of a special "key" virtual function.  (This is safe
255   /// because the ODR requires that every virtual function be defined
256   /// somewhere in a program.)  This usually permits such data to be
257   /// emitted in only a single object file, as opposed to redundantly
258   /// in every object file that requires it.
259   ///
260   /// One simple and common definition of "key function" is the first
261   /// virtual function in the class definition which is not defined there.
262   /// This rule works very well when that function has a non-inline
263   /// definition in some non-header file.  Unfortunately, when that
264   /// function is defined inline, this rule requires the type data
265   /// to be emitted weakly, as if there were no key function.
266   ///
267   /// The ARM ABI observes that the ODR provides an additional guarantee:
268   /// a virtual function is always ODR-used, so if it is defined inline,
269   /// that definition must appear in every translation unit that defines
270   /// the class.  Therefore, there is no reason to allow such functions
271   /// to serve as key functions.
272   ///
273   /// Because this changes the rules for emitting type data,
274   /// it can cause type data to be emitted with both weak and strong
275   /// linkage, which is not allowed on all platforms.  Therefore,
276   /// exploiting this observation requires an ABI break and cannot be
277   /// done on a generic Itanium platform.
278   bool canKeyFunctionBeInline() const {
279     switch (getKind()) {
280     case AppleARM64:
281     case Fuchsia:
282     case GenericARM:
283     case WebAssembly:
284     case WatchOS:
285       return false;
286 
287     case GenericAArch64:
288     case GenericItanium:
289     case iOS:   // old iOS compilers did not follow this rule
290     case Microsoft:
291     case GenericMIPS:
292     case XL:
293       return true;
294     }
295     llvm_unreachable("bad ABI kind");
296   }
297 
298   /// When is record layout allowed to allocate objects in the tail
299   /// padding of a base class?
300   ///
301   /// This decision cannot be changed without breaking platform ABI
302   /// compatibility. In ISO C++98, tail padding reuse was only permitted for
303   /// non-POD base classes, but that restriction was removed retroactively by
304   /// DR 43, and tail padding reuse is always permitted in all de facto C++
305   /// language modes. However, many platforms use a variant of the old C++98
306   /// rule for compatibility.
307   enum TailPaddingUseRules {
308     /// The tail-padding of a base class is always theoretically
309     /// available, even if it's POD.
310     AlwaysUseTailPadding,
311 
312     /// Only allocate objects in the tail padding of a base class if
313     /// the base class is not POD according to the rules of C++ TR1.
314     UseTailPaddingUnlessPOD03,
315 
316     /// Only allocate objects in the tail padding of a base class if
317     /// the base class is not POD according to the rules of C++11.
318     UseTailPaddingUnlessPOD11
319   };
320   TailPaddingUseRules getTailPaddingUseRules() const {
321     switch (getKind()) {
322     // To preserve binary compatibility, the generic Itanium ABI has
323     // permanently locked the definition of POD to the rules of C++ TR1,
324     // and that trickles down to derived ABIs.
325     case GenericItanium:
326     case GenericAArch64:
327     case GenericARM:
328     case iOS:
329     case GenericMIPS:
330     case XL:
331       return UseTailPaddingUnlessPOD03;
332 
333     // AppleARM64 and WebAssembly use the C++11 POD rules.  They do not honor
334     // the Itanium exception about classes with over-large bitfields.
335     case AppleARM64:
336     case Fuchsia:
337     case WebAssembly:
338     case WatchOS:
339       return UseTailPaddingUnlessPOD11;
340 
341     // MSVC always allocates fields in the tail-padding of a base class
342     // subobject, even if they're POD.
343     case Microsoft:
344       return AlwaysUseTailPadding;
345     }
346     llvm_unreachable("bad ABI kind");
347   }
348 
349   friend bool operator==(const TargetCXXABI &left, const TargetCXXABI &right) {
350     return left.getKind() == right.getKind();
351   }
352 
353   friend bool operator!=(const TargetCXXABI &left, const TargetCXXABI &right) {
354     return !(left == right);
355   }
356 };
357 
358 }  // end namespace clang
359 
360 #endif
361