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;
// 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),
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);
// 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.
}
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.