Home | History | Annotate | Line # | Download | only in Basic
      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   /// A bogus initialization of the platform ABI.
     68   TargetCXXABI() : TheKind(GenericItanium) {}
     69 
     70   TargetCXXABI(Kind kind) : TheKind(kind) {}
     71 
     72   void set(Kind kind) {
     73     TheKind = kind;
     74   }
     75 
     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.
     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?
    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?
    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.
    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.
    184   bool areArgsDestroyedLeftToRightInCallee() const {
    185     return isMicrosoft();
    186   }
    187 
    188   /// Does this ABI have different entrypoints for complete-object
    189   /// and base-subobject constructors?
    190   bool hasConstructorVariants() const {
    191     return isItaniumFamily();
    192   }
    193 
    194   /// Does this ABI allow virtual bases to be primary base classes?
    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.
    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.
    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   };
    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