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