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
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to