summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-03-17 20:35:05 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-03-17 20:35:05 +0000
commit5f0dd6162c941a32e89052f8848799df0553b7c7 (patch)
tree930bffd6d833243036aea31edd6bb365508f77ce /clang/lib/CodeGen
parent443250f08da3ea3396586f0349d8d34d42223633 (diff)
downloadbcm5719-llvm-5f0dd6162c941a32e89052f8848799df0553b7c7.tar.gz
bcm5719-llvm-5f0dd6162c941a32e89052f8848799df0553b7c7.zip
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. llvm-svn: 232538
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGCXXABI.h3
-rw-r--r--clang/lib/CodeGen/CGException.cpp3
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp6
-rw-r--r--clang/lib/CodeGen/CodeGenModule.h3
-rw-r--r--clang/lib/CodeGen/ItaniumCXXABI.cpp3
-rw-r--r--clang/lib/CodeGen/MicrosoftCXXABI.cpp61
6 files changed, 67 insertions, 12 deletions
diff --git a/clang/lib/CodeGen/CGCXXABI.h b/clang/lib/CodeGen/CGCXXABI.h
index 3a92d05e7e3..b6a94f9082d 100644
--- a/clang/lib/CodeGen/CGCXXABI.h
+++ b/clang/lib/CodeGen/CGCXXABI.h
@@ -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;
diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp
index 1a9ebb395fc..223b8f76d0d 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -567,7 +567,8 @@ void CodeGenFunction::EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
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.
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 03948d68cdc..c91de6df9e9 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -3644,8 +3644,10 @@ llvm::Constant *CodeGenModule::EmitUuidofInitializer(StringRef Uuid) {
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,
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index 7e5bd7caa5c..ce540e91dcb 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -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);
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index ca9322840eb..73bbfe071dd 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -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);
}
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index 7539ad8bdfa..6417b87444d 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -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(ASTContext &Context, QualType T,
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::getAddrOfCXXCatchDescriptor(QualType Type) {
/// 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::getAddrOfRTTIDescriptor(QualType Type) {
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);
OpenPOWER on IntegriCloud