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_TARGETCXXABI_H
17#define LLVM_CLANG_TARGETCXXABI_H
18
19#include "llvm/ADT/Triple.h"
20#include "llvm/Support/ErrorHandling.h"
21
22namespace clang {
23
24/// \brief The basic abstraction for the target C++ ABI.
25class TargetCXXABI {
26public:
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    /// The generic AArch64 ABI is also a modified version of the Itanium ABI,
75    /// but it has fewer divergences than the 32-bit ARM ABI.
76    ///
77    /// The relevant changes from the generic ABI in this case are:
78    ///   - representation of member function pointers adjusted as in ARM.
79    ///   - guard variables  are smaller.
80    GenericAArch64,
81
82    /// The Microsoft ABI is the ABI used by Microsoft Visual Studio (and
83    /// compatible compilers).
84    ///
85    /// FIXME: should this be split into Win32 and Win64 variants?
86    ///
87    /// Only scattered and incomplete official documentation exists.
88    Microsoft
89  };
90
91private:
92  // Right now, this class is passed around as a cheap value type.
93  // If you add more members, especially non-POD members, please
94  // audit the users to pass it by reference instead.
95  Kind TheKind;
96
97public:
98  /// A bogus initialization of the platform ABI.
99  TargetCXXABI() : TheKind(GenericItanium) {}
100
101  TargetCXXABI(Kind kind) : TheKind(kind) {}
102
103  void set(Kind kind) {
104    TheKind = kind;
105  }
106
107  Kind getKind() const { return TheKind; }
108
109  /// \brief Does this ABI generally fall into the Itanium family of ABIs?
110  bool isItaniumFamily() const {
111    switch (getKind()) {
112    case GenericAArch64:
113    case GenericItanium:
114    case GenericARM:
115    case iOS:
116    case iOS64:
117      return true;
118
119    case Microsoft:
120      return false;
121    }
122    llvm_unreachable("bad ABI kind");
123  }
124
125  /// \brief Is this ABI an MSVC-compatible ABI?
126  bool isMicrosoft() const {
127    switch (getKind()) {
128    case GenericAArch64:
129    case GenericItanium:
130    case GenericARM:
131    case iOS:
132    case iOS64:
133      return false;
134
135    case Microsoft:
136      return true;
137    }
138    llvm_unreachable("bad ABI kind");
139  }
140
141  /// \brief Is the default C++ member function calling convention
142  /// the same as the default calling convention?
143  bool isMemberFunctionCCDefault() const {
144    // Right now, this is always false for Microsoft.
145    return !isMicrosoft();
146  }
147
148  /// Are arguments to a call destroyed left to right in the callee?
149  /// This is a fundamental language change, since it implies that objects
150  /// passed by value do *not* live to the end of the full expression.
151  /// Temporaries passed to a function taking a const reference live to the end
152  /// of the full expression as usual.  Both the caller and the callee must
153  /// have access to the destructor, while only the caller needs the
154  /// destructor if this is false.
155  bool areArgsDestroyedLeftToRightInCallee() const {
156    return isMicrosoft();
157  }
158
159  /// \brief Does this ABI have different entrypoints for complete-object
160  /// and base-subobject constructors?
161  bool hasConstructorVariants() const {
162    return isItaniumFamily();
163  }
164
165  /// \brief Does this ABI allow virtual bases to be primary base classes?
166  bool hasPrimaryVBases() const {
167    return isItaniumFamily();
168  }
169
170  /// \brief Does this ABI use key functions?  If so, class data such as the
171  /// vtable is emitted with strong linkage by the TU containing the key
172  /// function.
173  bool hasKeyFunctions() const {
174    return isItaniumFamily();
175  }
176
177  /// \brief Can an out-of-line inline function serve as a key function?
178  ///
179  /// This flag is only useful in ABIs where type data (for example,
180  /// v-tables and type_info objects) are emitted only after processing
181  /// the definition of a special "key" virtual function.  (This is safe
182  /// because the ODR requires that every virtual function be defined
183  /// somewhere in a program.)  This usually permits such data to be
184  /// emitted in only a single object file, as opposed to redundantly
185  /// in every object file that requires it.
186  ///
187  /// One simple and common definition of "key function" is the first
188  /// virtual function in the class definition which is not defined there.
189  /// This rule works very well when that function has a non-inline
190  /// definition in some non-header file.  Unfortunately, when that
191  /// function is defined inline, this rule requires the type data
192  /// to be emitted weakly, as if there were no key function.
193  ///
194  /// The ARM ABI observes that the ODR provides an additional guarantee:
195  /// a virtual function is always ODR-used, so if it is defined inline,
196  /// that definition must appear in every translation unit that defines
197  /// the class.  Therefore, there is no reason to allow such functions
198  /// to serve as key functions.
199  ///
200  /// Because this changes the rules for emitting type data,
201  /// it can cause type data to be emitted with both weak and strong
202  /// linkage, which is not allowed on all platforms.  Therefore,
203  /// exploiting this observation requires an ABI break and cannot be
204  /// done on a generic Itanium platform.
205  bool canKeyFunctionBeInline() const {
206    switch (getKind()) {
207    case GenericARM:
208    case iOS64:
209      return false;
210
211    case GenericAArch64:
212    case GenericItanium:
213    case iOS:   // old iOS compilers did not follow this rule
214    case Microsoft:
215      return true;
216    }
217    llvm_unreachable("bad ABI kind");
218  }
219
220  /// When is record layout allowed to allocate objects in the tail
221  /// padding of a base class?
222  ///
223  /// This decision cannot be changed without breaking platform ABI
224  /// compatibility, and yet it is tied to language guarantees which
225  /// the committee has so far seen fit to strengthen no less than
226  /// three separate times:
227  ///   - originally, there were no restrictions at all;
228  ///   - C++98 declared that objects could not be allocated in the
229  ///     tail padding of a POD type;
230  ///   - C++03 extended the definition of POD to include classes
231  ///     containing member pointers; and
232  ///   - C++11 greatly broadened the definition of POD to include
233  ///     all trivial standard-layout classes.
234  /// Each of these changes technically took several existing
235  /// platforms and made them permanently non-conformant.
236  enum TailPaddingUseRules {
237    /// The tail-padding of a base class is always theoretically
238    /// available, even if it's POD.  This is not strictly conforming
239    /// in any language mode.
240    AlwaysUseTailPadding,
241
242    /// Only allocate objects in the tail padding of a base class if
243    /// the base class is not POD according to the rules of C++ TR1.
244    /// This is non-strictly conforming in C++11 mode.
245    UseTailPaddingUnlessPOD03,
246
247    /// Only allocate objects in the tail padding of a base class if
248    /// the base class is not POD according to the rules of C++11.
249    UseTailPaddingUnlessPOD11
250  };
251  TailPaddingUseRules getTailPaddingUseRules() const {
252    switch (getKind()) {
253    // To preserve binary compatibility, the generic Itanium ABI has
254    // permanently locked the definition of POD to the rules of C++ TR1,
255    // and that trickles down to all the derived ABIs.
256    case GenericItanium:
257    case GenericAArch64:
258    case GenericARM:
259    case iOS:
260      return UseTailPaddingUnlessPOD03;
261
262    // iOS on ARM64 uses the C++11 POD rules.  It does not honor the
263    // Itanium exception about classes with over-large bitfields.
264    case iOS64:
265      return UseTailPaddingUnlessPOD11;
266
267    // MSVC always allocates fields in the tail-padding of a base class
268    // subobject, even if they're POD.
269    case Microsoft:
270      return AlwaysUseTailPadding;
271    }
272    llvm_unreachable("bad ABI kind");
273  }
274
275  /// Try to parse an ABI name, returning false on error.
276  bool tryParse(llvm::StringRef name);
277
278  friend bool operator==(const TargetCXXABI &left, const TargetCXXABI &right) {
279    return left.getKind() == right.getKind();
280  }
281
282  friend bool operator!=(const TargetCXXABI &left, const TargetCXXABI &right) {
283    return !(left == right);
284  }
285};
286
287}  // end namespace clang
288
289#endif
290