David Majnemer <[email protected]> writes: > Author: majnemer > Date: Tue Mar 17 15:35:05 2015 > New Revision: 232538 > > URL: http://llvm.org/viewvc/llvm-project?rev=232538&view=rev > Log: > MS ABI: Emit HandlerMap entries for C++ catch > > The HandlerMap describes, to the runtime, what sort of catches surround > the try. In principle, this structure has to be emitted by the backend > because only it knows the layout of the stack (the runtime needs to know > where on the stack the destination of a copy lives, etc.) but there is > some C++ specific information that the backend can't reason about. > > Stick this information in special LLVM globals with the relevant > "const", "volatile", "reference" info mangled into the name.
I was getting a couple of -Winconsistent-missing-override warnings after this. I've fixed them in r232559. > Modified: > cfe/trunk/include/clang/AST/Mangle.h > cfe/trunk/lib/AST/MicrosoftMangle.cpp > cfe/trunk/lib/CodeGen/CGCXXABI.h > cfe/trunk/lib/CodeGen/CGException.cpp > cfe/trunk/lib/CodeGen/CodeGenModule.cpp > cfe/trunk/lib/CodeGen/CodeGenModule.h > cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp > cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp > cfe/trunk/test/CodeGenCXX/microsoft-abi-try-throw.cpp > > Modified: cfe/trunk/include/clang/AST/Mangle.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Mangle.h?rev=232538&r1=232537&r2=232538&view=diff > ============================================================================== > --- cfe/trunk/include/clang/AST/Mangle.h (original) > +++ cfe/trunk/include/clang/AST/Mangle.h Tue Mar 17 15:35:05 2015 > @@ -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; > > Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=232538&r1=232537&r2=232538&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original) > +++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Tue Mar 17 15:35:05 2015 > @@ -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::mangleC > 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, > > Modified: cfe/trunk/lib/CodeGen/CGCXXABI.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXABI.h?rev=232538&r1=232537&r2=232538&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGCXXABI.h (original) > +++ cfe/trunk/lib/CodeGen/CGCXXABI.h Tue Mar 17 15:35:05 2015 > @@ -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; > > Modified: cfe/trunk/lib/CodeGen/CGException.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGException.cpp?rev=232538&r1=232537&r2=232538&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGException.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGException.cpp Tue Mar 17 15:35:05 2015 > @@ -567,7 +567,8 @@ void CodeGenFunction::EnterCXXTryStmt(co > 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. > > Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=232538&r1=232537&r2=232538&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original) > +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Tue Mar 17 15:35:05 2015 > @@ -3644,8 +3644,10 @@ llvm::Constant *CodeGenModule::EmitUuido > 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, > > Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=232538&r1=232537&r2=232538&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CodeGenModule.h (original) > +++ cfe/trunk/lib/CodeGen/CodeGenModule.h Tue Mar 17 15:35:05 2015 > @@ -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); > > Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=232538&r1=232537&r2=232538&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original) > +++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Tue Mar 17 15:35:05 2015 > @@ -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); > } > > > Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=232538&r1=232537&r2=232538&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original) > +++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Tue Mar 17 15:35:05 2015 > @@ -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(ASTCo > 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::getAddr > /// 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::getAddr > 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); > > Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-try-throw.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-try-throw.cpp?rev=232538&r1=232537&r2=232538&view=diff > ============================================================================== > --- cfe/trunk/test/CodeGenCXX/microsoft-abi-try-throw.cpp (original) > +++ cfe/trunk/test/CodeGenCXX/microsoft-abi-try-throw.cpp Tue Mar 17 15:35:05 > 2015 > @@ -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 > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
