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