summaryrefslogtreecommitdiffstats
path: root/include/clang/Basic/TargetCXXABI.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Basic/TargetCXXABI.h')
-rw-r--r--include/clang/Basic/TargetCXXABI.h354
1 files changed, 0 insertions, 354 deletions
diff --git a/include/clang/Basic/TargetCXXABI.h b/include/clang/Basic/TargetCXXABI.h
deleted file mode 100644
index 67247ea..0000000
--- a/include/clang/Basic/TargetCXXABI.h
+++ /dev/null
@@ -1,354 +0,0 @@
-//===--- TargetCXXABI.h - C++ ABI Target Configuration ----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Defines the TargetCXXABI class, which abstracts details of the
-/// C++ ABI that we're targeting.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_TARGETCXXABI_H
-#define LLVM_CLANG_BASIC_TARGETCXXABI_H
-
-#include "llvm/ADT/Triple.h"
-#include "llvm/Support/ErrorHandling.h"
-
-namespace clang {
-
-/// \brief The basic abstraction for the target C++ ABI.
-class TargetCXXABI {
-public:
- /// \brief The basic C++ ABI kind.
- enum Kind {
- /// The generic Itanium ABI is the standard ABI of most open-source
- /// and Unix-like platforms. It is the primary ABI targeted by
- /// many compilers, including Clang and GCC.
- ///
- /// It is documented here:
- /// http://www.codesourcery.com/public/cxx-abi/
- GenericItanium,
-
- /// The generic ARM ABI is a modified version of the Itanium ABI
- /// proposed by ARM for use on ARM-based platforms.
- ///
- /// These changes include:
- /// - the representation of member function pointers is adjusted
- /// to not conflict with the 'thumb' bit of ARM function pointers;
- /// - constructors and destructors return 'this';
- /// - guard variables are smaller;
- /// - inline functions are never key functions;
- /// - array cookies have a slightly different layout;
- /// - additional convenience functions are specified;
- /// - and more!
- ///
- /// It is documented here:
- /// http://infocenter.arm.com
- /// /help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf
- GenericARM,
-
- /// The iOS ABI is a partial implementation of the ARM ABI.
- /// Several of the features of the ARM ABI were not fully implemented
- /// in the compilers that iOS was launched with.
- ///
- /// Essentially, the iOS ABI includes the ARM changes to:
- /// - member function pointers,
- /// - guard variables,
- /// - array cookies, and
- /// - constructor/destructor signatures.
- iOS,
-
- /// The iOS 64-bit ABI is follows ARM's published 64-bit ABI more
- /// closely, but we don't guarantee to follow it perfectly.
- ///
- /// It is documented here:
- /// http://infocenter.arm.com
- /// /help/topic/com.arm.doc.ihi0059a/IHI0059A_cppabi64.pdf
- iOS64,
-
- /// WatchOS is a modernisation of the iOS ABI, which roughly means it's
- /// the iOS64 ABI ported to 32-bits. The primary difference from iOS64 is
- /// that RTTI objects must still be unique at the moment.
- WatchOS,
-
- /// The generic AArch64 ABI is also a modified version of the Itanium ABI,
- /// but it has fewer divergences than the 32-bit ARM ABI.
- ///
- /// The relevant changes from the generic ABI in this case are:
- /// - representation of member function pointers adjusted as in ARM.
- /// - guard variables are smaller.
- GenericAArch64,
-
- /// The generic Mips ABI is a modified version of the Itanium ABI.
- ///
- /// At the moment, only change from the generic ABI in this case is:
- /// - representation of member function pointers adjusted as in ARM.
- GenericMIPS,
-
- /// The WebAssembly ABI is a modified version of the Itanium ABI.
- ///
- /// The changes from the Itanium ABI are:
- /// - representation of member function pointers is adjusted, as in ARM;
- /// - member functions are not specially aligned;
- /// - constructors and destructors return 'this', as in ARM;
- /// - guard variables are 32-bit on wasm32, as in ARM;
- /// - unused bits of guard variables are reserved, as in ARM;
- /// - inline functions are never key functions, as in ARM;
- /// - C++11 POD rules are used for tail padding, as in iOS64.
- ///
- /// TODO: At present the WebAssembly ABI is not considered stable, so none
- /// of these details is necessarily final yet.
- WebAssembly,
-
- /// The Microsoft ABI is the ABI used by Microsoft Visual Studio (and
- /// compatible compilers).
- ///
- /// FIXME: should this be split into Win32 and Win64 variants?
- ///
- /// Only scattered and incomplete official documentation exists.
- Microsoft
- };
-
-private:
- // Right now, this class is passed around as a cheap value type.
- // If you add more members, especially non-POD members, please
- // audit the users to pass it by reference instead.
- Kind TheKind;
-
-public:
- /// A bogus initialization of the platform ABI.
- TargetCXXABI() : TheKind(GenericItanium) {}
-
- TargetCXXABI(Kind kind) : TheKind(kind) {}
-
- void set(Kind kind) {
- TheKind = kind;
- }
-
- Kind getKind() const { return TheKind; }
-
- /// \brief Does this ABI generally fall into the Itanium family of ABIs?
- bool isItaniumFamily() const {
- switch (getKind()) {
- case GenericAArch64:
- case GenericItanium:
- case GenericARM:
- case iOS:
- case iOS64:
- case WatchOS:
- case GenericMIPS:
- case WebAssembly:
- return true;
-
- case Microsoft:
- return false;
- }
- llvm_unreachable("bad ABI kind");
- }
-
- /// \brief Is this ABI an MSVC-compatible ABI?
- bool isMicrosoft() const {
- switch (getKind()) {
- case GenericAArch64:
- case GenericItanium:
- case GenericARM:
- case iOS:
- case iOS64:
- case WatchOS:
- case GenericMIPS:
- case WebAssembly:
- return false;
-
- case Microsoft:
- return true;
- }
- llvm_unreachable("bad ABI kind");
- }
-
- /// \brief Are member functions differently aligned?
- ///
- /// Many Itanium-style C++ ABIs require member functions to be aligned, so
- /// that a pointer to such a function is guaranteed to have a zero in the
- /// least significant bit, so that pointers to member functions can use that
- /// bit to distinguish between virtual and non-virtual functions. However,
- /// some Itanium-style C++ ABIs differentiate between virtual and non-virtual
- /// functions via other means, and consequently don't require that member
- /// functions be aligned.
- bool areMemberFunctionsAligned() const {
- switch (getKind()) {
- case WebAssembly:
- // WebAssembly doesn't require any special alignment for member functions.
- return false;
- case GenericARM:
- case GenericAArch64:
- case GenericMIPS:
- // TODO: ARM-style pointers to member functions put the discriminator in
- // the this adjustment, so they don't require functions to have any
- // special alignment and could therefore also return false.
- case GenericItanium:
- case iOS:
- case iOS64:
- case WatchOS:
- case Microsoft:
- return true;
- }
- llvm_unreachable("bad ABI kind");
- }
-
- /// \brief Is the default C++ member function calling convention
- /// the same as the default calling convention?
- bool isMemberFunctionCCDefault() const {
- // Right now, this is always false for Microsoft.
- return !isMicrosoft();
- }
-
- /// Are arguments to a call destroyed left to right in the callee?
- /// This is a fundamental language change, since it implies that objects
- /// passed by value do *not* live to the end of the full expression.
- /// Temporaries passed to a function taking a const reference live to the end
- /// of the full expression as usual. Both the caller and the callee must
- /// have access to the destructor, while only the caller needs the
- /// destructor if this is false.
- bool areArgsDestroyedLeftToRightInCallee() const {
- return isMicrosoft();
- }
-
- /// \brief Does this ABI have different entrypoints for complete-object
- /// and base-subobject constructors?
- bool hasConstructorVariants() const {
- return isItaniumFamily();
- }
-
- /// \brief Does this ABI allow virtual bases to be primary base classes?
- bool hasPrimaryVBases() const {
- return isItaniumFamily();
- }
-
- /// \brief Does this ABI use key functions? If so, class data such as the
- /// vtable is emitted with strong linkage by the TU containing the key
- /// function.
- bool hasKeyFunctions() const {
- return isItaniumFamily();
- }
-
- /// \brief Can an out-of-line inline function serve as a key function?
- ///
- /// This flag is only useful in ABIs where type data (for example,
- /// v-tables and type_info objects) are emitted only after processing
- /// the definition of a special "key" virtual function. (This is safe
- /// because the ODR requires that every virtual function be defined
- /// somewhere in a program.) This usually permits such data to be
- /// emitted in only a single object file, as opposed to redundantly
- /// in every object file that requires it.
- ///
- /// One simple and common definition of "key function" is the first
- /// virtual function in the class definition which is not defined there.
- /// This rule works very well when that function has a non-inline
- /// definition in some non-header file. Unfortunately, when that
- /// function is defined inline, this rule requires the type data
- /// to be emitted weakly, as if there were no key function.
- ///
- /// The ARM ABI observes that the ODR provides an additional guarantee:
- /// a virtual function is always ODR-used, so if it is defined inline,
- /// that definition must appear in every translation unit that defines
- /// the class. Therefore, there is no reason to allow such functions
- /// to serve as key functions.
- ///
- /// Because this changes the rules for emitting type data,
- /// it can cause type data to be emitted with both weak and strong
- /// linkage, which is not allowed on all platforms. Therefore,
- /// exploiting this observation requires an ABI break and cannot be
- /// done on a generic Itanium platform.
- bool canKeyFunctionBeInline() const {
- switch (getKind()) {
- case GenericARM:
- case iOS64:
- case WebAssembly:
- case WatchOS:
- return false;
-
- case GenericAArch64:
- case GenericItanium:
- case iOS: // old iOS compilers did not follow this rule
- case Microsoft:
- case GenericMIPS:
- return true;
- }
- llvm_unreachable("bad ABI kind");
- }
-
- /// When is record layout allowed to allocate objects in the tail
- /// padding of a base class?
- ///
- /// This decision cannot be changed without breaking platform ABI
- /// compatibility, and yet it is tied to language guarantees which
- /// the committee has so far seen fit to strengthen no less than
- /// three separate times:
- /// - originally, there were no restrictions at all;
- /// - C++98 declared that objects could not be allocated in the
- /// tail padding of a POD type;
- /// - C++03 extended the definition of POD to include classes
- /// containing member pointers; and
- /// - C++11 greatly broadened the definition of POD to include
- /// all trivial standard-layout classes.
- /// Each of these changes technically took several existing
- /// platforms and made them permanently non-conformant.
- enum TailPaddingUseRules {
- /// The tail-padding of a base class is always theoretically
- /// available, even if it's POD. This is not strictly conforming
- /// in any language mode.
- AlwaysUseTailPadding,
-
- /// Only allocate objects in the tail padding of a base class if
- /// the base class is not POD according to the rules of C++ TR1.
- /// This is non-strictly conforming in C++11 mode.
- UseTailPaddingUnlessPOD03,
-
- /// Only allocate objects in the tail padding of a base class if
- /// the base class is not POD according to the rules of C++11.
- UseTailPaddingUnlessPOD11
- };
- TailPaddingUseRules getTailPaddingUseRules() const {
- switch (getKind()) {
- // To preserve binary compatibility, the generic Itanium ABI has
- // permanently locked the definition of POD to the rules of C++ TR1,
- // and that trickles down to derived ABIs.
- case GenericItanium:
- case GenericAArch64:
- case GenericARM:
- case iOS:
- case GenericMIPS:
- return UseTailPaddingUnlessPOD03;
-
- // iOS on ARM64 and WebAssembly use the C++11 POD rules. They do not honor
- // the Itanium exception about classes with over-large bitfields.
- case iOS64:
- case WebAssembly:
- case WatchOS:
- return UseTailPaddingUnlessPOD11;
-
- // MSVC always allocates fields in the tail-padding of a base class
- // subobject, even if they're POD.
- case Microsoft:
- return AlwaysUseTailPadding;
- }
- llvm_unreachable("bad ABI kind");
- }
-
- friend bool operator==(const TargetCXXABI &left, const TargetCXXABI &right) {
- return left.getKind() == right.getKind();
- }
-
- friend bool operator!=(const TargetCXXABI &left, const TargetCXXABI &right) {
- return !(left == right);
- }
-};
-
-} // end namespace clang
-
-#endif
OpenPOWER on IntegriCloud