From 86353416a7115dc430b9cd47a1aaeb8f19c34f2c Mon Sep 17 00:00:00 2001 From: John McCall Date: Sat, 21 Aug 2010 22:46:04 +0000 Subject: [PATCH] The ARM C++ ABI is sufficiently different from the Itanium C++ ABI that it deserves its own enumerator. Obviously the implementations should closely follow the Itanium ABI except in cases of divergence. llvm-svn: 111749 --- clang/include/clang/Basic/TargetInfo.h | 29 +++++++++++++++++++---- clang/include/clang/Basic/TargetOptions.h | 5 ---- clang/lib/AST/ASTContext.cpp | 8 +++++-- clang/lib/AST/CXXABI.h | 1 + clang/lib/AST/ItaniumCXXABI.cpp | 13 ++++++++++ clang/lib/Basic/TargetInfo.cpp | 3 +++ clang/lib/Basic/Targets.cpp | 5 +++- clang/lib/CodeGen/CGCXXABI.h | 1 + clang/lib/CodeGen/CodeGenModule.cpp | 6 ++++- clang/lib/CodeGen/ItaniumCXXABI.cpp | 13 ++++++++++ 10 files changed, 70 insertions(+), 14 deletions(-) diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 11e009cb01ea..40df9ba11da4 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -40,8 +40,17 @@ namespace Builtin { struct Info; } /// TargetCXXABI - The types of C++ ABIs for which we can generate code. enum TargetCXXABI { - CXXABI_Unknown = -1, + /// 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 }; @@ -443,12 +452,22 @@ public: /// setCXXABI - Use this specific C++ ABI. /// /// \return - False on error (invalid C++ ABI name). - virtual bool setCXXABI(const std::string &Name) { - CXXABI = llvm::StringSwitch(Name) + bool setCXXABI(const std::string &Name) { + static const TargetCXXABI Unknown = static_cast(-1); + TargetCXXABI ABI = llvm::StringSwitch(Name) + .Case("arm", CXXABI_ARM) .Case("itanium", CXXABI_Itanium) .Case("microsoft", CXXABI_Microsoft) - .Default(CXXABI_Unknown); - if (CXXABI == CXXABI_Unknown) return false; + .Default(Unknown); + if (ABI == Unknown) return false; + return setCXXABI(ABI); + } + + /// setCXXABI - Set the C++ ABI to be used by this implementation. + /// + /// \return - False on error (ABI not valid on this target) + virtual bool setCXXABI(TargetCXXABI ABI) { + CXXABI = ABI; return true; } diff --git a/clang/include/clang/Basic/TargetOptions.h b/clang/include/clang/Basic/TargetOptions.h index b88b1f590e9e..f3c206f2cc96 100644 --- a/clang/include/clang/Basic/TargetOptions.h +++ b/clang/include/clang/Basic/TargetOptions.h @@ -18,11 +18,6 @@ namespace clang { /// TargetOptions - Options for controlling the target. class TargetOptions { public: - - TargetOptions() { - CXXABI = "itanium"; - } - /// If given, the name of the target triple to compile for. If not given the /// target will be selected to match the host. std::string Triple; diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index ee4608badc05..890dfc3490ad 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -136,13 +136,17 @@ ASTContext::getCanonicalTemplateTemplateParmDecl( } CXXABI *ASTContext::createCXXABI(const TargetInfo &T) { - if (!LangOpts.CPlusPlus) return NULL; + if (!LangOpts.CPlusPlus) return 0; + switch (T.getCXXABI()) { - default: + case CXXABI_ARM: + return CreateARMCXXABI(*this); + case CXXABI_Itanium: return CreateItaniumCXXABI(*this); case CXXABI_Microsoft: return CreateMicrosoftCXXABI(*this); } + return 0; } ASTContext::ASTContext(const LangOptions& LOpts, SourceManager &SM, diff --git a/clang/lib/AST/CXXABI.h b/clang/lib/AST/CXXABI.h index 8781bd7c75fc..4b38d7afb6a4 100644 --- a/clang/lib/AST/CXXABI.h +++ b/clang/lib/AST/CXXABI.h @@ -31,6 +31,7 @@ public: }; /// Creates an instance of a C++ ABI class. +CXXABI *CreateARMCXXABI(ASTContext &Ctx); CXXABI *CreateItaniumCXXABI(ASTContext &Ctx); CXXABI *CreateMicrosoftCXXABI(ASTContext &Ctx); } diff --git a/clang/lib/AST/ItaniumCXXABI.cpp b/clang/lib/AST/ItaniumCXXABI.cpp index 0ac80ecd6384..c3fa4666537b 100644 --- a/clang/lib/AST/ItaniumCXXABI.cpp +++ b/clang/lib/AST/ItaniumCXXABI.cpp @@ -11,6 +11,10 @@ // documented at: // http://www.codesourcery.com/public/cxx-abi/abi.html // http://www.codesourcery.com/public/cxx-abi/abi-eh.html +// +// It also supports the closely-related ARM C++ ABI, documented at: +// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf +// //===----------------------------------------------------------------------===// #include "CXXABI.h" @@ -21,6 +25,7 @@ using namespace clang; namespace { class ItaniumCXXABI : public CXXABI { +protected: ASTContext &Context; public: ItaniumCXXABI(ASTContext &Ctx) : Context(Ctx) { } @@ -31,9 +36,17 @@ public: return 1; } }; + +class ARMCXXABI : public ItaniumCXXABI { +public: + ARMCXXABI(ASTContext &Ctx) : ItaniumCXXABI(Ctx) { } +}; } CXXABI *clang::CreateItaniumCXXABI(ASTContext &Ctx) { return new ItaniumCXXABI(Ctx); } +CXXABI *clang::CreateARMCXXABI(ASTContext &Ctx) { + return new ARMCXXABI(Ctx); +} diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 7c42a80d1bb8..6d42883cd13c 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -58,6 +58,9 @@ TargetInfo::TargetInfo(const std::string &T) : Triple(T) { // Default to no types using fpret. RealTypeUsesObjCFPRet = 0; + + // Default to using the Itanium ABI. + CXXABI = CXXABI_Itanium; } // Out of line virtual dtor for TargetInfo. diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index 9dcb61eca842..cabe50a5600d 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -1585,6 +1585,9 @@ public: "i64:64:64-f32:32:32-f64:64:64-" "v64:64:64-v128:128:128-a0:0:64-n32"); } + + // ARM targets default to using the ARM C++ ABI. + CXXABI = CXXABI_ARM; } virtual const char *getABI() const { return ABI.c_str(); } virtual bool setABI(const std::string &Name) { @@ -2631,7 +2634,7 @@ TargetInfo *TargetInfo::CreateTargetInfo(Diagnostic &Diags, } // Set the target C++ ABI. - if (!Target->setCXXABI(Opts.CXXABI)) { + if (!Opts.CXXABI.empty() && !Target->setCXXABI(Opts.CXXABI)) { Diags.Report(diag::err_target_unknown_cxxabi) << Opts.CXXABI; return 0; } diff --git a/clang/lib/CodeGen/CGCXXABI.h b/clang/lib/CodeGen/CGCXXABI.h index 0cebcb1c31bc..7df63d38befd 100644 --- a/clang/lib/CodeGen/CGCXXABI.h +++ b/clang/lib/CodeGen/CGCXXABI.h @@ -30,6 +30,7 @@ public: }; /// Creates an instance of a C++ ABI class. +CGCXXABI *CreateARMCXXABI(CodeGenModule &CGM); CGCXXABI *CreateItaniumCXXABI(CodeGenModule &CGM); CGCXXABI *CreateMicrosoftCXXABI(CodeGenModule &CGM); } diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index c0df55b808d6..2d9d57393ef7 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -91,11 +91,15 @@ void CodeGenModule::createObjCRuntime() { void CodeGenModule::createCXXABI() { switch (Context.Target.getCXXABI()) { - default: + case CXXABI_ARM: + ABI = CreateARMCXXABI(*this); + break; + case CXXABI_Itanium: ABI = CreateItaniumCXXABI(*this); break; case CXXABI_Microsoft: ABI = CreateMicrosoftCXXABI(*this); + break; } } diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index a6137692fbd7..bd396d29d7a5 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -12,6 +12,10 @@ // documented at: // http://www.codesourcery.com/public/cxx-abi/abi.html // http://www.codesourcery.com/public/cxx-abi/abi-eh.html +// +// It also supports the closely-related ARM ABI, documented at: +// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0041c/IHI0041C_cppabi.pdf +// //===----------------------------------------------------------------------===// #include "CGCXXABI.h" @@ -31,9 +35,18 @@ public: return MangleCtx; } }; + +class ARMCXXABI : public ItaniumCXXABI { +public: + ARMCXXABI(CodeGen::CodeGenModule &CGM) : ItaniumCXXABI(CGM) {} +}; } CodeGen::CGCXXABI *CodeGen::CreateItaniumCXXABI(CodeGenModule &CGM) { return new ItaniumCXXABI(CGM); } +CodeGen::CGCXXABI *CodeGen::CreateARMCXXABI(CodeGenModule &CGM) { + return new ARMCXXABI(CGM); +} +