From ad32fdb927a37dba26cb8b56f3a6b11667fe6584 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 25 Apr 2014 15:51:06 -0700 Subject: Introduce an Emscripten C++ ABI. Emscripten uses the Itanium C++ ABI for most things, except that it uses ARM C++ ABI pointers to member functions, to avoid the overhead of aligning functions. --- include/clang/Basic/TargetCXXABI.h | 8 ++++++++ lib/AST/ASTContext.cpp | 2 ++ lib/Basic/Targets.cpp | 5 +++++ lib/CodeGen/CodeGenModule.cpp | 1 + lib/CodeGen/ItaniumCXXABI.cpp | 17 +++++++++++------ 5 files changed, 27 insertions(+), 6 deletions(-) diff --git a/include/clang/Basic/TargetCXXABI.h b/include/clang/Basic/TargetCXXABI.h index c9d28f8774..29e4e47076 100644 --- a/include/clang/Basic/TargetCXXABI.h +++ b/include/clang/Basic/TargetCXXABI.h @@ -71,6 +71,10 @@ public: /// - guard variables are smaller. GenericAArch64, + /// Emscripten uses the Itanium C++, with the exception that it uses + /// ARM-style pointers to member functions. + Emscripten, + /// The Microsoft ABI is the ABI used by Microsoft Visual Studio (and /// compatible compilers). /// @@ -104,6 +108,7 @@ public: case GenericAArch64: case GenericItanium: case GenericARM: + case Emscripten: case iOS: return true; @@ -119,6 +124,7 @@ public: case GenericAArch64: case GenericItanium: case GenericARM: + case Emscripten: case iOS: return false; @@ -187,6 +193,7 @@ public: case GenericAArch64: case GenericItanium: + case Emscripten: case iOS: // old iOS compilers did not follow this rule case Microsoft: return true; @@ -233,6 +240,7 @@ public: case GenericItanium: case GenericAArch64: case GenericARM: + case Emscripten: case iOS: return UseTailPaddingUnlessPOD03; diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 176aec53a2..b77977f7fd 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -651,6 +651,7 @@ CXXABI *ASTContext::createCXXABI(const TargetInfo &T) { case TargetCXXABI::GenericARM: case TargetCXXABI::iOS: return CreateARMCXXABI(*this); + case TargetCXXABI::Emscripten: // Same as Itanium at this level case TargetCXXABI::GenericAArch64: // Same as Itanium at this level case TargetCXXABI::GenericItanium: return CreateItaniumCXXABI(*this); @@ -7940,6 +7941,7 @@ MangleContext *ASTContext::createMangleContext() { case TargetCXXABI::GenericAArch64: case TargetCXXABI::GenericItanium: case TargetCXXABI::GenericARM: + case TargetCXXABI::Emscripten: case TargetCXXABI::iOS: return createItaniumMangleContext(*this, getDiagnostics()); case TargetCXXABI::Microsoft: diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index b56b42c798..93da96f897 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -270,6 +270,11 @@ public: // beneficial. this->UserLabelPrefix = ""; this->MaxAtomicPromoteWidth = this->MaxAtomicInlineWidth = 32; + + // Emscripten uses the Itanium ABI mostly, but it uses ARM-style pointers + // to member functions so that it can avoid having to align function + // addresses. + this->TheCXXABI.set(TargetCXXABI::Emscripten); } }; diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 0b03a3c4b6..15e4a50eaa 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -57,6 +57,7 @@ static CGCXXABI &createCXXABI(CodeGenModule &CGM) { switch (CGM.getTarget().getCXXABI().getKind()) { case TargetCXXABI::GenericAArch64: case TargetCXXABI::GenericARM: + case TargetCXXABI::Emscripten: case TargetCXXABI::iOS: case TargetCXXABI::GenericItanium: return *CreateItaniumCXXABI(CGM); diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp index 3767e4f278..1568284a7d 100644 --- a/lib/CodeGen/ItaniumCXXABI.cpp +++ b/lib/CodeGen/ItaniumCXXABI.cpp @@ -231,18 +231,23 @@ CodeGen::CGCXXABI *CodeGen::CreateItaniumCXXABI(CodeGenModule &CGM) { return new ItaniumCXXABI(CGM, /* UseARMMethodPtrABI = */ true, /* UseARMGuardVarABI = */ true); + case TargetCXXABI::Emscripten: + // Use ARM-style method pointers so that generated code + // does not assume anything about the alignment of function + // pointers. + return new ItaniumCXXABI(CGM, /* UseARMMethodPtrABI = */ true, + /* UseARMGuardVarABI = */ false); + case TargetCXXABI::GenericItanium: - switch (CGM.getContext().getTargetInfo().getTriple().getArch()) { - case llvm::Triple::le32: - case llvm::Triple::asmjs: - // Use ARM-style method pointers so that generated code + if (CGM.getContext().getTargetInfo().getTriple().getArch() + == llvm::Triple::le32) { + // For PNaCl, use ARM-style method pointers so that PNaCl code // does not assume anything about the alignment of function // pointers. return new ItaniumCXXABI(CGM, /* UseARMMethodPtrABI = */ true, /* UseARMGuardVarABI = */ false); - default: - return new ItaniumCXXABI(CGM); } + return new ItaniumCXXABI(CGM); case TargetCXXABI::Microsoft: llvm_unreachable("Microsoft ABI is not Itanium-based"); -- cgit v1.2.3-18-g5258