/// 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
};
/// 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;
}
/// 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;
}
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,
};
/// Creates an instance of a C++ ABI class.
+CXXABI *CreateARMCXXABI(ASTContext &Ctx);
CXXABI *CreateItaniumCXXABI(ASTContext &Ctx);
CXXABI *CreateMicrosoftCXXABI(ASTContext &Ctx);
}
// 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"
namespace {
class ItaniumCXXABI : public CXXABI {
+protected:
ASTContext &Context;
public:
ItaniumCXXABI(ASTContext &Ctx) : Context(Ctx) { }
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);
+}
// Default to no types using fpret.
RealTypeUsesObjCFPRet = 0;
+
+ // Default to using the Itanium ABI.
+ CXXABI = CXXABI_Itanium;
}
// Out of line virtual dtor for TargetInfo.
"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) {
}
// 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;
}
};
/// Creates an instance of a C++ ABI class.
+CGCXXABI *CreateARMCXXABI(CodeGenModule &CGM);
CGCXXABI *CreateItaniumCXXABI(CodeGenModule &CGM);
CGCXXABI *CreateMicrosoftCXXABI(CodeGenModule &CGM);
}
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;
}
}
// 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"
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);
+}
+