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