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/ADT/Triple.h" 23 #include "llvm/Support/ErrorHandling.h" 24 25 namespace clang { 26 27 /// The basic abstraction for the target C++ ABI. 28 class TargetCXXABI { 29 public: 30 /// The basic C++ ABI kind. 31 enum Kind { 32 #define CXXABI(Name, Str) Name, 33 #include "TargetCXXABI.def" 34 }; 35 36 private: 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 getABIMap()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 getSpellingMap()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 } 57 58 public: getKind(StringRef Name)59 static Kind getKind(StringRef Name) { return getABIMap().lookup(Name); } getSpelling(Kind ABIKind)60 static const auto &getSpelling(Kind ABIKind) { 61 return getSpellingMap().find(ABIKind)->second; 62 } isABI(StringRef Name)63 static bool isABI(StringRef Name) { 64 return getABIMap().find(Name) != getABIMap().end(); 65 } 66 67 /// A bogus initialization of the platform ABI. TargetCXXABI()68 TargetCXXABI() : TheKind(GenericItanium) {} 69 TargetCXXABI(Kind kind)70 TargetCXXABI(Kind kind) : TheKind(kind) {} 71 set(Kind kind)72 void set(Kind kind) { 73 TheKind = kind; 74 } 75 getKind()76 Kind getKind() const { return TheKind; } 77 78 // Check that the kind provided by the fc++-abi flag is supported on this 79 // target. Users who want to experiment using different ABIs on specific 80 // platforms can change this freely, but this function should be conservative 81 // enough such that not all ABIs are allowed on all platforms. For example, we 82 // probably don't want to allow usage of an ARM ABI on an x86 architecture. isSupportedCXXABI(const llvm::Triple & T,Kind Kind)83 static bool isSupportedCXXABI(const llvm::Triple &T, Kind Kind) { 84 switch (Kind) { 85 case GenericARM: 86 return T.isARM() || T.isAArch64(); 87 88 case iOS: 89 case WatchOS: 90 case AppleARM64: 91 return T.isOSDarwin(); 92 93 case Fuchsia: 94 return T.isOSFuchsia(); 95 96 case GenericAArch64: 97 return T.isAArch64(); 98 99 case GenericMIPS: 100 return T.isMIPS(); 101 102 case WebAssembly: 103 return T.isWasm(); 104 105 case XL: 106 return T.isOSAIX(); 107 108 case GenericItanium: 109 return true; 110 111 case Microsoft: 112 return T.isKnownWindowsMSVCEnvironment(); 113 } 114 llvm_unreachable("invalid CXXABI kind"); 115 }; 116 117 /// Does this ABI generally fall into the Itanium family of ABIs? isItaniumFamily()118 bool isItaniumFamily() const { 119 switch (getKind()) { 120 #define CXXABI(Name, Str) 121 #define ITANIUM_CXXABI(Name, Str) case Name: 122 #include "TargetCXXABI.def" 123 return true; 124 125 default: 126 return false; 127 } 128 llvm_unreachable("bad ABI kind"); 129 } 130 131 /// Is this ABI an MSVC-compatible ABI? isMicrosoft()132 bool isMicrosoft() const { 133 switch (getKind()) { 134 #define CXXABI(Name, Str) 135 #define MICROSOFT_CXXABI(Name, Str) case Name: 136 #include "TargetCXXABI.def" 137 return true; 138 139 default: 140 return false; 141 } 142 llvm_unreachable("bad ABI kind"); 143 } 144 145 /// Are member functions differently aligned? 146 /// 147 /// Many Itanium-style C++ ABIs require member functions to be aligned, so 148 /// that a pointer to such a function is guaranteed to have a zero in the 149 /// least significant bit, so that pointers to member functions can use that 150 /// bit to distinguish between virtual and non-virtual functions. However, 151 /// some Itanium-style C++ ABIs differentiate between virtual and non-virtual 152 /// functions via other means, and consequently don't require that member 153 /// functions be aligned. areMemberFunctionsAligned()154 bool areMemberFunctionsAligned() const { 155 switch (getKind()) { 156 case WebAssembly: 157 // WebAssembly doesn't require any special alignment for member functions. 158 return false; 159 case AppleARM64: 160 case Fuchsia: 161 case GenericARM: 162 case GenericAArch64: 163 case GenericMIPS: 164 // TODO: ARM-style pointers to member functions put the discriminator in 165 // the this adjustment, so they don't require functions to have any 166 // special alignment and could therefore also return false. 167 case GenericItanium: 168 case iOS: 169 case WatchOS: 170 case Microsoft: 171 case XL: 172 return true; 173 } 174 llvm_unreachable("bad ABI kind"); 175 } 176 177 /// Are arguments to a call destroyed left to right in the callee? 178 /// This is a fundamental language change, since it implies that objects 179 /// passed by value do *not* live to the end of the full expression. 180 /// Temporaries passed to a function taking a const reference live to the end 181 /// of the full expression as usual. Both the caller and the callee must 182 /// have access to the destructor, while only the caller needs the 183 /// destructor if this is false. areArgsDestroyedLeftToRightInCallee()184 bool areArgsDestroyedLeftToRightInCallee() const { 185 return isMicrosoft(); 186 } 187 188 /// Does this ABI have different entrypoints for complete-object 189 /// and base-subobject constructors? hasConstructorVariants()190 bool hasConstructorVariants() const { 191 return isItaniumFamily(); 192 } 193 194 /// Does this ABI allow virtual bases to be primary base classes? hasPrimaryVBases()195 bool hasPrimaryVBases() const { 196 return isItaniumFamily(); 197 } 198 199 /// Does this ABI use key functions? If so, class data such as the 200 /// vtable is emitted with strong linkage by the TU containing the key 201 /// function. hasKeyFunctions()202 bool hasKeyFunctions() const { 203 return isItaniumFamily(); 204 } 205 206 /// Can an out-of-line inline function serve as a key function? 207 /// 208 /// This flag is only useful in ABIs where type data (for example, 209 /// vtables and type_info objects) are emitted only after processing 210 /// the definition of a special "key" virtual function. (This is safe 211 /// because the ODR requires that every virtual function be defined 212 /// somewhere in a program.) This usually permits such data to be 213 /// emitted in only a single object file, as opposed to redundantly 214 /// in every object file that requires it. 215 /// 216 /// One simple and common definition of "key function" is the first 217 /// virtual function in the class definition which is not defined there. 218 /// This rule works very well when that function has a non-inline 219 /// definition in some non-header file. Unfortunately, when that 220 /// function is defined inline, this rule requires the type data 221 /// to be emitted weakly, as if there were no key function. 222 /// 223 /// The ARM ABI observes that the ODR provides an additional guarantee: 224 /// a virtual function is always ODR-used, so if it is defined inline, 225 /// that definition must appear in every translation unit that defines 226 /// the class. Therefore, there is no reason to allow such functions 227 /// to serve as key functions. 228 /// 229 /// Because this changes the rules for emitting type data, 230 /// it can cause type data to be emitted with both weak and strong 231 /// linkage, which is not allowed on all platforms. Therefore, 232 /// exploiting this observation requires an ABI break and cannot be 233 /// done on a generic Itanium platform. canKeyFunctionBeInline()234 bool canKeyFunctionBeInline() const { 235 switch (getKind()) { 236 case AppleARM64: 237 case Fuchsia: 238 case GenericARM: 239 case WebAssembly: 240 case WatchOS: 241 return false; 242 243 case GenericAArch64: 244 case GenericItanium: 245 case iOS: // old iOS compilers did not follow this rule 246 case Microsoft: 247 case GenericMIPS: 248 case XL: 249 return true; 250 } 251 llvm_unreachable("bad ABI kind"); 252 } 253 254 /// When is record layout allowed to allocate objects in the tail 255 /// padding of a base class? 256 /// 257 /// This decision cannot be changed without breaking platform ABI 258 /// compatibility. In ISO C++98, tail padding reuse was only permitted for 259 /// non-POD base classes, but that restriction was removed retroactively by 260 /// DR 43, and tail padding reuse is always permitted in all de facto C++ 261 /// language modes. However, many platforms use a variant of the old C++98 262 /// rule for compatibility. 263 enum TailPaddingUseRules { 264 /// The tail-padding of a base class is always theoretically 265 /// available, even if it's POD. 266 AlwaysUseTailPadding, 267 268 /// Only allocate objects in the tail padding of a base class if 269 /// the base class is not POD according to the rules of C++ TR1. 270 UseTailPaddingUnlessPOD03, 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++11. 274 UseTailPaddingUnlessPOD11 275 }; getTailPaddingUseRules()276 TailPaddingUseRules getTailPaddingUseRules() const { 277 switch (getKind()) { 278 // To preserve binary compatibility, the generic Itanium ABI has 279 // permanently locked the definition of POD to the rules of C++ TR1, 280 // and that trickles down to derived ABIs. 281 case GenericItanium: 282 case GenericAArch64: 283 case GenericARM: 284 case iOS: 285 case GenericMIPS: 286 case XL: 287 return UseTailPaddingUnlessPOD03; 288 289 // AppleARM64 and WebAssembly use the C++11 POD rules. They do not honor 290 // the Itanium exception about classes with over-large bitfields. 291 case AppleARM64: 292 case Fuchsia: 293 case WebAssembly: 294 case WatchOS: 295 return UseTailPaddingUnlessPOD11; 296 297 // MSVC always allocates fields in the tail-padding of a base class 298 // subobject, even if they're POD. 299 case Microsoft: 300 return AlwaysUseTailPadding; 301 } 302 llvm_unreachable("bad ABI kind"); 303 } 304 305 friend bool operator==(const TargetCXXABI &left, const TargetCXXABI &right) { 306 return left.getKind() == right.getKind(); 307 } 308 309 friend bool operator!=(const TargetCXXABI &left, const TargetCXXABI &right) { 310 return !(left == right); 311 } 312 }; 313 314 } // end namespace clang 315 316 #endif 317