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 <map>
19
20#include "clang/Basic/LLVM.h"
21#include "llvm/ADT/StringMap.h"
22#include "llvm/ADT/Triple.h"
23#include "llvm/Support/ErrorHandling.h"
24
25namespace clang {
26
27/// The basic abstraction for the target C++ ABI.
28class TargetCXXABI {
29public:
30  /// The basic C++ ABI kind.
31  enum Kind {
32#define CXXABI(Name, Str) Name,
33#include "TargetCXXABI.def"
34  };
35
36private:
37  // Right now, this class is passed around as a cheap value type.
38  // If you add more members, especially non-POD members, please
39  // audit the users to pass it by reference instead.
40  Kind TheKind;
41
42  static const auto &getABIMap() {
43    static llvm::StringMap<Kind> ABIMap = {
44#define CXXABI(Name, Str) {Str, Name},
45#include "TargetCXXABI.def"
46    };
47    return ABIMap;
48  }
49
50  static const auto &getSpellingMap() {
51    static std::map<Kind, std::string> SpellingMap = {
52#define CXXABI(Name, Str) {Name, Str},
53#include "TargetCXXABI.def"
54    };
55    return SpellingMap;
56  }
57
58public:
59  static Kind getKind(StringRef Name) { return getABIMap().lookup(Name); }
60  static const auto &getSpelling(Kind ABIKind) {
61    return getSpellingMap().find(ABIKind)->second;
62  }
63  static bool isABI(StringRef Name) {
64    return getABIMap().find(Name) != getABIMap().end();
65  }
66
67  /// A bogus initialization of the platform ABI.
68  TargetCXXABI() : TheKind(GenericItanium) {}
69
70  TargetCXXABI(Kind kind) : TheKind(kind) {}
71
72  void set(Kind kind) {
73    TheKind = kind;
74  }
75
76  Kind getKind() const { return TheKind; }
77
78  // Check that the kind provided by the fc++-abi flag is supported on this
79  // target. Users who want to experiment using different ABIs on specific
80  // platforms can change this freely, but this function should be conservative
81  // enough such that not all ABIs are allowed on all platforms. For example, we
82  // probably don't want to allow usage of an ARM ABI on an x86 architecture.
83  static bool isSupportedCXXABI(const llvm::Triple &T, Kind Kind) {
84    switch (Kind) {
85    case GenericARM:
86      return T.isARM() || T.isAArch64();
87
88    case iOS:
89    case WatchOS:
90    case AppleARM64:
91      return T.isOSDarwin();
92
93    case Fuchsia:
94      return T.isOSFuchsia();
95
96    case GenericAArch64:
97      return T.isAArch64();
98
99    case GenericMIPS:
100      return T.isMIPS();
101
102    case WebAssembly:
103      return T.isWasm();
104
105    case XL:
106      return T.isOSAIX();
107
108    case GenericItanium:
109      return true;
110
111    case Microsoft:
112      return T.isKnownWindowsMSVCEnvironment();
113    }
114    llvm_unreachable("invalid CXXABI kind");
115  };
116
117  /// Does this ABI generally fall into the Itanium family of ABIs?
118  bool isItaniumFamily() const {
119    switch (getKind()) {
120#define CXXABI(Name, Str)
121#define ITANIUM_CXXABI(Name, Str) case Name:
122#include "TargetCXXABI.def"
123      return true;
124
125    default:
126      return false;
127    }
128    llvm_unreachable("bad ABI kind");
129  }
130
131  /// Is this ABI an MSVC-compatible ABI?
132  bool isMicrosoft() const {
133    switch (getKind()) {
134#define CXXABI(Name, Str)
135#define MICROSOFT_CXXABI(Name, Str) case Name:
136#include "TargetCXXABI.def"
137      return true;
138
139    default:
140      return false;
141    }
142    llvm_unreachable("bad ABI kind");
143  }
144
145  /// Are member functions differently aligned?
146  ///
147  /// Many Itanium-style C++ ABIs require member functions to be aligned, so
148  /// that a pointer to such a function is guaranteed to have a zero in the
149  /// least significant bit, so that pointers to member functions can use that
150  /// bit to distinguish between virtual and non-virtual functions. However,
151  /// some Itanium-style C++ ABIs differentiate between virtual and non-virtual
152  /// functions via other means, and consequently don't require that member
153  /// functions be aligned.
154  bool areMemberFunctionsAligned() const {
155    switch (getKind()) {
156    case WebAssembly:
157      // WebAssembly doesn't require any special alignment for member functions.
158      return false;
159    case AppleARM64:
160    case Fuchsia:
161    case GenericARM:
162    case GenericAArch64:
163    case GenericMIPS:
164      // TODO: ARM-style pointers to member functions put the discriminator in
165      //       the this adjustment, so they don't require functions to have any
166      //       special alignment and could therefore also return false.
167    case GenericItanium:
168    case iOS:
169    case WatchOS:
170    case Microsoft:
171    case XL:
172      return true;
173    }
174    llvm_unreachable("bad ABI kind");
175  }
176
177  /// Are arguments to a call destroyed left to right in the callee?
178  /// This is a fundamental language change, since it implies that objects
179  /// passed by value do *not* live to the end of the full expression.
180  /// Temporaries passed to a function taking a const reference live to the end
181  /// of the full expression as usual.  Both the caller and the callee must
182  /// have access to the destructor, while only the caller needs the
183  /// destructor if this is false.
184  bool areArgsDestroyedLeftToRightInCallee() const {
185    return isMicrosoft();
186  }
187
188  /// Does this ABI have different entrypoints for complete-object
189  /// and base-subobject constructors?
190  bool hasConstructorVariants() const {
191    return isItaniumFamily();
192  }
193
194  /// Does this ABI allow virtual bases to be primary base classes?
195  bool hasPrimaryVBases() const {
196    return isItaniumFamily();
197  }
198
199  /// Does this ABI use key functions?  If so, class data such as the
200  /// vtable is emitted with strong linkage by the TU containing the key
201  /// function.
202  bool hasKeyFunctions() const {
203    return isItaniumFamily();
204  }
205
206  /// Can an out-of-line inline function serve as a key function?
207  ///
208  /// This flag is only useful in ABIs where type data (for example,
209  /// vtables and type_info objects) are emitted only after processing
210  /// the definition of a special "key" virtual function.  (This is safe
211  /// because the ODR requires that every virtual function be defined
212  /// somewhere in a program.)  This usually permits such data to be
213  /// emitted in only a single object file, as opposed to redundantly
214  /// in every object file that requires it.
215  ///
216  /// One simple and common definition of "key function" is the first
217  /// virtual function in the class definition which is not defined there.
218  /// This rule works very well when that function has a non-inline
219  /// definition in some non-header file.  Unfortunately, when that
220  /// function is defined inline, this rule requires the type data
221  /// to be emitted weakly, as if there were no key function.
222  ///
223  /// The ARM ABI observes that the ODR provides an additional guarantee:
224  /// a virtual function is always ODR-used, so if it is defined inline,
225  /// that definition must appear in every translation unit that defines
226  /// the class.  Therefore, there is no reason to allow such functions
227  /// to serve as key functions.
228  ///
229  /// Because this changes the rules for emitting type data,
230  /// it can cause type data to be emitted with both weak and strong
231  /// linkage, which is not allowed on all platforms.  Therefore,
232  /// exploiting this observation requires an ABI break and cannot be
233  /// done on a generic Itanium platform.
234  bool canKeyFunctionBeInline() const {
235    switch (getKind()) {
236    case AppleARM64:
237    case Fuchsia:
238    case GenericARM:
239    case WebAssembly:
240    case WatchOS:
241      return false;
242
243    case GenericAArch64:
244    case GenericItanium:
245    case iOS:   // old iOS compilers did not follow this rule
246    case Microsoft:
247    case GenericMIPS:
248    case XL:
249      return true;
250    }
251    llvm_unreachable("bad ABI kind");
252  }
253
254  /// When is record layout allowed to allocate objects in the tail
255  /// padding of a base class?
256  ///
257  /// This decision cannot be changed without breaking platform ABI
258  /// compatibility. In ISO C++98, tail padding reuse was only permitted for
259  /// non-POD base classes, but that restriction was removed retroactively by
260  /// DR 43, and tail padding reuse is always permitted in all de facto C++
261  /// language modes. However, many platforms use a variant of the old C++98
262  /// rule for compatibility.
263  enum TailPaddingUseRules {
264    /// The tail-padding of a base class is always theoretically
265    /// available, even if it's POD.
266    AlwaysUseTailPadding,
267
268    /// Only allocate objects in the tail padding of a base class if
269    /// the base class is not POD according to the rules of C++ TR1.
270    UseTailPaddingUnlessPOD03,
271
272    /// Only allocate objects in the tail padding of a base class if
273    /// the base class is not POD according to the rules of C++11.
274    UseTailPaddingUnlessPOD11
275  };
276  TailPaddingUseRules getTailPaddingUseRules() const {
277    switch (getKind()) {
278    // To preserve binary compatibility, the generic Itanium ABI has
279    // permanently locked the definition of POD to the rules of C++ TR1,
280    // and that trickles down to derived ABIs.
281    case GenericItanium:
282    case GenericAArch64:
283    case GenericARM:
284    case iOS:
285    case GenericMIPS:
286    case XL:
287      return UseTailPaddingUnlessPOD03;
288
289    // AppleARM64 and WebAssembly use the C++11 POD rules.  They do not honor
290    // the Itanium exception about classes with over-large bitfields.
291    case AppleARM64:
292    case Fuchsia:
293    case WebAssembly:
294    case WatchOS:
295      return UseTailPaddingUnlessPOD11;
296
297    // MSVC always allocates fields in the tail-padding of a base class
298    // subobject, even if they're POD.
299    case Microsoft:
300      return AlwaysUseTailPadding;
301    }
302    llvm_unreachable("bad ABI kind");
303  }
304
305  friend bool operator==(const TargetCXXABI &left, const TargetCXXABI &right) {
306    return left.getKind() == right.getKind();
307  }
308
309  friend bool operator!=(const TargetCXXABI &left, const TargetCXXABI &right) {
310    return !(left == right);
311  }
312};
313
314}  // end namespace clang
315
316#endif
317