1249261Sdim//===--- TargetCXXABI.h - C++ ABI Target Configuration ----------*- C++ -*-===// 2249261Sdim// 3249261Sdim// The LLVM Compiler Infrastructure 4249261Sdim// 5249261Sdim// This file is distributed under the University of Illinois Open Source 6249261Sdim// License. See LICENSE.TXT for details. 7249261Sdim// 8249261Sdim//===----------------------------------------------------------------------===// 9249261Sdim/// 10249261Sdim/// \file 11249261Sdim/// \brief Defines the TargetCXXABI class, which abstracts details of the 12249261Sdim/// C++ ABI that we're targeting. 13249261Sdim/// 14249261Sdim//===----------------------------------------------------------------------===// 15249261Sdim 16249261Sdim#ifndef LLVM_CLANG_TARGETCXXABI_H 17249261Sdim#define LLVM_CLANG_TARGETCXXABI_H 18249261Sdim 19249261Sdim#include "llvm/ADT/Triple.h" 20249261Sdim#include "llvm/Support/ErrorHandling.h" 21249261Sdim 22249261Sdimnamespace clang { 23249261Sdim 24249261Sdim/// \brief The basic abstraction for the target C++ ABI. 25249261Sdimclass TargetCXXABI { 26249261Sdimpublic: 27249261Sdim /// \brief The basic C++ ABI kind. 28249261Sdim enum Kind { 29249261Sdim /// The generic Itanium ABI is the standard ABI of most open-source 30249261Sdim /// and Unix-like platforms. It is the primary ABI targeted by 31249261Sdim /// many compilers, including Clang and GCC. 32249261Sdim /// 33249261Sdim /// It is documented here: 34249261Sdim /// http://www.codesourcery.com/public/cxx-abi/ 35249261Sdim GenericItanium, 36249261Sdim 37249261Sdim /// The generic ARM ABI is a modified version of the Itanium ABI 38249261Sdim /// proposed by ARM for use on ARM-based platforms. 39249261Sdim /// 40249261Sdim /// These changes include: 41249261Sdim /// - the representation of member function pointers is adjusted 42249261Sdim /// to not conflict with the 'thumb' bit of ARM function pointers; 43249261Sdim /// - constructors and destructors return 'this'; 44249261Sdim /// - guard variables are smaller; 45249261Sdim /// - inline functions are never key functions; 46249261Sdim /// - array cookies have a slightly different layout; 47249261Sdim /// - additional convenience functions are specified; 48249261Sdim /// - and more! 49249261Sdim /// 50249261Sdim /// It is documented here: 51249261Sdim /// http://infocenter.arm.com 52249261Sdim /// /help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf 53249261Sdim GenericARM, 54249261Sdim 55249261Sdim /// The iOS ABI is a partial implementation of the ARM ABI. 56249261Sdim /// Several of the features of the ARM ABI were not fully implemented 57249261Sdim /// in the compilers that iOS was launched with. 58249261Sdim /// 59249261Sdim /// Essentially, the iOS ABI includes the ARM changes to: 60249261Sdim /// - member function pointers, 61249261Sdim /// - guard variables, 62249261Sdim /// - array cookies, and 63249261Sdim /// - constructor/destructor signatures. 64249261Sdim iOS, 65249261Sdim 66249261Sdim /// The generic AArch64 ABI is also a modified version of the Itanium ABI, 67249261Sdim /// but it has fewer divergences than the 32-bit ARM ABI. 68249261Sdim /// 69249261Sdim /// The relevant changes from the generic ABI in this case are: 70249261Sdim /// - representation of member function pointers adjusted as in ARM. 71249261Sdim /// - guard variables are smaller. 72249261Sdim GenericAArch64, 73249261Sdim 74249261Sdim /// The Microsoft ABI is the ABI used by Microsoft Visual Studio (and 75249261Sdim /// compatible compilers). 76249261Sdim /// 77249261Sdim /// FIXME: should this be split into Win32 and Win64 variants? 78249261Sdim /// 79249261Sdim /// Only scattered and incomplete official documentation exists. 80249261Sdim Microsoft 81249261Sdim }; 82249261Sdim 83249261Sdimprivate: 84249261Sdim // Right now, this class is passed around as a cheap value type. 85249261Sdim // If you add more members, especially non-POD members, please 86249261Sdim // audit the users to pass it by reference instead. 87249261Sdim Kind TheKind; 88249261Sdim 89249261Sdimpublic: 90249261Sdim /// A bogus initialization of the platform ABI. 91249261Sdim TargetCXXABI() : TheKind(GenericItanium) {} 92249261Sdim 93249261Sdim TargetCXXABI(Kind kind) : TheKind(kind) {} 94249261Sdim 95249261Sdim void set(Kind kind) { 96249261Sdim TheKind = kind; 97249261Sdim } 98249261Sdim 99249261Sdim Kind getKind() const { return TheKind; } 100249261Sdim 101249261Sdim /// \brief Does this ABI generally fall into the Itanium family of ABIs? 102249261Sdim bool isItaniumFamily() const { 103249261Sdim switch (getKind()) { 104249261Sdim case GenericAArch64: 105249261Sdim case GenericItanium: 106249261Sdim case GenericARM: 107249261Sdim case iOS: 108249261Sdim return true; 109249261Sdim 110249261Sdim case Microsoft: 111249261Sdim return false; 112249261Sdim } 113249261Sdim llvm_unreachable("bad ABI kind"); 114249261Sdim } 115249261Sdim 116249261Sdim /// \brief Is this ABI an MSVC-compatible ABI? 117249261Sdim bool isMicrosoft() const { 118249261Sdim switch (getKind()) { 119249261Sdim case GenericAArch64: 120249261Sdim case GenericItanium: 121249261Sdim case GenericARM: 122249261Sdim case iOS: 123249261Sdim return false; 124249261Sdim 125249261Sdim case Microsoft: 126249261Sdim return true; 127249261Sdim } 128249261Sdim llvm_unreachable("bad ABI kind"); 129249261Sdim } 130249261Sdim 131249261Sdim /// \brief Is the default C++ member function calling convention 132249261Sdim /// the same as the default calling convention? 133249261Sdim bool isMemberFunctionCCDefault() const { 134263508Sdim // Right now, this is always false for Microsoft. 135249261Sdim return !isMicrosoft(); 136249261Sdim } 137249261Sdim 138263508Sdim /// Are temporary objects passed by value to a call destroyed by the callee? 139263508Sdim /// This is a fundamental language change, since it implies that objects 140263508Sdim /// passed by value do *not* live to the end of the full expression. 141263508Sdim /// Temporaries passed to a function taking a const reference live to the end 142263508Sdim /// of the full expression as usual. Both the caller and the callee must 143263508Sdim /// have access to the destructor, while only the caller needs the 144263508Sdim /// destructor if this is false. 145263508Sdim bool isArgumentDestroyedByCallee() const { 146263508Sdim return isMicrosoft(); 147263508Sdim } 148263508Sdim 149249261Sdim /// \brief Does this ABI have different entrypoints for complete-object 150249261Sdim /// and base-subobject constructors? 151249261Sdim bool hasConstructorVariants() const { 152249261Sdim return isItaniumFamily(); 153249261Sdim } 154249261Sdim 155263508Sdim /// \brief Does this ABI allow virtual bases to be primary base classes? 156263508Sdim bool hasPrimaryVBases() const { 157249261Sdim return isItaniumFamily(); 158249261Sdim } 159249261Sdim 160263508Sdim /// \brief Does this ABI use key functions? If so, class data such as the 161263508Sdim /// vtable is emitted with strong linkage by the TU containing the key 162263508Sdim /// function. 163263508Sdim bool hasKeyFunctions() const { 164249261Sdim return isItaniumFamily(); 165249261Sdim } 166249261Sdim 167249261Sdim /// \brief Can an out-of-line inline function serve as a key function? 168249261Sdim /// 169249261Sdim /// This flag is only useful in ABIs where type data (for example, 170249261Sdim /// v-tables and type_info objects) are emitted only after processing 171249261Sdim /// the definition of a special "key" virtual function. (This is safe 172249261Sdim /// because the ODR requires that every virtual function be defined 173249261Sdim /// somewhere in a program.) This usually permits such data to be 174249261Sdim /// emitted in only a single object file, as opposed to redundantly 175249261Sdim /// in every object file that requires it. 176249261Sdim /// 177249261Sdim /// One simple and common definition of "key function" is the first 178249261Sdim /// virtual function in the class definition which is not defined there. 179249261Sdim /// This rule works very well when that function has a non-inline 180249261Sdim /// definition in some non-header file. Unfortunately, when that 181249261Sdim /// function is defined inline, this rule requires the type data 182249261Sdim /// to be emitted weakly, as if there were no key function. 183249261Sdim /// 184249261Sdim /// The ARM ABI observes that the ODR provides an additional guarantee: 185249261Sdim /// a virtual function is always ODR-used, so if it is defined inline, 186249261Sdim /// that definition must appear in every translation unit that defines 187249261Sdim /// the class. Therefore, there is no reason to allow such functions 188249261Sdim /// to serve as key functions. 189249261Sdim /// 190249261Sdim /// Because this changes the rules for emitting type data, 191249261Sdim /// it can cause type data to be emitted with both weak and strong 192249261Sdim /// linkage, which is not allowed on all platforms. Therefore, 193249261Sdim /// exploiting this observation requires an ABI break and cannot be 194249261Sdim /// done on a generic Itanium platform. 195249261Sdim bool canKeyFunctionBeInline() const { 196249261Sdim switch (getKind()) { 197249261Sdim case GenericARM: 198249261Sdim return false; 199249261Sdim 200249261Sdim case GenericAArch64: 201249261Sdim case GenericItanium: 202249261Sdim case iOS: // old iOS compilers did not follow this rule 203249261Sdim case Microsoft: 204249261Sdim return true; 205249261Sdim } 206249261Sdim llvm_unreachable("bad ABI kind"); 207249261Sdim } 208249261Sdim 209249261Sdim /// When is record layout allowed to allocate objects in the tail 210249261Sdim /// padding of a base class? 211249261Sdim /// 212249261Sdim /// This decision cannot be changed without breaking platform ABI 213249261Sdim /// compatibility, and yet it is tied to language guarantees which 214249261Sdim /// the committee has so far seen fit to strengthen no less than 215249261Sdim /// three separate times: 216249261Sdim /// - originally, there were no restrictions at all; 217249261Sdim /// - C++98 declared that objects could not be allocated in the 218249261Sdim /// tail padding of a POD type; 219249261Sdim /// - C++03 extended the definition of POD to include classes 220249261Sdim /// containing member pointers; and 221249261Sdim /// - C++11 greatly broadened the definition of POD to include 222249261Sdim /// all trivial standard-layout classes. 223249261Sdim /// Each of these changes technically took several existing 224249261Sdim /// platforms and made them permanently non-conformant. 225249261Sdim enum TailPaddingUseRules { 226249261Sdim /// The tail-padding of a base class is always theoretically 227249261Sdim /// available, even if it's POD. This is not strictly conforming 228249261Sdim /// in any language mode. 229249261Sdim AlwaysUseTailPadding, 230249261Sdim 231249261Sdim /// Only allocate objects in the tail padding of a base class if 232249261Sdim /// the base class is not POD according to the rules of C++ TR1. 233249261Sdim /// This is non strictly conforming in C++11 mode. 234249261Sdim UseTailPaddingUnlessPOD03, 235249261Sdim 236249261Sdim /// Only allocate objects in the tail padding of a base class if 237249261Sdim /// the base class is not POD according to the rules of C++11. 238249261Sdim UseTailPaddingUnlessPOD11 239249261Sdim }; 240249261Sdim TailPaddingUseRules getTailPaddingUseRules() const { 241249261Sdim switch (getKind()) { 242249261Sdim // To preserve binary compatibility, the generic Itanium ABI has 243249261Sdim // permanently locked the definition of POD to the rules of C++ TR1, 244249261Sdim // and that trickles down to all the derived ABIs. 245249261Sdim case GenericItanium: 246249261Sdim case GenericAArch64: 247249261Sdim case GenericARM: 248249261Sdim case iOS: 249249261Sdim return UseTailPaddingUnlessPOD03; 250249261Sdim 251249261Sdim // MSVC always allocates fields in the tail-padding of a base class 252249261Sdim // subobject, even if they're POD. 253249261Sdim case Microsoft: 254249261Sdim return AlwaysUseTailPadding; 255249261Sdim } 256249261Sdim llvm_unreachable("bad ABI kind"); 257249261Sdim } 258249261Sdim 259249261Sdim /// Try to parse an ABI name, returning false on error. 260249261Sdim bool tryParse(llvm::StringRef name); 261249261Sdim 262249261Sdim friend bool operator==(const TargetCXXABI &left, const TargetCXXABI &right) { 263249261Sdim return left.getKind() == right.getKind(); 264249261Sdim } 265249261Sdim 266249261Sdim friend bool operator!=(const TargetCXXABI &left, const TargetCXXABI &right) { 267249261Sdim return !(left == right); 268249261Sdim } 269249261Sdim}; 270249261Sdim 271249261Sdim} // end namespace clang 272249261Sdim 273249261Sdim#endif 274