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