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 Microsoft ABI is the ABI used by Microsoft Visual Studio (and 113 /// compatible compilers). 114 /// 115 /// FIXME: should this be split into Win32 and Win64 variants? 116 /// 117 /// Only scattered and incomplete official documentation exists. 118 Microsoft 119 }; 120 121 private: 122 // Right now, this class is passed around as a cheap value type. 123 // If you add more members, especially non-POD members, please 124 // audit the users to pass it by reference instead. 125 Kind TheKind; 126 127 public: 128 /// A bogus initialization of the platform ABI. 129 TargetCXXABI() : TheKind(GenericItanium) {} 130 131 TargetCXXABI(Kind kind) : TheKind(kind) {} 132 133 void set(Kind kind) { 134 TheKind = kind; 135 } 136 137 Kind getKind() const { return TheKind; } 138 139 /// Does this ABI generally fall into the Itanium family of ABIs? 140 bool isItaniumFamily() const { 141 switch (getKind()) { 142 case Fuchsia: 143 case GenericAArch64: 144 case GenericItanium: 145 case GenericARM: 146 case iOS: 147 case iOS64: 148 case WatchOS: 149 case GenericMIPS: 150 case WebAssembly: 151 return true; 152 153 case Microsoft: 154 return false; 155 } 156 llvm_unreachable("bad ABI kind"); 157 } 158 159 /// Is this ABI an MSVC-compatible ABI? 160 bool isMicrosoft() const { 161 switch (getKind()) { 162 case Fuchsia: 163 case GenericAArch64: 164 case GenericItanium: 165 case GenericARM: 166 case iOS: 167 case iOS64: 168 case WatchOS: 169 case GenericMIPS: 170 case WebAssembly: 171 return false; 172 173 case Microsoft: 174 return true; 175 } 176 llvm_unreachable("bad ABI kind"); 177 } 178 179 /// Are member functions differently aligned? 180 /// 181 /// Many Itanium-style C++ ABIs require member functions to be aligned, so 182 /// that a pointer to such a function is guaranteed to have a zero in the 183 /// least significant bit, so that pointers to member functions can use that 184 /// bit to distinguish between virtual and non-virtual functions. However, 185 /// some Itanium-style C++ ABIs differentiate between virtual and non-virtual 186 /// functions via other means, and consequently don't require that member 187 /// functions be aligned. 188 bool areMemberFunctionsAligned() const { 189 switch (getKind()) { 190 case WebAssembly: 191 // WebAssembly doesn't require any special alignment for member functions. 192 return false; 193 case Fuchsia: 194 case GenericARM: 195 case GenericAArch64: 196 case GenericMIPS: 197 // TODO: ARM-style pointers to member functions put the discriminator in 198 // the this adjustment, so they don't require functions to have any 199 // special alignment and could therefore also return false. 200 case GenericItanium: 201 case iOS: 202 case iOS64: 203 case WatchOS: 204 case Microsoft: 205 return true; 206 } 207 llvm_unreachable("bad ABI kind"); 208 } 209 210 /// Are arguments to a call destroyed left to right in the callee? 211 /// This is a fundamental language change, since it implies that objects 212 /// passed by value do *not* live to the end of the full expression. 213 /// Temporaries passed to a function taking a const reference live to the end 214 /// of the full expression as usual. Both the caller and the callee must 215 /// have access to the destructor, while only the caller needs the 216 /// destructor if this is false. 217 bool areArgsDestroyedLeftToRightInCallee() const { 218 return isMicrosoft(); 219 } 220 221 /// Does this ABI have different entrypoints for complete-object 222 /// and base-subobject constructors? 223 bool hasConstructorVariants() const { 224 return isItaniumFamily(); 225 } 226 227 /// Does this ABI allow virtual bases to be primary base classes? 228 bool hasPrimaryVBases() const { 229 return isItaniumFamily(); 230 } 231 232 /// Does this ABI use key functions? If so, class data such as the 233 /// vtable is emitted with strong linkage by the TU containing the key 234 /// function. 235 bool hasKeyFunctions() const { 236 return isItaniumFamily(); 237 } 238 239 /// Can an out-of-line inline function serve as a key function? 240 /// 241 /// This flag is only useful in ABIs where type data (for example, 242 /// vtables and type_info objects) are emitted only after processing 243 /// the definition of a special "key" virtual function. (This is safe 244 /// because the ODR requires that every virtual function be defined 245 /// somewhere in a program.) This usually permits such data to be 246 /// emitted in only a single object file, as opposed to redundantly 247 /// in every object file that requires it. 248 /// 249 /// One simple and common definition of "key function" is the first 250 /// virtual function in the class definition which is not defined there. 251 /// This rule works very well when that function has a non-inline 252 /// definition in some non-header file. Unfortunately, when that 253 /// function is defined inline, this rule requires the type data 254 /// to be emitted weakly, as if there were no key function. 255 /// 256 /// The ARM ABI observes that the ODR provides an additional guarantee: 257 /// a virtual function is always ODR-used, so if it is defined inline, 258 /// that definition must appear in every translation unit that defines 259 /// the class. Therefore, there is no reason to allow such functions 260 /// to serve as key functions. 261 /// 262 /// Because this changes the rules for emitting type data, 263 /// it can cause type data to be emitted with both weak and strong 264 /// linkage, which is not allowed on all platforms. Therefore, 265 /// exploiting this observation requires an ABI break and cannot be 266 /// done on a generic Itanium platform. 267 bool canKeyFunctionBeInline() const { 268 switch (getKind()) { 269 case Fuchsia: 270 case GenericARM: 271 case iOS64: 272 case WebAssembly: 273 case WatchOS: 274 return false; 275 276 case GenericAArch64: 277 case GenericItanium: 278 case iOS: // old iOS compilers did not follow this rule 279 case Microsoft: 280 case GenericMIPS: 281 return true; 282 } 283 llvm_unreachable("bad ABI kind"); 284 } 285 286 /// When is record layout allowed to allocate objects in the tail 287 /// padding of a base class? 288 /// 289 /// This decision cannot be changed without breaking platform ABI 290 /// compatibility. In ISO C++98, tail padding reuse was only permitted for 291 /// non-POD base classes, but that restriction was removed retroactively by 292 /// DR 43, and tail padding reuse is always permitted in all de facto C++ 293 /// language modes. However, many platforms use a variant of the old C++98 294 /// rule for compatibility. 295 enum TailPaddingUseRules { 296 /// The tail-padding of a base class is always theoretically 297 /// available, even if it's POD. 298 AlwaysUseTailPadding, 299 300 /// Only allocate objects in the tail padding of a base class if 301 /// the base class is not POD according to the rules of C++ TR1. 302 UseTailPaddingUnlessPOD03, 303 304 /// Only allocate objects in the tail padding of a base class if 305 /// the base class is not POD according to the rules of C++11. 306 UseTailPaddingUnlessPOD11 307 }; 308 TailPaddingUseRules getTailPaddingUseRules() const { 309 switch (getKind()) { 310 // To preserve binary compatibility, the generic Itanium ABI has 311 // permanently locked the definition of POD to the rules of C++ TR1, 312 // and that trickles down to derived ABIs. 313 case GenericItanium: 314 case GenericAArch64: 315 case GenericARM: 316 case iOS: 317 case GenericMIPS: 318 return UseTailPaddingUnlessPOD03; 319 320 // iOS on ARM64 and WebAssembly use the C++11 POD rules. They do not honor 321 // the Itanium exception about classes with over-large bitfields. 322 case Fuchsia: 323 case iOS64: 324 case WebAssembly: 325 case WatchOS: 326 return UseTailPaddingUnlessPOD11; 327 328 // MSVC always allocates fields in the tail-padding of a base class 329 // subobject, even if they're POD. 330 case Microsoft: 331 return AlwaysUseTailPadding; 332 } 333 llvm_unreachable("bad ABI kind"); 334 } 335 336 friend bool operator==(const TargetCXXABI &left, const TargetCXXABI &right) { 337 return left.getKind() == right.getKind(); 338 } 339 340 friend bool operator!=(const TargetCXXABI &left, const TargetCXXABI &right) { 341 return !(left == right); 342 } 343 }; 344 345 } // end namespace clang 346 347 #endif 348