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