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