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 
25 namespace clang {
26 
27 /// The basic abstraction for the target C++ ABI.
28 class TargetCXXABI {
29 public:
30   /// The basic C++ ABI kind.
31   enum Kind {
32 #define CXXABI(Name, Str) Name,
33 #include "TargetCXXABI.def"
34   };
35 
36 private:
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 
getABIMap()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 
getSpellingMap()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 
58 public:
getKind(StringRef Name)59   static Kind getKind(StringRef Name) { return getABIMap().lookup(Name); }
getSpelling(Kind ABIKind)60   static const auto &getSpelling(Kind ABIKind) {
61     return getSpellingMap().find(ABIKind)->second;
62   }
isABI(StringRef Name)63   static bool isABI(StringRef Name) {
64     return getABIMap().find(Name) != getABIMap().end();
65   }
66 
67   /// A bogus initialization of the platform ABI.
TargetCXXABI()68   TargetCXXABI() : TheKind(GenericItanium) {}
69 
TargetCXXABI(Kind kind)70   TargetCXXABI(Kind kind) : TheKind(kind) {}
71 
set(Kind kind)72   void set(Kind kind) {
73     TheKind = kind;
74   }
75 
getKind()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.
isSupportedCXXABI(const llvm::Triple & T,Kind Kind)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?
isItaniumFamily()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?
isMicrosoft()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.
areMemberFunctionsAligned()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.
areArgsDestroyedLeftToRightInCallee()184   bool areArgsDestroyedLeftToRightInCallee() const {
185     return isMicrosoft();
186   }
187 
188   /// Does this ABI have different entrypoints for complete-object
189   /// and base-subobject constructors?
hasConstructorVariants()190   bool hasConstructorVariants() const {
191     return isItaniumFamily();
192   }
193 
194   /// Does this ABI allow virtual bases to be primary base classes?
hasPrimaryVBases()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.
hasKeyFunctions()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.
canKeyFunctionBeInline()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   };
getTailPaddingUseRules()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