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