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