diff options
-rw-r--r-- | clang/include/clang/AST/Mangle.h | 4 | ||||
-rw-r--r-- | clang/lib/AST/MicrosoftMangle.cpp | 18 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGCXXABI.h | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGException.cpp | 3 | ||||
-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 | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/MicrosoftCXXABI.cpp | 61 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/microsoft-abi-try-throw.cpp | 6 |
9 files changed, 93 insertions, 14 deletions
diff --git a/clang/include/clang/AST/Mangle.h b/clang/include/clang/AST/Mangle.h index aa644b2f001..23dde6b3f92 100644 --- a/clang/include/clang/AST/Mangle.h +++ b/clang/include/clang/AST/Mangle.h @@ -208,6 +208,10 @@ public: uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBIndex, raw_ostream &Out) = 0; + virtual void mangleCXXHandlerMapEntry(QualType T, bool IsConst, + bool IsVolatile, bool IsReference, + raw_ostream &Out) = 0; + virtual void mangleCXXRTTIBaseClassDescriptor( const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) = 0; diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 1b10fe3c2eb..c402f4abb0d 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -122,6 +122,8 @@ public: CXXCtorType CT, uint32_t Size, uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBIndex, raw_ostream &Out) override; + void mangleCXXHandlerMapEntry(QualType T, bool IsConst, bool IsVolatile, + bool IsReference, raw_ostream &Out); void mangleCXXRTTI(QualType T, raw_ostream &Out) override; void mangleCXXRTTIName(QualType T, raw_ostream &Out) override; void mangleCXXRTTIBaseClassDescriptor(const CXXRecordDecl *Derived, @@ -2339,6 +2341,22 @@ void MicrosoftMangleContextImpl::mangleCXXRTTIName(QualType T, Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result); } +void MicrosoftMangleContextImpl::mangleCXXHandlerMapEntry(QualType T, + bool IsConst, + bool IsVolatile, + bool IsReference, + raw_ostream &Out) { + MicrosoftCXXNameMangler Mangler(*this, Out); + Mangler.getStream() << "llvm.eh.handlermapentry."; + if (IsConst) + Mangler.getStream() << "const."; + if (IsVolatile) + Mangler.getStream() << "volatile."; + if (IsReference) + Mangler.getStream() << "reference."; + Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result); +} + void MicrosoftMangleContextImpl::mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile, diff --git a/clang/lib/CodeGen/CGCXXABI.h b/clang/lib/CodeGen/CGCXXABI.h index 3a92d05e7e3..b6a94f9082d 100644 --- a/clang/lib/CodeGen/CGCXXABI.h +++ b/clang/lib/CodeGen/CGCXXABI.h @@ -225,7 +225,8 @@ public: llvm::Value *Exn); virtual llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) = 0; - virtual llvm::Constant *getAddrOfCXXCatchDescriptor(QualType Ty) = 0; + virtual llvm::Constant * + getAddrOfCXXHandlerMapEntry(QualType Ty, QualType CatchHandlerType) = 0; virtual bool shouldTypeidBeNullChecked(bool IsDeref, QualType SrcRecordTy) = 0; diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp index 1a9ebb395fc..223b8f76d0d 100644 --- a/clang/lib/CodeGen/CGException.cpp +++ b/clang/lib/CodeGen/CGException.cpp @@ -567,7 +567,8 @@ void CodeGenFunction::EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) { if (CaughtType->isObjCObjectPointerType()) TypeInfo = CGM.getObjCRuntime().GetEHType(CaughtType); else - TypeInfo = CGM.getAddrOfCXXCatchDescriptor(CaughtType); + TypeInfo = + CGM.getAddrOfCXXHandlerMapEntry(CaughtType, C->getCaughtType()); CatchScope->setHandler(I, TypeInfo, Handler); } else { // No exception decl indicates '...', a catch-all. diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 03948d68cdc..c91de6df9e9 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -3644,8 +3644,10 @@ llvm::Constant *CodeGenModule::EmitUuidofInitializer(StringRef Uuid) { return llvm::ConstantStruct::getAnon(Fields); } -llvm::Constant *CodeGenModule::getAddrOfCXXCatchDescriptor(QualType Ty) { - return getCXXABI().getAddrOfCXXCatchDescriptor(Ty); +llvm::Constant * +CodeGenModule::getAddrOfCXXHandlerMapEntry(QualType Ty, + QualType CatchHandlerType) { + return getCXXABI().getAddrOfCXXHandlerMapEntry(Ty, CatchHandlerType); } llvm::Constant *CodeGenModule::GetAddrOfRTTIDescriptor(QualType Ty, diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 7e5bd7caa5c..ce540e91dcb 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -719,7 +719,8 @@ public: /// Get the address of the RTTI descriptor for the given type. llvm::Constant *GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH = false); - llvm::Constant *getAddrOfCXXCatchDescriptor(QualType Ty); + llvm::Constant *getAddrOfCXXHandlerMapEntry(QualType Ty, + QualType CatchHandlerType); /// Get the address of a uuid descriptor . llvm::Constant *GetAddrOfUuidDescriptor(const CXXUuidofExpr* E); diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index ca9322840eb..73bbfe071dd 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -126,7 +126,8 @@ public: void EmitFundamentalRTTIDescriptor(QualType Type); void EmitFundamentalRTTIDescriptors(); llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) override; - llvm::Constant *getAddrOfCXXCatchDescriptor(QualType Ty) { + llvm::Constant *getAddrOfCXXHandlerMapEntry(QualType Ty, + QualType CatchHandlerType) { return getAddrOfRTTIDescriptor(Ty); } diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index 7539ad8bdfa..6417b87444d 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -45,7 +45,7 @@ public: : CGCXXABI(CGM), BaseClassDescriptorType(nullptr), ClassHierarchyDescriptorType(nullptr), CompleteObjectLocatorType(nullptr), CatchableTypeType(nullptr), - ThrowInfoType(nullptr) {} + ThrowInfoType(nullptr), HandlerMapEntryType(nullptr) {} bool HasThisReturn(GlobalDecl GD) const override; bool hasMostDerivedReturn(GlobalDecl GD) const override; @@ -84,7 +84,8 @@ public: const VPtrInfo *Info); llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) override; - llvm::Constant *getAddrOfCXXCatchDescriptor(QualType Ty) override; + llvm::Constant * + getAddrOfCXXHandlerMapEntry(QualType Ty, QualType CatchHandlerType) override; bool shouldTypeidBeNullChecked(bool IsDeref, QualType SrcRecordTy) override; void EmitBadTypeidCall(CodeGenFunction &CGF) override; @@ -572,6 +573,18 @@ public: void emitCXXStructor(const CXXMethodDecl *MD, StructorType Type) override; + llvm::StructType *getHandlerMapEntryType() { + if (!HandlerMapEntryType) { + llvm::Type *FieldTypes[] = { + CGM.IntTy, // Flags + getImageRelativeType(CGM.Int8PtrTy), // TypeDescriptor + }; + HandlerMapEntryType = llvm::StructType::create( + CGM.getLLVMContext(), FieldTypes, "eh.HandlerMapEntry"); + } + return HandlerMapEntryType; + } + llvm::StructType *getCatchableTypeType() { if (CatchableTypeType) return CatchableTypeType; @@ -685,6 +698,7 @@ private: llvm::StructType *CatchableTypeType; llvm::DenseMap<uint32_t, llvm::StructType *> CatchableTypeArrayTypeMap; llvm::StructType *ThrowInfoType; + llvm::StructType *HandlerMapEntryType; }; } @@ -3186,14 +3200,48 @@ static QualType decomposeTypeForEH(ASTContext &Context, QualType T, return T; } -llvm::Constant *MicrosoftCXXABI::getAddrOfCXXCatchDescriptor(QualType Type) { - // TypeDescriptors for exceptions never has qualified pointer types, +llvm::Constant * +MicrosoftCXXABI::getAddrOfCXXHandlerMapEntry(QualType Type, + QualType CatchHandlerType) { + // TypeDescriptors for exceptions never have qualified pointer types, // qualifiers are stored seperately in order to support qualification // conversions. bool IsConst, IsVolatile; Type = decomposeTypeForEH(getContext(), Type, IsConst, IsVolatile); - return getAddrOfRTTIDescriptor(Type); + bool IsReference = CatchHandlerType->isReferenceType(); + + SmallString<256> MangledName; + { + llvm::raw_svector_ostream Out(MangledName); + getMangleContext().mangleCXXHandlerMapEntry(Type, IsConst, IsVolatile, + IsReference, Out); + } + + if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(MangledName)) + return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy); + + uint32_t Flags = 0; + if (IsConst) + Flags |= 1; + if (IsVolatile) + Flags |= 2; + if (IsReference) + Flags |= 8; + + llvm::Constant *Fields[] = { + llvm::ConstantInt::get(CGM.IntTy, Flags), // Flags + getImageRelativeConstant(getAddrOfRTTIDescriptor(Type)), // TypeDescriptor + }; + llvm::StructType *HandlerMapEntryType = getHandlerMapEntryType(); + auto *Var = new llvm::GlobalVariable( + CGM.getModule(), HandlerMapEntryType, /*Constant=*/true, + llvm::GlobalValue::PrivateLinkage, + llvm::ConstantStruct::get(HandlerMapEntryType, Fields), + StringRef(MangledName)); + Var->setUnnamedAddr(true); + Var->setSection("llvm.metadata"); + return Var; } /// \brief Gets a TypeDescriptor. Returns a llvm::Constant * rather than a @@ -3201,7 +3249,7 @@ llvm::Constant *MicrosoftCXXABI::getAddrOfCXXCatchDescriptor(QualType Type) { /// types, and need to be abstracted. They are abstracting by casting the /// address to an Int8PtrTy. llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(QualType Type) { - SmallString<256> MangledName, TypeInfoString; + SmallString<256> MangledName; { llvm::raw_svector_ostream Out(MangledName); getMangleContext().mangleCXXRTTI(Type, Out); @@ -3212,6 +3260,7 @@ llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(QualType Type) { return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy); // Compute the fields for the TypeDescriptor. + SmallString<256> TypeInfoString; { llvm::raw_svector_ostream Out(TypeInfoString); getMangleContext().mangleCXXRTTIName(Type, Out); diff --git a/clang/test/CodeGenCXX/microsoft-abi-try-throw.cpp b/clang/test/CodeGenCXX/microsoft-abi-try-throw.cpp index 8aecab4f655..c7bbcf28888 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-try-throw.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-try-throw.cpp @@ -6,6 +6,8 @@ // THROW-DAG: @_CTA1H = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.1 { i32 1, [1 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0H@84"] }, section ".xdata", comdat // THROW-DAG: @_TI1H = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i8* null, i8* null, i8* bitcast (%eh.CatchableTypeArray.1* @_CTA1H to i8*) }, section ".xdata", comdat +// TRY-DAG: @llvm.eh.handlermapentry.const.PAH = private unnamed_addr constant %eh.HandlerMapEntry { i32 1, i8* bitcast (%rtti.TypeDescriptor4* @"\01??_R0PAH@8" to i8*) }, section "llvm.metadata" + void external(); inline void not_emitted() { @@ -39,7 +41,7 @@ void qual_catch() { external(); } catch (const int *) { } - // TRY: catch i8* bitcast (%rtti.TypeDescriptor4* @"\01??_R0PAH@8" to i8*) - // TRY: call i32 @llvm.eh.typeid.for(i8* bitcast (%rtti.TypeDescriptor4* @"\01??_R0PAH@8" to i8*)) + // TRY: catch %eh.HandlerMapEntry* @llvm.eh.handlermapentry.const.PAH + // TRY: call i32 @llvm.eh.typeid.for(i8* bitcast (%eh.HandlerMapEntry* @llvm.eh.handlermapentry.const.PAH to i8*)) } #endif |