diff options
author | Reid Kleckner <rnk@google.com> | 2015-09-16 20:15:55 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2015-09-16 20:15:55 +0000 |
commit | 10aa77032de43681231e81ee3f2e7d232b16dc9c (patch) | |
tree | 1a1bcae8633d6ba6a4753bbc7573c515ece19467 /clang/lib/CodeGen | |
parent | 7d7ca2f2ba68340be3d5927f7e8c68d984638053 (diff) | |
download | bcm5719-llvm-10aa77032de43681231e81ee3f2e7d232b16dc9c.tar.gz bcm5719-llvm-10aa77032de43681231e81ee3f2e7d232b16dc9c.zip |
[WinEH] Pass the catch adjectives to catchpad directly
This avoids building a fake LLVM IR global variable just to ferry an i32
down into LLVM codegen. It also puts a nail in the coffin of using MS
ABI C++ EH with landingpads, since now we'll assert in the lpad code
when flags are present.
llvm-svn: 247843
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGCXXABI.cpp | 5 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGCXXABI.h | 4 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGCleanup.h | 19 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGException.cpp | 41 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 6 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/ItaniumCXXABI.cpp | 4 | ||||
-rw-r--r-- | clang/lib/CodeGen/MicrosoftCXXABI.cpp | 36 |
8 files changed, 60 insertions, 58 deletions
diff --git a/clang/lib/CodeGen/CGCXXABI.cpp b/clang/lib/CodeGen/CGCXXABI.cpp index 1f0c3c0e1b4..51f1b0730b3 100644 --- a/clang/lib/CodeGen/CGCXXABI.cpp +++ b/clang/lib/CodeGen/CGCXXABI.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "CGCXXABI.h" +#include "CGCleanup.h" using namespace clang; using namespace CodeGen; @@ -321,3 +322,7 @@ CGCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF, // Just call std::terminate and ignore the violating exception. return CGF.EmitNounwindRuntimeCall(CGF.CGM.getTerminateFn()); } + +CatchTypeInfo CGCXXABI::getCatchAllTypeInfo() { + return CatchTypeInfo{nullptr, 0}; +} diff --git a/clang/lib/CodeGen/CGCXXABI.h b/clang/lib/CodeGen/CGCXXABI.h index 6461a478b16..dc4d6d38275 100644 --- a/clang/lib/CodeGen/CGCXXABI.h +++ b/clang/lib/CodeGen/CGCXXABI.h @@ -37,6 +37,7 @@ class MangleContext; namespace CodeGen { class CodeGenFunction; class CodeGenModule; +struct CatchTypeInfo; /// \brief Implements C++ ABI-specific code generation functions. class CGCXXABI { @@ -236,8 +237,9 @@ public: llvm::Value *Exn); virtual llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) = 0; - virtual llvm::Constant * + virtual CatchTypeInfo getAddrOfCXXCatchHandlerType(QualType Ty, QualType CatchHandlerType) = 0; + virtual CatchTypeInfo getCatchAllTypeInfo(); virtual bool shouldTypeidBeNullChecked(bool IsDeref, QualType SrcRecordTy) = 0; diff --git a/clang/lib/CodeGen/CGCleanup.h b/clang/lib/CodeGen/CGCleanup.h index 5782343013c..51b33f43e90 100644 --- a/clang/lib/CodeGen/CGCleanup.h +++ b/clang/lib/CodeGen/CGCleanup.h @@ -33,6 +33,13 @@ namespace CodeGen { class CodeGenModule; class CodeGenFunction; +/// The MS C++ ABI needs a pointer to RTTI data plus some flags to describe the +/// type of a catch handler, so we use this wrapper. +struct CatchTypeInfo { + llvm::Constant *RTTI; + unsigned Flags; +}; + /// A protected scope for zero-cost EH handling. class EHScope { llvm::BasicBlock *CachedLandingPad; @@ -153,12 +160,12 @@ public: struct Handler { /// A type info value, or null (C++ null, not an LLVM null pointer) /// for a catch-all. - llvm::Constant *Type; + CatchTypeInfo Type; /// The catch handler for this type. llvm::BasicBlock *Block; - bool isCatchAll() const { return Type == nullptr; } + bool isCatchAll() const { return Type.RTTI == nullptr; } }; private: @@ -188,11 +195,17 @@ public: } void setCatchAllHandler(unsigned I, llvm::BasicBlock *Block) { - setHandler(I, /*catchall*/ nullptr, Block); + setHandler(I, CatchTypeInfo{nullptr, 0}, Block); } void setHandler(unsigned I, llvm::Constant *Type, llvm::BasicBlock *Block) { assert(I < getNumHandlers()); + getHandlers()[I].Type = CatchTypeInfo{Type, 0}; + getHandlers()[I].Block = Block; + } + + void setHandler(unsigned I, CatchTypeInfo Type, llvm::BasicBlock *Block) { + assert(I < getNumHandlers()); getHandlers()[I].Type = Type; getHandlers()[I].Block = Block; } diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp index 858b83da36e..6c4a3670e5f 100644 --- a/clang/lib/CodeGen/CGException.cpp +++ b/clang/lib/CodeGen/CGException.cpp @@ -554,16 +554,16 @@ void CodeGenFunction::EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) { QualType CaughtType = CGM.getContext().getUnqualifiedArrayType( C->getCaughtType().getNonReferenceType(), CaughtTypeQuals); - llvm::Constant *TypeInfo = nullptr; + CatchTypeInfo TypeInfo{nullptr, 0}; if (CaughtType->isObjCObjectPointerType()) - TypeInfo = CGM.getObjCRuntime().GetEHType(CaughtType); + TypeInfo.RTTI = CGM.getObjCRuntime().GetEHType(CaughtType); else - TypeInfo = - CGM.getAddrOfCXXCatchHandlerType(CaughtType, C->getCaughtType()); + TypeInfo = CGM.getCXXABI().getAddrOfCXXCatchHandlerType( + CaughtType, C->getCaughtType()); CatchScope->setHandler(I, TypeInfo, Handler); } else { // No exception decl indicates '...', a catch-all. - CatchScope->setCatchAllHandler(I, Handler); + CatchScope->setHandler(I, CGM.getCXXABI().getCatchAllTypeInfo(), Handler); } } } @@ -807,18 +807,20 @@ llvm::BasicBlock *CodeGenFunction::EmitLandingPad() { EHCatchScope &catchScope = cast<EHCatchScope>(*I); for (unsigned hi = 0, he = catchScope.getNumHandlers(); hi != he; ++hi) { EHCatchScope::Handler handler = catchScope.getHandler(hi); + assert(handler.Type.Flags == 0 && + "landingpads do not support catch handler flags"); // If this is a catch-all, register that and abort. - if (!handler.Type) { + if (!handler.Type.RTTI) { assert(!hasCatchAll); hasCatchAll = true; goto done; } // Check whether we already have a handler for this type. - if (catchTypes.insert(handler.Type).second) + if (catchTypes.insert(handler.Type.RTTI).second) // If not, add it directly to the landingpad. - LPadInst->addClause(handler.Type); + LPadInst->addClause(handler.Type.RTTI); } } @@ -881,10 +883,9 @@ static llvm::BasicBlock *emitMSVCCatchDispatchBlock(CodeGenFunction &CGF, for (unsigned I = 0, E = CatchScope.getNumHandlers(); I < E; ++I) { const EHCatchScope::Handler &Handler = CatchScope.getHandler(I); - llvm::Value *TypeValue = Handler.Type; - assert(TypeValue != nullptr || Handler.isCatchAll()); - if (!TypeValue) - TypeValue = llvm::Constant::getNullValue(CGF.VoidPtrTy); + CatchTypeInfo TypeInfo = Handler.Type; + if (!TypeInfo.RTTI) + TypeInfo.RTTI = llvm::Constant::getNullValue(CGF.VoidPtrTy); // If this is the last handler, we're at the end, and the next // block is the block for the enclosing EH scope. @@ -897,11 +898,12 @@ static llvm::BasicBlock *emitMSVCCatchDispatchBlock(CodeGenFunction &CGF, } if (EHPersonality::get(CGF).isMSVCXXPersonality()) { - CGF.Builder.CreateCatchPad( - Handler.Block, NextBlock, - {TypeValue, llvm::Constant::getNullValue(CGF.VoidPtrTy)}); + CGF.Builder.CreateCatchPad(Handler.Block, NextBlock, + {TypeInfo.RTTI, + CGF.Builder.getInt32(TypeInfo.Flags), + llvm::Constant::getNullValue(CGF.VoidPtrTy)}); } else { - CGF.Builder.CreateCatchPad(Handler.Block, NextBlock, {TypeValue}); + CGF.Builder.CreateCatchPad(Handler.Block, NextBlock, {TypeInfo.RTTI}); } // Otherwise we need to emit and continue at that block. @@ -948,7 +950,9 @@ static llvm::BasicBlock *emitCatchDispatchBlock(CodeGenFunction &CGF, assert(i < e && "ran off end of handlers!"); const EHCatchScope::Handler &handler = catchScope.getHandler(i); - llvm::Value *typeValue = handler.Type; + llvm::Value *typeValue = handler.Type.RTTI; + assert(handler.Type.Flags == 0 && + "landingpads do not support catch handler flags"); assert(typeValue && "fell into catch-all case!"); typeValue = CGF.Builder.CreateBitCast(typeValue, CGF.Int8PtrTy); @@ -1841,7 +1845,8 @@ void CodeGenFunction::EnterSEHTryStmt(const SEHTryStmt &S) { HelperCGF.GenerateSEHFilterFunction(*this, *Except); llvm::Constant *OpaqueFunc = llvm::ConstantExpr::getBitCast(FilterFunc, Int8PtrTy); - CatchScope->setHandler(0, OpaqueFunc, createBasicBlock("__except.ret")); + CatchScope->setHandler(0, CatchTypeInfo{OpaqueFunc}, + createBasicBlock("__except.ret")); } void CodeGenFunction::ExitSEHTryStmt(const SEHTryStmt &S) { diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index bb3bbf28183..34eb06d7207 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -3808,12 +3808,6 @@ llvm::Constant *CodeGenModule::EmitUuidofInitializer(StringRef Uuid) { return llvm::ConstantStruct::getAnon(Fields); } -llvm::Constant * -CodeGenModule::getAddrOfCXXCatchHandlerType(QualType Ty, - QualType CatchHandlerType) { - return getCXXABI().getAddrOfCXXCatchHandlerType(Ty, CatchHandlerType); -} - llvm::Constant *CodeGenModule::GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH) { // Return a bogus pointer if RTTI is disabled, unless it's for EH. diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index e7ae20fce03..5f40d41261c 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -723,9 +723,6 @@ public: /// Get the address of the RTTI descriptor for the given type. llvm::Constant *GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH = false); - llvm::Constant *getAddrOfCXXCatchHandlerType(QualType Ty, - QualType CatchHandlerType); - /// Get the address of a uuid descriptor . ConstantAddress GetAddrOfUuidDescriptor(const CXXUuidofExpr* E); diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index da67b16c24d..8392f6a7ba2 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -179,10 +179,10 @@ public: void EmitFundamentalRTTIDescriptor(QualType Type); void EmitFundamentalRTTIDescriptors(); llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) override; - llvm::Constant * + CatchTypeInfo getAddrOfCXXCatchHandlerType(QualType Ty, QualType CatchHandlerType) override { - return getAddrOfRTTIDescriptor(Ty); + return CatchTypeInfo{getAddrOfRTTIDescriptor(Ty), 0}; } bool shouldTypeidBeNullChecked(bool IsDeref, QualType SrcRecordTy) override; diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index a2f7165a380..504dc3fa09b 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -15,6 +15,7 @@ //===----------------------------------------------------------------------===// #include "CGCXXABI.h" +#include "CGCleanup.h" #include "CGVTables.h" #include "CodeGenModule.h" #include "CodeGenTypes.h" @@ -105,9 +106,14 @@ public: const VPtrInfo *Info); llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) override; - llvm::Constant * + CatchTypeInfo getAddrOfCXXCatchHandlerType(QualType Ty, QualType CatchHandlerType) override; + /// MSVC needs an extra flag to indicate a catchall. + CatchTypeInfo getCatchAllTypeInfo() override { + return CatchTypeInfo{nullptr, 0x40}; + } + bool shouldTypeidBeNullChecked(bool IsDeref, QualType SrcRecordTy) override; void EmitBadTypeidCall(CodeGenFunction &CGF) override; llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy, @@ -926,7 +932,7 @@ void MicrosoftCXXABI::emitBeginCatch(CodeGenFunction &CGF, llvm::Value *Args[2] = {Exn, ParamAddr.getPointer()}; CGF.EmitNounwindRuntimeCall(BeginCatch, Args); } else { - CPI->setArgOperand(1, var.getObjectAddress(CGF).getPointer()); + CPI->setArgOperand(2, var.getObjectAddress(CGF).getPointer()); } CGF.EHStack.pushCleanup<CallEndCatchMSVC>(NormalCleanup, CPI); CGF.EmitAutoVarCleanups(var); @@ -3687,7 +3693,7 @@ static QualType decomposeTypeForEH(ASTContext &Context, QualType T, return T; } -llvm::Constant * +CatchTypeInfo MicrosoftCXXABI::getAddrOfCXXCatchHandlerType(QualType Type, QualType CatchHandlerType) { // TypeDescriptors for exceptions never have qualified pointer types, @@ -3706,28 +3712,8 @@ MicrosoftCXXABI::getAddrOfCXXCatchHandlerType(QualType Type, if (IsReference) Flags |= 8; - SmallString<256> MangledName; - { - llvm::raw_svector_ostream Out(MangledName); - getMangleContext().mangleCXXCatchHandlerType(Type, Flags, Out); - } - - if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(MangledName)) - return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy); - - llvm::Constant *Fields[] = { - llvm::ConstantInt::get(CGM.IntTy, Flags), // Flags - getAddrOfRTTIDescriptor(Type), // TypeDescriptor - }; - llvm::StructType *CatchHandlerTypeType = getCatchHandlerTypeType(); - auto *Var = new llvm::GlobalVariable( - CGM.getModule(), CatchHandlerTypeType, /*Constant=*/true, - llvm::GlobalValue::PrivateLinkage, - llvm::ConstantStruct::get(CatchHandlerTypeType, Fields), - StringRef(MangledName)); - Var->setUnnamedAddr(true); - Var->setSection("llvm.metadata"); - return Var; + return CatchTypeInfo{getAddrOfRTTIDescriptor(Type)->stripPointerCasts(), + Flags}; } /// \brief Gets a TypeDescriptor. Returns a llvm::Constant * rather than a |