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,
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,
: 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;
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;
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;
llvm::StructType *CatchableTypeType;
llvm::DenseMap<uint32_t, llvm::StructType *> CatchableTypeArrayTypeMap;
llvm::StructType *ThrowInfoType;
+ llvm::StructType *HandlerMapEntryType;
};
}
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
/// 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);
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);