clang 22.0.0git
TargetCXXABI.h
Go to the documentation of this file.
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
25namespace clang {
26
27/// The basic abstraction for the target C++ ABI.
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 }
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) { 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.
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.
189 return isMicrosoft();
190 }
191
192 /// Does this ABI have different entrypoints for complete-object
193 /// and base-subobject constructors?
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.
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.
268 /// The tail-padding of a base class is always theoretically
269 /// available, even if it's POD.
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.
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.
279 };
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:
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:
300
301 // MSVC always allocates fields in the tail-padding of a base class
302 // subobject, even if they're POD.
303 case Microsoft:
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
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
TargetCXXABI()
A bogus initialization of the platform ABI.
static bool isSupportedCXXABI(const llvm::Triple &T, Kind Kind)
static const auto & getSpelling(Kind ABIKind)
TargetCXXABI(Kind kind)
static bool usesRelativeVTables(const llvm::Triple &T)
TailPaddingUseRules getTailPaddingUseRules() const
bool hasConstructorVariants() const
Does this ABI have different entrypoints for complete-object and base-subobject constructors?
bool areArgsDestroyedLeftToRightInCallee() const
Are arguments to a call destroyed left to right in the callee?
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
bool hasPrimaryVBases() const
Does this ABI allow virtual bases to be primary base classes?
static bool isABI(StringRef Name)
bool canKeyFunctionBeInline() const
Can an out-of-line inline function serve as a key function?
Kind getKind() const
friend bool operator==(const TargetCXXABI &left, const TargetCXXABI &right)
void set(Kind kind)
TailPaddingUseRules
When is record layout allowed to allocate objects in the tail padding of a base class?
@ AlwaysUseTailPadding
The tail-padding of a base class is always theoretically available, even if it's POD.
@ UseTailPaddingUnlessPOD11
Only allocate objects in the tail padding of a base class if the base class is not POD according to t...
@ UseTailPaddingUnlessPOD03
Only allocate objects in the tail padding of a base class if the base class is not POD according to t...
bool isItaniumFamily() const
Does this ABI generally fall into the Itanium family of ABIs?
bool areMemberFunctionsAligned() const
Are member functions differently aligned?
bool hasKeyFunctions() const
Does this ABI use key functions?
Kind
The basic C++ ABI kind.
static Kind getKind(StringRef Name)
friend bool operator!=(const TargetCXXABI &left, const TargetCXXABI &right)
WebAssembly builtins.
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T