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