diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td index 88e7dc19ae..4b0bf57bef 100644 --- a/include/clang/Basic/DiagnosticCommonKinds.td +++ b/include/clang/Basic/DiagnosticCommonKinds.td @@ -66,6 +66,7 @@ def err_target_unknown_triple : Error< "unknown target triple '%0', please use -triple or -arch">; def err_target_unknown_cpu : Error<"unknown target CPU '%0'">; def err_target_unknown_abi : Error<"unknown target ABI '%0'">; +def err_target_unknown_cxxabi : Error<"unknown C++ ABI '%0'">; def err_target_invalid_feature : Error<"invalid target feature '%0'">; // Source manager diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index 4c5019ca98..5763a12135 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -58,6 +58,7 @@ protected: const char *UserLabelPrefix; const llvm::fltSemantics *FloatFormat, *DoubleFormat, *LongDoubleFormat; unsigned char RegParmMax, SSERegParmMax; + std::string CXXABI; unsigned HasAlignMac68kSupport : 1; @@ -396,6 +397,11 @@ public: return ""; } + /// getCXXABI - Get the C++ ABI in use. + virtual llvm::StringRef getCXXABI() const { + return CXXABI; + } + /// setCPU - Target the specific CPU. /// /// \return - False on error (invalid CPU name). @@ -412,6 +418,16 @@ public: return false; } + /// setCXXABI - Use this specific C++ ABI. + /// + /// \return - False on error (invalid ABI name). + virtual bool setCXXABI(const std::string &Name) { + if (Name != "itanium" && Name != "microsoft") + return false; + CXXABI = Name; + return true; + } + /// setFeatureEnabled - Enable or disable a specific target feature, /// the feature name must be valid. /// diff --git a/include/clang/Basic/TargetOptions.h b/include/clang/Basic/TargetOptions.h index eeaab1558f..cec8f53158 100644 --- a/include/clang/Basic/TargetOptions.h +++ b/include/clang/Basic/TargetOptions.h @@ -29,6 +29,10 @@ public: /// If given, the name of the target ABI to use. std::string ABI; + /// If given, the name of the target C++ ABI to use. If not given, defaults + /// to "itanium". + std::string CXXABI; + /// The list of target specific features to enable or disable -- this should /// be a list of strings starting with by '+' or '-'. std::vector Features; diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index fd8322b843..59c49301b3 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -18,6 +18,8 @@ include "OptParser.td" // Target Options //===----------------------------------------------------------------------===// +def cxx_abi : Separate<"-cxx-abi">, + HelpText<"Target a particular C++ ABI type">; def target_abi : Separate<"-target-abi">, HelpText<"Target a particular ABI type">; def target_cpu : Separate<"-target-cpu">, diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index fb58739896..3717b12b15 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -2475,6 +2475,12 @@ TargetInfo *TargetInfo::CreateTargetInfo(Diagnostic &Diags, return 0; } + // Set the target C++ ABI. + if (!Target->setCXXABI(Opts.CXXABI)) { + Diags.Report(diag::err_target_unknown_cxxabi) << Opts.CXXABI; + return 0; + } + // Compute the default target features, we need the target to handle this // because features may have dependencies on one another. llvm::StringMap Features; diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 90abd439b1..880d5372bf 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -86,8 +86,10 @@ void CodeGenModule::createObjCRuntime() { } void CodeGenModule::createCXXABI() { - // For now, just create an Itanium ABI. - ABI = CreateItaniumCXXABI(*this); + if (Context.Target.getCXXABI() == "microsoft") + ABI = CreateMicrosoftCXXABI(*this); + else + ABI = CreateItaniumCXXABI(*this); } void CodeGenModule::Release() { diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp index cf809991de..d391651fac 100644 --- a/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/lib/CodeGen/MicrosoftCXXABI.cpp @@ -124,7 +124,7 @@ void MicrosoftMangleContext::mangleCXXDtor(const CXXDestructorDecl *D, assert(false && "Can't yet mangle destructors!"); } -CXXABI *CreateMicrosoftCXXABI(CodeGenModule &CGM) { +CXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) { return new MicrosoftCXXABI(CGM); } diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index 68e7ac17ea..314e253f12 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -219,6 +219,7 @@ ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename, // FIXME: This is broken, we should store the TargetOptions in the PCH. TargetOptions TargetOpts; TargetOpts.ABI = ""; + TargetOpts.CXXABI = "itanium"; TargetOpts.CPU = ""; TargetOpts.Features.clear(); TargetOpts.Triple = TargetTriple; diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 4d7f839bdc..9bc8b76de8 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -680,6 +680,8 @@ static void TargetOptsToArgs(const TargetOptions &Opts, Res.push_back("-target-abi"); Res.push_back(Opts.ABI); } + Res.push_back("-cxx-abi"); + Res.push_back(Opts.CXXABI); for (unsigned i = 0, e = Opts.Features.size(); i != e; ++i) { Res.push_back("-target-feature"); Res.push_back(Opts.Features[i]); @@ -1367,6 +1369,7 @@ static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts, static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args) { using namespace cc1options; Opts.ABI = Args.getLastArgValue(OPT_target_abi); + Opts.CXXABI = Args.getLastArgValue(OPT_cxx_abi); Opts.CPU = Args.getLastArgValue(OPT_target_cpu); Opts.Triple = Args.getLastArgValue(OPT_triple); Opts.Features = Args.getAllArgValues(OPT_target_feature); @@ -1374,6 +1377,10 @@ static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args) { // Use the host triple if unspecified. if (Opts.Triple.empty()) Opts.Triple = llvm::sys::getHostTriple(); + + // Use the Itanium C++ ABI if unspecified. + if (Opts.CXXABI.empty()) + Opts.CXXABI = "itanium"; } //