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