diff options
author | John McCall <rjmccall@apple.com> | 2013-01-25 22:30:49 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2013-01-25 22:30:49 +0000 |
commit | b8b2c9da87e7d70a1679db026f40548b3192b705 (patch) | |
tree | faa4fbe6a64798098a71a21c89b2efc392f393e5 /include/clang | |
parent | d07865b42dcb32154c75134fded51b38cc55a0c4 (diff) |
First pass at abstracting out a class for the target C++ ABI.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@173514 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang')
-rw-r--r-- | include/clang/Basic/TargetCXXABI.h | 159 | ||||
-rw-r--r-- | include/clang/Basic/TargetInfo.h | 36 |
2 files changed, 167 insertions, 28 deletions
diff --git a/include/clang/Basic/TargetCXXABI.h b/include/clang/Basic/TargetCXXABI.h new file mode 100644 index 0000000000..2a8f5d0df5 --- /dev/null +++ b/include/clang/Basic/TargetCXXABI.h @@ -0,0 +1,159 @@ +//===--- 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_TARGETCXXABI_H +#define LLVM_CLANG_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 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 GenericItanium: + case GenericARM: + case iOS: + 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 GenericItanium: + case GenericARM: + case iOS: + return false; + + 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 true for Microsoft. + 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 have different entrypoints for complete-object + /// and base-subobject destructors? + bool hasDestructorVariants() const { + return isItaniumFamily(); + } + + /// \brief Does this ABI allow virtual bases to be primary base classes? + bool hasPrimaryVBases() const { + return isItaniumFamily(); + } + + /// Try to parse an ABI name, returning false on error. + bool tryParse(llvm::StringRef name); + + 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 diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index 463c2ea691..716d776df6 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -16,6 +16,7 @@ #define LLVM_CLANG_BASIC_TARGETINFO_H #include "clang/Basic/AddressSpaces.h" +#include "clang/Basic/TargetCXXABI.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/Specifiers.h" #include "clang/Basic/TargetOptions.h" @@ -43,22 +44,6 @@ class SourceManager; namespace Builtin { struct Info; } -/// \brief The types of C++ ABIs for which we can generate code. -enum TargetCXXABI { - /// The generic ("Itanium") C++ ABI, documented at: - /// http://www.codesourcery.com/public/cxx-abi/ - CXXABI_Itanium, - - /// The ARM C++ ABI, based largely on the Itanium ABI but with - /// significant differences. - /// http://infocenter.arm.com - /// /help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf - CXXABI_ARM, - - /// The Visual Studio ABI. Only scattered official documentation exists. - CXXABI_Microsoft -}; - /// \brief Exposes information about the current target. /// class TargetInfo : public RefCountedBase<TargetInfo> { @@ -89,7 +74,7 @@ protected: const llvm::fltSemantics *HalfFormat, *FloatFormat, *DoubleFormat, *LongDoubleFormat; unsigned char RegParmMax, SSERegParmMax; - TargetCXXABI CXXABI; + TargetCXXABI TheCXXABI; const LangAS::Map *AddrSpaceMap; mutable StringRef PlatformName; @@ -634,8 +619,8 @@ public: } /// \brief Get the C++ ABI currently in use. - virtual TargetCXXABI getCXXABI() const { - return CXXABI; + TargetCXXABI getCXXABI() const { + return TheCXXABI; } /// \brief Target the specified CPU. @@ -655,14 +640,9 @@ public: /// \brief Use this specified C++ ABI. /// /// \return False on error (invalid C++ ABI name). - bool setCXXABI(const std::string &Name) { - static const TargetCXXABI Unknown = static_cast<TargetCXXABI>(-1); - TargetCXXABI ABI = llvm::StringSwitch<TargetCXXABI>(Name) - .Case("arm", CXXABI_ARM) - .Case("itanium", CXXABI_Itanium) - .Case("microsoft", CXXABI_Microsoft) - .Default(Unknown); - if (ABI == Unknown) return false; + bool setCXXABI(llvm::StringRef name) { + TargetCXXABI ABI; + if (!ABI.tryParse(name)) return false; return setCXXABI(ABI); } @@ -670,7 +650,7 @@ public: /// /// \return False on error (ABI not valid on this target) virtual bool setCXXABI(TargetCXXABI ABI) { - CXXABI = ABI; + TheCXXABI = ABI; return true; } |