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
This commit is contained in:
John McCall 2010-08-21 22:46:04 +00:00
parent b186bc3c4b
commit 86353416a7
10 changed files with 70 additions and 14 deletions

View File

@ -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<TargetCXXABI>(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(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;
}

View File

@ -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;

View File

@ -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,

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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.

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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);
}