smeenai updated this revision to Diff 150399.
smeenai added a comment.
Address objc_exception attribute case
Repository:
rC Clang
https://reviews.llvm.org/D47233
Files:
lib/CodeGen/CGCXXABI.h
lib/CodeGen/CGObjCMac.cpp
lib/CodeGen/MicrosoftCXXABI.cpp
test/CodeGenObjC/dllstorage.m
test/CodeGenObjC/exceptions-msvc.m
Index: test/CodeGenObjC/exceptions-msvc.m
===================================================================
--- /dev/null
+++ test/CodeGenObjC/exceptions-msvc.m
@@ -0,0 +1,81 @@
+// RUN: %clang_cc1 -triple i686--windows-msvc -fobjc-runtime=ios-6.0 -fdeclspec -fexceptions -fobjc-exceptions -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK,X86 %s
+// RUN: %clang_cc1 -triple i686--windows-msvc -fobjc-runtime=ios-6.0 -fobjc-arc -fdeclspec -fexceptions -fobjc-exceptions -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK,X86 %s
+// RUN: %clang_cc1 -triple x86_64--windows-msvc -fobjc-runtime=ios-6.0 -fdeclspec -fexceptions -fobjc-exceptions -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK,X64 %s
+// RUN: %clang_cc1 -triple x86_64--windows-msvc -fobjc-runtime=ios-6.0 -fobjc-arc -fdeclspec -fexceptions -fobjc-exceptions -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK,X64 %s
+
+#if __has_feature(objc_arc)
+#define WEAK __weak
+#else
+#define WEAK
+#endif
+
+// CHECK-DAG: $OBJC_EHTYPE_id = comdat any
+// X86-DAG: @OBJC_EHTYPE_id = linkonce_odr global {{%[^ ]+}} { i8** @"??_7type_info@@6B@", i8* null, [18 x i8] c".PAUobjc_object@@\00" }, comdat
+// X64-DAG: @OBJC_EHTYPE_id = linkonce_odr global {{%[^ ]+}} { i8** @"??_7type_info@@6B@", i8* null, [19 x i8] c".PEAUobjc_object@@\00" }, comdat
+
+@class I;
+
+// CHECK-DAG: $"OBJC_EHTYPE_$_I" = comdat any
+// X86-DAG: @"OBJC_EHTYPE_$_I" = linkonce_odr global {{%[^ ]+}} { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".PAUI@@\00" }, comdat
+// X64-DAG: @"OBJC_EHTYPE_$_I" = linkonce_odr global {{%[^ ]+}} { i8** @"??_7type_info@@6B@", i8* null, [9 x i8] c".PEAUI@@\00" }, comdat
+
+@class J;
+
+// CHECK-DAG: $"OBJC_EHTYPE_$_J" = comdat any
+// X86-DAG: @"OBJC_EHTYPE_$_J" = linkonce_odr global {{%[^ ]+}} { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".PAUJ@@\00" }, comdat
+// X64-DAG: @"OBJC_EHTYPE_$_J" = linkonce_odr global {{%[^ ]+}} { i8** @"??_7type_info@@6B@", i8* null, [9 x i8] c".PEAUJ@@\00" }, comdat
+
+// The EHType shouldn't be exported
+__declspec(dllexport)
+__attribute__((objc_root_class))
+@interface K
+@end
+
+@implementation K
+@end
+
+// CHECK-DAG: $"OBJC_EHTYPE_$_K" = comdat any
+// X86-DAG: @"OBJC_EHTYPE_$_K" = linkonce_odr global {{%[^ ]+}} { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".PAUK@@\00" }, comdat
+// X64-DAG: @"OBJC_EHTYPE_$_K" = linkonce_odr global {{%[^ ]+}} { i8** @"??_7type_info@@6B@", i8* null, [9 x i8] c".PEAUK@@\00" }, comdat
+
+__attribute__((objc_root_class))
+__attribute__((objc_runtime_name("NotL")))
+@interface L
+@end
+
+// CHECK-DAG: $"OBJC_EHTYPE_$_NotL" = comdat any
+// X86-DAG: @"OBJC_EHTYPE_$_NotL" = linkonce_odr global {{%[^ ]+}} { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".PAUL@@\00" }, comdat
+// X64-DAG: @"OBJC_EHTYPE_$_NotL" = linkonce_odr global {{%[^ ]+}} { i8** @"??_7type_info@@6B@", i8* null, [9 x i8] c".PEAUL@@\00" }, comdat
+
+@class M;
+
+// CHECK-DAG: $"OBJC_EHTYPE_$_M" = comdat any
+// X86-DAG: @"OBJC_EHTYPE_$_M" = linkonce_odr global {{%[^ ]+}} { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".PAUM@@\00" }, comdat
+// X64-DAG: @"OBJC_EHTYPE_$_M" = linkonce_odr global {{%[^ ]+}} { i8** @"??_7type_info@@6B@", i8* null, [9 x i8] c".PEAUM@@\00" }, comdat
+
+// The EHType shouldn't be generated for this definition, since it's not referenced.
+__attribute__((objc_root_class))
+__attribute__((objc_exception))
+@interface N
+@end
+
+@implementation N
+@end
+
+// CHECK-NOT: @"OBJC_EHTYPE_$_N"
+
+@protocol P;
+
+void f(void);
+
+void g() {
+ @try {
+ f();
+ } @catch (I *) {
+ } @catch (J<P> *) {
+ } @catch (K *) {
+ } @catch (L *) {
+ } @catch (M *WEAK) {
+ } @catch (id) {
+ }
+}
Index: test/CodeGenObjC/dllstorage.m
===================================================================
--- test/CodeGenObjC/dllstorage.m
+++ test/CodeGenObjC/dllstorage.m
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -fdeclspec -fobjc-runtime=ios -fobjc-exceptions -S -emit-llvm -o - %s | FileCheck -check-prefix CHECK-IR %s
-// RUN: %clang_cc1 -triple i686-windows-itanium -fms-extensions -fobjc-runtime=macosx -fdeclspec -fobjc-exceptions -S -emit-llvm -o - %s | FileCheck -check-prefix CHECK-IR %s
+// RUN: %clang_cc1 -triple i686-windows-itanium -fms-extensions -fobjc-runtime=macosx -fdeclspec -fobjc-exceptions -S -emit-llvm -o - %s | FileCheck -check-prefix CHECK-IR -check-prefix CHECK-ITANIUM %s
// RUN: %clang_cc1 -triple i686-windows-itanium -fms-extensions -fobjc-runtime=objfw -fdeclspec -fobjc-exceptions -S -emit-llvm -o - %s | FileCheck -check-prefix CHECK-FW %s
// CHECK-IR-DAG: @_objc_empty_cache = external dllimport global %struct._objc_cache
@@ -100,20 +100,20 @@
@implementation N : I
@end
-// CHECK-IR-DAG: @"OBJC_EHTYPE_$_N" = dso_local dllexport global %struct._objc_typeinfo
+// CHECK-ITANIUM-DAG: @"OBJC_EHTYPE_$_N" = dso_local dllexport global %struct._objc_typeinfo
__declspec(dllimport)
__attribute__((__objc_exception__))
@interface O : I
@end
-// CHECK-IR-DAG: @"OBJC_EHTYPE_$_O" = external dllimport global %struct._objc_typeinfo
+// CHECK-ITANIUM-DAG: @"OBJC_EHTYPE_$_O" = external dllimport global %struct._objc_typeinfo
__attribute__((__objc_exception__))
@interface P : I
@end
-// CHECK-IR-DAG: @"OBJC_EHTYPE_$_P" = external dso_local global %struct._objc_typeinfo
+// CHECK-ITANIUM-DAG: @"OBJC_EHTYPE_$_P" = external dso_local global %struct._objc_typeinfo
@interface Q : M
@end
@@ -153,9 +153,9 @@
return 0;
}
-// CHECK-IR-DAG: @OBJC_EHTYPE_id = external dllimport global %struct._objc_typeinfo
-// CHECK-IR-DAG: @"OBJC_EHTYPE_$_I" = weak global %struct._objc_typeinfo
-// CHECK-IR-DAG: @"OBJC_EHTYPE_$_K" = weak global %struct._objc_typeinfo
-// CHECK-IR-DAG: @"OBJC_EHTYPE_$_L" = weak global %struct._objc_typeinfo
-// CHECK-IR-DAG: @"OBJC_EHTYPE_$_M" = weak global %struct._objc_typeinfo
+// CHECK-ITANIUM-DAG: @OBJC_EHTYPE_id = external dllimport global %struct._objc_typeinfo
+// CHECK-ITANIUM-DAG: @"OBJC_EHTYPE_$_I" = weak global %struct._objc_typeinfo
+// CHECK-ITANIUM-DAG: @"OBJC_EHTYPE_$_K" = weak global %struct._objc_typeinfo
+// CHECK-ITANIUM-DAG: @"OBJC_EHTYPE_$_L" = weak global %struct._objc_typeinfo
+// CHECK-ITANIUM-DAG: @"OBJC_EHTYPE_$_M" = weak global %struct._objc_typeinfo
Index: lib/CodeGen/MicrosoftCXXABI.cpp
===================================================================
--- lib/CodeGen/MicrosoftCXXABI.cpp
+++ lib/CodeGen/MicrosoftCXXABI.cpp
@@ -126,6 +126,8 @@
const VPtrInfo &Info);
llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) override;
+ llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty,
+ StringRef MangledName) override;
CatchTypeInfo
getAddrOfCXXCatchHandlerType(QualType Ty, QualType CatchHandlerType) override;
@@ -3759,7 +3761,11 @@
llvm::raw_svector_ostream Out(MangledName);
getMangleContext().mangleCXXRTTI(Type, Out);
}
+ return getAddrOfRTTIDescriptor(Type, MangledName);
+}
+llvm::Constant *
+MicrosoftCXXABI::getAddrOfRTTIDescriptor(QualType Type, StringRef MangledName) {
// Check to see if we've already declared this TypeDescriptor.
if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(MangledName))
return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy);
Index: lib/CodeGen/CGObjCMac.cpp
===================================================================
--- lib/CodeGen/CGObjCMac.cpp
+++ lib/CodeGen/CGObjCMac.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "CGBlocks.h"
+#include "CGCXXABI.h"
#include "CGCleanup.h"
#include "CGObjCRuntime.h"
#include "CGRecordLayout.h"
@@ -6358,7 +6359,9 @@
DefinedNonLazyClasses.push_back(ClassMD);
// Force the definition of the EHType if necessary.
- if (flags & NonFragileABI_Class_Exception)
+ // Windows MSVC will just emit the EHType locally wherever needed instead.
+ if ((flags & NonFragileABI_Class_Exception) &&
+ !CGM.getTriple().isWindowsMSVCEnvironment())
(void) GetInterfaceEHType(CI, ForDefinition);
// Make sure method definition entries are all clear for next implementation.
MethodDefinitions.clear();
@@ -7456,6 +7459,10 @@
CGObjCNonFragileABIMac::GetEHType(QualType T) {
// There's a particular fixed type info for 'id'.
if (T->isObjCIdType() || T->isObjCQualifiedIdType()) {
+ if (CGM.getTriple().isWindowsMSVCEnvironment())
+ return CGM.getCXXABI().getAddrOfRTTIDescriptor(
+ T.getLocalUnqualifiedType(), "OBJC_EHTYPE_id");
+
auto *IDEHType = CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id");
if (!IDEHType) {
IDEHType =
@@ -7475,7 +7482,15 @@
const ObjCInterfaceType *IT = PT->getInterfaceType();
assert(IT && "Invalid @catch type.");
- return GetInterfaceEHType(IT->getDecl(), NotForDefinition);
+ const ObjCInterfaceDecl *ID = IT->getDecl();
+ if (CGM.getTriple().isWindowsMSVCEnvironment()) {
+ const ASTContext &Ctx = CGM.getContext();
+ return CGM.getCXXABI().getAddrOfRTTIDescriptor(
+ Ctx.getObjCObjectPointerType(IT->stripObjCKindOfTypeAndQuals(Ctx)),
+ ("OBJC_EHTYPE_$_" + ID->getObjCRuntimeNameAsString()).str());
+ }
+
+ return GetInterfaceEHType(ID, NotForDefinition);
}
void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
@@ -7508,6 +7523,9 @@
llvm::Constant *
CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
ForDefinition_t IsForDefinition) {
+ assert(!CGM.getTriple().isWindowsMSVCEnvironment() &&
+ "MSVC EHType should be emitted by GetEHType");
+
llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
StringRef ClassName = ID->getObjCRuntimeNameAsString();
Index: lib/CodeGen/CGCXXABI.h
===================================================================
--- lib/CodeGen/CGCXXABI.h
+++ lib/CodeGen/CGCXXABI.h
@@ -249,6 +249,10 @@
llvm::Value *Exn);
virtual llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) = 0;
+ virtual llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty,
+ StringRef MangledName) {
+ llvm_unreachable("Only needed for the Microsoft ABI");
+ }
virtual CatchTypeInfo
getAddrOfCXXCatchHandlerType(QualType Ty, QualType CatchHandlerType) = 0;
virtual CatchTypeInfo getCatchAllTypeInfo();
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits