diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGCXXABI.h | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/ItaniumCXXABI.cpp | 5 | ||||
-rw-r--r-- | clang/lib/CodeGen/MicrosoftCXXABI.cpp | 78 |
4 files changed, 55 insertions, 32 deletions
diff --git a/clang/lib/CodeGen/CGCXXABI.h b/clang/lib/CodeGen/CGCXXABI.h index df2aa1a7b17..800f337e705 100644 --- a/clang/lib/CodeGen/CGCXXABI.h +++ b/clang/lib/CodeGen/CGCXXABI.h @@ -224,7 +224,7 @@ public: emitTerminateForUnexpectedException(CodeGenFunction &CGF, llvm::Value *Exn); - virtual llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) = 0; + virtual llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty, bool ForEH) = 0; virtual bool shouldTypeidBeNullChecked(bool IsDeref, QualType SrcRecordTy) = 0; diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index ac94e57c3e1..29c6872377b 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -3656,7 +3656,7 @@ llvm::Constant *CodeGenModule::GetAddrOfRTTIDescriptor(QualType Ty, LangOpts.ObjCRuntime.isGNUFamily()) return ObjCRuntime->GetEHType(Ty); - return getCXXABI().getAddrOfRTTIDescriptor(Ty); + return getCXXABI().getAddrOfRTTIDescriptor(Ty, ForEH); } void CodeGenModule::EmitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D) { diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 93407d9c3c7..2fb6a5ec41f 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -125,7 +125,7 @@ public: void EmitFundamentalRTTIDescriptor(QualType Type); void EmitFundamentalRTTIDescriptors(); - llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) override; + llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty, bool ForEH) override; bool shouldTypeidBeNullChecked(bool IsDeref, QualType SrcRecordTy) override; void EmitBadTypeidCall(CodeGenFunction &CGF) override; @@ -3101,7 +3101,8 @@ ItaniumRTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) { ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(QualType(ClassType, 0))); } -llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(QualType Ty) { +llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(QualType Ty, + bool ForEH) { return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty); } diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index beae92d31f3..89f0d4fa3bf 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -83,7 +83,7 @@ public: llvm::GlobalVariable *getMSCompleteObjectLocator(const CXXRecordDecl *RD, const VPtrInfo *Info); - llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) override; + llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty, bool ForEH) override; bool shouldTypeidBeNullChecked(bool IsDeref, QualType SrcRecordTy) override; void EmitBadTypeidCall(CodeGenFunction &CGF) override; @@ -3094,7 +3094,8 @@ MSRTTIBuilder::getBaseClassDescriptor(const MSRTTIClass &Class) { // Initialize the BaseClassDescriptor. llvm::Constant *Fields[] = { ABI.getImageRelativeConstant( - ABI.getAddrOfRTTIDescriptor(Context.getTypeDeclType(Class.RD))), + ABI.getAddrOfRTTIDescriptor(Context.getTypeDeclType(Class.RD), + /*ForEH=*/false)), llvm::ConstantInt::get(CGM.IntTy, Class.NumBases), llvm::ConstantInt::get(CGM.IntTy, Class.OffsetInVBase), llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset), @@ -3154,11 +3155,53 @@ MSRTTIBuilder::getCompleteObjectLocator(const VPtrInfo *Info) { return COL; } +static QualType decomposeTypeForEH(ASTContext &Context, QualType T, + bool &IsConst, bool &IsVolatile) { + T = Context.getExceptionObjectType(T); + + // C++14 [except.handle]p3: + // A handler is a match for an exception object of type E if [...] + // - the handler is of type cv T or const T& where T is a pointer type and + // E is a pointer type that can be converted to T by [...] + // - a qualification conversion + IsConst = false; + IsVolatile = false; + QualType PointeeType = T->getPointeeType(); + if (!PointeeType.isNull()) { + IsConst = PointeeType.isConstQualified(); + IsVolatile = PointeeType.isVolatileQualified(); + } + + // Member pointer types like "const int A::*" are represented by having RTTI + // for "int A::*" and separately storing the const qualifier. + if (const auto *MPTy = T->getAs<MemberPointerType>()) + T = Context.getMemberPointerType(PointeeType.getUnqualifiedType(), + MPTy->getClass()); + + // Pointer types like "const int * const *" are represented by having RTTI + // for "const int **" and separately storing the const qualifier. + if (T->isPointerType()) + T = Context.getPointerType(PointeeType.getUnqualifiedType()); + + return T; +} + /// \brief Gets a TypeDescriptor. Returns a llvm::Constant * rather than a /// llvm::GlobalVariable * because different type descriptors have different /// types, and need to be abstracted. They are abstracting by casting the /// address to an Int8PtrTy. -llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(QualType Type) { +llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(QualType Type, + bool ForEH) { + // TypeDescriptors for exceptions never has qualified pointer types, + // qualifiers are stored seperately in order to support qualification + // conversions. + if (ForEH) { + // FIXME: This is only a 50% solution, we need to actually do something with + // these qualifiers. + bool IsConst, IsVolatile; + Type = decomposeTypeForEH(getContext(), Type, IsConst, IsVolatile); + } + SmallString<256> MangledName, TypeInfoString; { llvm::raw_svector_ostream Out(MangledName); @@ -3374,7 +3417,8 @@ llvm::Constant *MicrosoftCXXABI::getCatchableType(QualType T, // The TypeDescriptor is used by the runtime to determine if a catch handler // is appropriate for the exception object. - llvm::Constant *TD = getImageRelativeConstant(getAddrOfRTTIDescriptor(T)); + llvm::Constant *TD = + getImageRelativeConstant(getAddrOfRTTIDescriptor(T, /*ForEH=*/true)); // The runtime is responsible for calling the copy constructor if the // exception is caught by value. @@ -3551,30 +3595,8 @@ llvm::GlobalVariable *MicrosoftCXXABI::getCatchableTypeArray(QualType T) { } llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(QualType T) { - T = getContext().getExceptionObjectType(T); - - // C++14 [except.handle]p3: - // A handler is a match for an exception object of type E if [...] - // - the handler is of type cv T or const T& where T is a pointer type and - // E is a pointer type that can be converted to T by [...] - // - a qualification conversion - bool IsConst = false, IsVolatile = false; - QualType PointeeType = T->getPointeeType(); - if (!PointeeType.isNull()) { - IsConst = PointeeType.isConstQualified(); - IsVolatile = PointeeType.isVolatileQualified(); - } - - // Member pointer types like "const int A::*" are represented by having RTTI - // for "int A::*" and separately storing the const qualifier. - if (const auto *MPTy = T->getAs<MemberPointerType>()) - T = getContext().getMemberPointerType(PointeeType.getUnqualifiedType(), - MPTy->getClass()); - - // Pointer types like "const int * const *" are represented by having RTTI - // for "const int **" and separately storing the const qualifier. - if (T->isPointerType()) - T = getContext().getPointerType(PointeeType.getUnqualifiedType()); + bool IsConst, IsVolatile; + T = decomposeTypeForEH(getContext(), T, IsConst, IsVolatile); // The CatchableTypeArray enumerates the various (CV-unqualified) types that // the exception object may be caught as. |