r222733 - MS ABI: Add CodeGen support for rethrowing MS C++ exceptions
David Majnemer
david.majnemer at gmail.com
Mon Nov 24 23:20:21 PST 2014
Author: majnemer
Date: Tue Nov 25 01:20:20 2014
New Revision: 222733
URL: http://llvm.org/viewvc/llvm-project?rev=222733&view=rev
Log:
MS ABI: Add CodeGen support for rethrowing MS C++ exceptions
Rethrowing exceptions in the MS model is very simple: just call
_CxxThrowException with nullptr for both arguments.
N.B. They chose stdcall as the calling convention for x86 but cdecl for
all other platforms.
Modified:
cfe/trunk/docs/MSVCCompatibility.rst
cfe/trunk/lib/CodeGen/CGCXXABI.h
cfe/trunk/lib/CodeGen/CGException.cpp
cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
Modified: cfe/trunk/docs/MSVCCompatibility.rst
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/MSVCCompatibility.rst?rev=222733&r1=222732&r2=222733&view=diff
==============================================================================
--- cfe/trunk/docs/MSVCCompatibility.rst (original)
+++ cfe/trunk/docs/MSVCCompatibility.rst Tue Nov 25 01:20:20 2014
@@ -84,8 +84,9 @@ The status of major ABI-impacting C++ fe
* RTTI: :good:`Complete`. Generation of RTTI data structures has been
finished, along with support for the ``/GR`` flag.
-* Exceptions and SEH: :none:`Unstarted`. Clang can parse both constructs, but
- does not know how to emit compatible handlers.
+* Exceptions and SEH: :partial:`Minimal`. Clang can parse both constructs, but
+ does not know how to emit compatible handlers. Clang cannot throw exceptions
+ but it can rethrow them.
* Thread-safe initialization of local statics: :none:`Unstarted`. We are ABI
compatible with MSVC 2013, which does not support thread-safe local statics.
Modified: cfe/trunk/lib/CodeGen/CGCXXABI.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXABI.h?rev=222733&r1=222732&r2=222733&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXABI.h (original)
+++ cfe/trunk/lib/CodeGen/CGCXXABI.h Tue Nov 25 01:20:20 2014
@@ -213,6 +213,7 @@ public:
const CXXDeleteExpr *DE,
llvm::Value *Ptr, QualType ElementType,
const CXXDestructorDecl *Dtor) = 0;
+ virtual void emitRethrow(CodeGenFunction &CGF, bool isNoReturn) = 0;
virtual llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) = 0;
Modified: cfe/trunk/lib/CodeGen/CGException.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGException.cpp?rev=222733&r1=222732&r2=222733&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGException.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGException.cpp Tue Nov 25 01:20:20 2014
@@ -13,6 +13,7 @@
#include "CodeGenFunction.h"
#include "CGCleanup.h"
+#include "CGCXXABI.h"
#include "CGObjCRuntime.h"
#include "TargetInfo.h"
#include "clang/AST/StmtCXX.h"
@@ -52,15 +53,6 @@ static llvm::Constant *getThrowFn(CodeGe
return CGM.CreateRuntimeFunction(FTy, "__cxa_throw");
}
-static llvm::Constant *getReThrowFn(CodeGenModule &CGM) {
- // void __cxa_rethrow();
-
- llvm::FunctionType *FTy =
- llvm::FunctionType::get(CGM.VoidTy, /*IsVarArgs=*/false);
-
- return CGM.CreateRuntimeFunction(FTy, "__cxa_rethrow");
-}
-
static llvm::Constant *getGetExceptionPtrFn(CodeGenModule &CGM) {
// void *__cxa_get_exception_ptr(void*);
@@ -425,13 +417,8 @@ llvm::Value *CodeGenFunction::getSelecto
void CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E,
bool KeepInsertionPoint) {
- if (CGM.getTarget().getTriple().isKnownWindowsMSVCEnvironment()) {
- ErrorUnsupported(E, "throw expression");
- return;
- }
-
if (!E->getSubExpr()) {
- EmitNoreturnRuntimeCallOrInvoke(getReThrowFn(CGM), None);
+ CGM.getCXXABI().emitRethrow(*this, /*isNoReturn*/true);
// throw is an expression, and the expression emitters expect us
// to leave ourselves at a valid insertion point.
@@ -441,6 +428,11 @@ void CodeGenFunction::EmitCXXThrowExpr(c
return;
}
+ if (CGM.getTarget().getTriple().isKnownWindowsMSVCEnvironment()) {
+ ErrorUnsupported(E, "throw expression");
+ return;
+ }
+
QualType ThrowType = E->getSubExpr()->getType();
if (ThrowType->isObjCObjectPointerType()) {
@@ -1281,7 +1273,7 @@ void CodeGenFunction::ExitCXXTryStmt(con
// constructor function-try-block's catch handler (p14), so this
// really only applies to destructors.
if (doImplicitRethrow && HaveInsertPoint()) {
- EmitRuntimeCallOrInvoke(getReThrowFn(CGM));
+ CGM.getCXXABI().emitRethrow(*this, /*isNoReturn*/false);
Builder.CreateUnreachable();
Builder.ClearInsertionPoint();
}
Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=222733&r1=222732&r2=222733&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Tue Nov 25 01:20:20 2014
@@ -110,6 +110,8 @@ public:
llvm::Value *Ptr, QualType ElementType,
const CXXDestructorDecl *Dtor) override;
+ void emitRethrow(CodeGenFunction &CGF, bool isNoReturn) override;
+
void EmitFundamentalRTTIDescriptor(QualType Type);
void EmitFundamentalRTTIDescriptors();
llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) override;
@@ -887,6 +889,20 @@ void ItaniumCXXABI::emitVirtualObjectDel
CGF.PopCleanupBlock();
}
+void ItaniumCXXABI::emitRethrow(CodeGenFunction &CGF, bool isNoReturn) {
+ // void __cxa_rethrow();
+
+ llvm::FunctionType *FTy =
+ llvm::FunctionType::get(CGM.VoidTy, /*IsVarArgs=*/false);
+
+ llvm::Constant *Fn = CGM.CreateRuntimeFunction(FTy, "__cxa_rethrow");
+
+ if (isNoReturn)
+ CGF.EmitNoreturnRuntimeCallOrInvoke(Fn, None);
+ else
+ CGF.EmitRuntimeCallOrInvoke(Fn);
+}
+
static llvm::Constant *getItaniumDynamicCastFn(CodeGenFunction &CGF) {
// void *__dynamic_cast(const void *sub,
// const abi::__class_type_info *src,
Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=222733&r1=222732&r2=222733&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Tue Nov 25 01:20:20 2014
@@ -70,6 +70,8 @@ public:
llvm::Value *Ptr, QualType ElementType,
const CXXDestructorDecl *Dtor) override;
+ void emitRethrow(CodeGenFunction &CGF, bool isNoReturn);
+
llvm::GlobalVariable *getMSCompleteObjectLocator(const CXXRecordDecl *RD,
const VPtrInfo *Info);
@@ -665,6 +667,30 @@ void MicrosoftCXXABI::emitVirtualObjectD
CGF.EmitDeleteCall(DE->getOperatorDelete(), MDThis, ElementType);
}
+static llvm::Function *getRethrowFn(CodeGenModule &CGM) {
+ // _CxxThrowException takes two pointer width arguments: a value and a context
+ // object which points to a TypeInfo object.
+ llvm::Type *ArgTypes[] = {CGM.Int8PtrTy, CGM.Int8PtrTy};
+ llvm::FunctionType *FTy =
+ llvm::FunctionType::get(CGM.VoidTy, ArgTypes, false);
+ auto *Fn = cast<llvm::Function>(
+ CGM.CreateRuntimeFunction(FTy, "_CxxThrowException"));
+ // _CxxThrowException is stdcall on 32-bit x86 platforms.
+ if (CGM.getTarget().getTriple().getArch() == llvm::Triple::x86)
+ Fn->setCallingConv(llvm::CallingConv::X86_StdCall);
+ return Fn;
+}
+
+void MicrosoftCXXABI::emitRethrow(CodeGenFunction &CGF, bool isNoReturn) {
+ llvm::Value *Args[] = {llvm::ConstantPointerNull::get(CGM.Int8PtrTy),
+ llvm::ConstantPointerNull::get(CGM.Int8PtrTy)};
+ auto *Fn = getRethrowFn(CGM);
+ if (isNoReturn)
+ CGF.EmitNoreturnRuntimeCallOrInvoke(Fn, Args);
+ else
+ CGF.EmitRuntimeCallOrInvoke(Fn, Args);
+}
+
/// \brief Gets the offset to the virtual base that contains the vfptr for
/// MS-ABI polymorphic types.
static llvm::Value *getPolymorphicOffset(CodeGenFunction &CGF,
More information about the cfe-commits
mailing list