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