r232538 - MS ABI: Emit HandlerMap entries for C++ catch
Justin Bogner
mail at justinbogner.com
Tue Mar 17 15:34:32 PDT 2015
David Majnemer <david.majnemer at gmail.com> 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 at 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 at 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 at 8" to i8*)
> - // TRY: call i32 @llvm.eh.typeid.for(i8* bitcast (%rtti.TypeDescriptor4* @"\01??_R0PAH at 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
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list