smeenai created this revision.
smeenai added reviewers: compnerd, DHowett-MSFT, rjmccall, rnk, theraven.
Herald added a subscriber: erik.pilkington.

Obj-C classes are mangled as C++ structs with the same name (in both the
Itanium and the Microsoft ABIs), but we want to be able to distinguish
them for the purposes of exception handling, so we need to add a
discriminator to the RTTI and the RTTI name.

The chosen discriminator (`.objc`) is fairly arbitrary, and I'm open to
other suggestions. It's also perhaps not ideal to have the discriminator
as a prefix, since then the RTTI won't demangle (RTTI names never
demangle anyway, so that's less of a concern). Having it infix would
make for a cleaner mangling, but it would also require keeping some
state around in the mangler to indicate when we're mangling for RTTI,
which seems like a much uglier implementation and not worth it.


Repository:
  rC Clang

https://reviews.llvm.org/D52674

Files:
  lib/AST/MicrosoftMangle.cpp
  test/CodeGenObjCXX/arc-marker-funclet.mm
  test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm
  test/CodeGenObjCXX/msabi-objc-exceptions-gnustep.mm
  test/CodeGenObjCXX/msabi-objc-extensions.mm
  test/CodeGenObjCXX/msabi-objc-types.mm

Index: test/CodeGenObjCXX/msabi-objc-types.mm
===================================================================
--- test/CodeGenObjCXX/msabi-objc-types.mm
+++ test/CodeGenObjCXX/msabi-objc-types.mm
@@ -3,166 +3,166 @@
 @class I;
 
 id kid;
-// CHECK: @"?kid@@3PAU.objc_object@@A" =  dso_local global
+// CHECK: @"?kid@@3PAUobjc_object@@A" =  dso_local global
 
 Class klass;
-// CHECK: @"?klass@@3PAU.objc_class@@A" = dso_local global
+// CHECK: @"?klass@@3PAUobjc_class@@A" = dso_local global
 
 I *kI;
-// CHECK: @"?kI@@3PAU.objc_cls_I@@A" = dso_local global
+// CHECK: @"?kI@@3PAUI@@A" = dso_local global
 
 void f(I *) {}
-// CHECK-LABEL: "?f@@YAXPAU.objc_cls_I@@@Z"
+// CHECK-LABEL: "?f@@YAXPAUI@@@Z"
 
 void f(const I *) {}
-// CHECK-LABEL: "?f@@YAXPBU.objc_cls_I@@@Z"
+// CHECK-LABEL: "?f@@YAXPBUI@@@Z"
 
 void f(I &) {}
-// CHECK-LABEL: "?f@@YAXAAU.objc_cls_I@@@Z"
+// CHECK-LABEL: "?f@@YAXAAUI@@@Z"
 
 void f(const I &) {}
-// CHECK-LABEL: "?f@@YAXABU.objc_cls_I@@@Z"
+// CHECK-LABEL: "?f@@YAXABUI@@@Z"
 
 void f(const I &&) {}
-// CHECK-LABEL: "?f@@YAX$$QBU.objc_cls_I@@@Z"
+// CHECK-LABEL: "?f@@YAX$$QBUI@@@Z"
 
 void g(id) {}
-// CHECK-LABEL: "?g@@YAXPAU.objc_object@@@Z"
+// CHECK-LABEL: "?g@@YAXPAUobjc_object@@@Z"
 
 void g(id &) {}
-// CHECK-LABEL: "?g@@YAXAAPAU.objc_object@@@Z"
+// CHECK-LABEL: "?g@@YAXAAPAUobjc_object@@@Z"
 
 void g(const id &) {}
-// CHECK-LABEL: "?g@@YAXABQAU.objc_object@@@Z"
+// CHECK-LABEL: "?g@@YAXABQAUobjc_object@@@Z"
 
 void g(id &&) {}
-// CHECK-LABEL: "?g@@YAX$$QAPAU.objc_object@@@Z"
+// CHECK-LABEL: "?g@@YAX$$QAPAUobjc_object@@@Z"
 
 void h(Class) {}
-// CHECK-LABEL: "?h@@YAXPAU.objc_class@@@Z"
+// CHECK-LABEL: "?h@@YAXPAUobjc_class@@@Z"
 
 void h(Class &) {}
-// CHECK-LABEL: "?h@@YAXAAPAU.objc_class@@@Z"
+// CHECK-LABEL: "?h@@YAXAAPAUobjc_class@@@Z"
 
 void h(const Class &) {}
-// CHECK-LABEL: "?h@@YAXABQAU.objc_class@@@Z"
+// CHECK-LABEL: "?h@@YAXABQAUobjc_class@@@Z"
 
 void h(Class &&) {}
-// CHECK-LABEL: "?h@@YAX$$QAPAU.objc_class@@@Z"
+// CHECK-LABEL: "?h@@YAX$$QAPAUobjc_class@@@Z"
 
 I *i() { return nullptr; }
-// CHECK-LABEL: "?i@@YAPAU.objc_cls_I@@XZ"
+// CHECK-LABEL: "?i@@YAPAUI@@XZ"
 
 const I *j() { return nullptr; }
-// CHECK-LABEL: "?j@@YAPBU.objc_cls_I@@XZ"
+// CHECK-LABEL: "?j@@YAPBUI@@XZ"
 
 I &k() { return *kI; }
-// CHECK-LABEL: "?k@@YAAAU.objc_cls_I@@XZ"
+// CHECK-LABEL: "?k@@YAAAUI@@XZ"
 
 const I &l() { return *kI; }
-// CHECK-LABEL: "?l@@YAABU.objc_cls_I@@XZ"
+// CHECK-LABEL: "?l@@YAABUI@@XZ"
 
 void m(const id) {}
-// CHECK-LABEL: "?m@@YAXQAU.objc_object@@@Z"
+// CHECK-LABEL: "?m@@YAXQAUobjc_object@@@Z"
 
 void m(const I *) {}
-// CHECK-LABEL: "?m@@YAXPBU.objc_cls_I@@@Z"
+// CHECK-LABEL: "?m@@YAXPBUI@@@Z"
 
 void n(SEL) {}
-// CHECK-LABEL: "?n@@YAXPAU.objc_selector@@@Z"
+// CHECK-LABEL: "?n@@YAXPAUobjc_selector@@@Z"
 
 void n(SEL *) {}
-// CHECK-LABEL: "?n@@YAXPAPAU.objc_selector@@@Z"
+// CHECK-LABEL: "?n@@YAXPAPAUobjc_selector@@@Z"
 
 void n(const SEL *) {}
-// CHECK-LABEL: "?n@@YAXPBQAU.objc_selector@@@Z"
+// CHECK-LABEL: "?n@@YAXPBQAUobjc_selector@@@Z"
 
 void n(SEL &) {}
-// CHECK-LABEL: "?n@@YAXAAPAU.objc_selector@@@Z"
+// CHECK-LABEL: "?n@@YAXAAPAUobjc_selector@@@Z"
 
 void n(const SEL &) {}
-// CHECK-LABEL: "?n@@YAXABQAU.objc_selector@@@Z"
+// CHECK-LABEL: "?n@@YAXABQAUobjc_selector@@@Z"
 
 void n(SEL &&) {}
-// CHECK-LABEL: "?n@@YAX$$QAPAU.objc_selector@@@Z"
+// CHECK-LABEL: "?n@@YAX$$QAPAUobjc_selector@@@Z"
 
 struct __declspec(dllexport) s {
   struct s &operator=(const struct s &) = delete;
 
   void m(I *) {}
-  // CHECK-LABEL: "?m@s@@QAAXPAU.objc_cls_I@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXPAUI@@@Z"
 
   void m(const I *) {}
-  // CHECK-LABEL: "?m@s@@QAAXPBU.objc_cls_I@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXPBUI@@@Z"
 
   void m(I &) {}
-  // CHECK-LABEL: "?m@s@@QAAXAAU.objc_cls_I@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXAAUI@@@Z"
 
   void m(const I &) {}
-  // CHECK-LABEL: "?m@s@@QAAXABU.objc_cls_I@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXABUI@@@Z"
 
   void m(I &&) {}
-  // CHECK-LABEL: "?m@s@@QAAX$$QAU.objc_cls_I@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAX$$QAUI@@@Z"
 
   void m(const I &&) {}
-  // CHECK-LABEL: "?m@s@@QAAX$$QBU.objc_cls_I@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAX$$QBUI@@@Z"
 
   void m(id) {}
-  // CHECK-LABEL: "?m@s@@QAAXPAU.objc_object@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXPAUobjc_object@@@Z"
 
   void m(id &) {}
-  // CHECK-LABEL: "?m@s@@QAAXAAPAU.objc_object@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXAAPAUobjc_object@@@Z"
 
   void m(id &&) {}
-  // CHECK-LABEL: "?m@s@@QAAX$$QAPAU.objc_object@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAX$$QAPAUobjc_object@@@Z"
 
   void m(const id &) {}
-  // CHECK-LABEL: "?m@s@@QAAXABQAU.objc_object@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXABQAUobjc_object@@@Z"
 
   void m(const id &&) {}
-  // CHECK-LABEL: "?m@s@@QAAX$$QBQAU.objc_object@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAX$$QBQAUobjc_object@@@Z"
 
   void m(Class *) {}
-  // CHECK-LABEL: "?m@s@@QAAXPAPAU.objc_class@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXPAPAUobjc_class@@@Z"
 
   void m(const Class *) {}
-  // CHECK-LABEL: "?m@s@@QAAXPBQAU.objc_class@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXPBQAUobjc_class@@@Z"
 
   void m(Class) {}
-  // CHECK-LABEL: "?m@s@@QAAXPAU.objc_class@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXPAUobjc_class@@@Z"
 
   void m(Class &) {}
-  // CHECK-LABEL: "?m@s@@QAAXAAPAU.objc_class@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXAAPAUobjc_class@@@Z"
 
   void m(const Class &) {}
-  // CHECK-LABEL: "?m@s@@QAAXABQAU.objc_class@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXABQAUobjc_class@@@Z"
 
   void m(Class &&) {}
-  // CHECK-LABEL: "?m@s@@QAAX$$QAPAU.objc_class@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAX$$QAPAUobjc_class@@@Z"
 
   void m(const Class &&) {}
-  // CHECK-LABEL: "?m@s@@QAAX$$QBQAU.objc_class@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAX$$QBQAUobjc_class@@@Z"
 
   void m(SEL) {}
-  // CHECK-LABEL: "?m@s@@QAAXPAU.objc_selector@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXPAUobjc_selector@@@Z"
 
   void m(SEL *) {}
-  // CHECK-LABEL: "?m@s@@QAAXPAPAU.objc_selector@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXPAPAUobjc_selector@@@Z"
 
   void m(const SEL *) {}
-  // CHECK-LABEL: "?m@s@@QAAXPBQAU.objc_selector@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXPBQAUobjc_selector@@@Z"
 
   void m(SEL &) {}
-  // CHECK-LABEL: "?m@s@@QAAXAAPAU.objc_selector@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXAAPAUobjc_selector@@@Z"
 
   void m(const SEL &) {}
-  // CHECK-LABEL: "?m@s@@QAAXABQAU.objc_selector@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXABQAUobjc_selector@@@Z"
 
   void m(SEL &&) {}
-  // CHECK-LABEL: "?m@s@@QAAX$$QAPAU.objc_selector@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAX$$QAPAUobjc_selector@@@Z"
 
   void m(const SEL &&) {}
-  // CHECK-LABEL: "?m@s@@QAAX$$QBQAU.objc_selector@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAX$$QBQAUobjc_selector@@@Z"
 };
 
 template <typename T>
@@ -179,14 +179,14 @@
 };
 
 template struct t<id>;
-// CHECK-LABEL: "??0?$t@PAU.objc_object@@@@QAA@XZ"
+// CHECK-LABEL: "??0?$t@PAUobjc_object@@@@QAA@XZ"
 
 template struct t<remove_pointer<id>::type>;
-// CHECK-LABEL: "??0?$t@U.objc_object@@@@QAA@XZ"
+// CHECK-LABEL: "??0?$t@Uobjc_object@@@@QAA@XZ"
 
 template struct t<SEL>;
-// CHECK-LABEL: "??0?$t@PAU.objc_selector@@@@QAA@XZ"
+// CHECK-LABEL: "??0?$t@PAUobjc_selector@@@@QAA@XZ"
 
 template struct t<remove_pointer<SEL>::type>;
-// CHECK-LABEL: "??0?$t@U.objc_selector@@@@QAA@XZ"
+// CHECK-LABEL: "??0?$t@Uobjc_selector@@@@QAA@XZ"
 
Index: test/CodeGenObjCXX/msabi-objc-extensions.mm
===================================================================
--- test/CodeGenObjCXX/msabi-objc-extensions.mm
+++ test/CodeGenObjCXX/msabi-objc-extensions.mm
@@ -7,92 +7,91 @@
 @class J<T>;
 
 void f(id<P>, id, id<P>, id) {}
-// CHECK-LABEL: "?f@@YAXPAU?$.objc_object@U?$Protocol@UP@@@__ObjC@@@@PAU.objc_object@@01@Z"
+// CHECK-LABEL: "?f@@YAXPAU?$objc_object@U?$Protocol@UP@@@__ObjC@@@@PAUobjc_object@@01@Z"
 
 void f(id, id<P>, id<P>, id) {}
-// CHECK-LABEL: "?f@@YAXPAU.objc_object@@PAU?$.objc_object@U?$Protocol@UP@@@__ObjC@@@@10@Z"
+// CHECK-LABEL: "?f@@YAXPAUobjc_object@@PAU?$objc_object@U?$Protocol@UP@@@__ObjC@@@@10@Z"
 
 void f(id<P>, id<P>) {}
-// CHECK-LABEL: "?f@@YAXPAU?$.objc_object@U?$Protocol@UP@@@__ObjC@@@@0@Z"
+// CHECK-LABEL: "?f@@YAXPAU?$objc_object@U?$Protocol@UP@@@__ObjC@@@@0@Z"
 
 void f(id<P>) {}
-// CHECK-LABEL: "?f@@YAXPAU?$.objc_object@U?$Protocol@UP@@@__ObjC@@@@@Z"
+// CHECK-LABEL: "?f@@YAXPAU?$objc_object@U?$Protocol@UP@@@__ObjC@@@@@Z"
 
 void f(id<P, Q>) {}
-// CHECK-LABEL: "?f@@YAXPAU?$.objc_object@U?$Protocol@UP@@@__ObjC@@U?$Protocol@UQ@@@2@@@@Z"
+// CHECK-LABEL: "?f@@YAXPAU?$objc_object@U?$Protocol@UP@@@__ObjC@@U?$Protocol@UQ@@@2@@@@Z"
 
 void f(Class<P>) {}
-// CHECK-LABEL: "?f@@YAXPAU?$.objc_class@U?$Protocol@UP@@@__ObjC@@@@@Z"
+// CHECK-LABEL: "?f@@YAXPAU?$objc_class@U?$Protocol@UP@@@__ObjC@@@@@Z"
 
 void f(Class<P, Q>) {}
-// CHECK-LABEL: "?f@@YAXPAU?$.objc_class@U?$Protocol@UP@@@__ObjC@@U?$Protocol@UQ@@@2@@@@Z"
+// CHECK-LABEL: "?f@@YAXPAU?$objc_class@U?$Protocol@UP@@@__ObjC@@U?$Protocol@UQ@@@2@@@@Z"
 
 void f(I<P> *) {}
-// CHECK-LABEL: "?f@@YAXPAU?$.objc_cls_I@U?$Protocol@UP@@@__ObjC@@@@@Z"
+// CHECK-LABEL: "?f@@YAXPAU?$I@U?$Protocol@UP@@@__ObjC@@@@@Z"
 
 void f(I<P, Q> *) {}
-// CHECK-LABEL: "?f@@YAXPAU?$.objc_cls_I@U?$Protocol@UP@@@__ObjC@@U?$Protocol@UQ@@@2@@@@Z"
+// CHECK-LABEL: "?f@@YAXPAU?$I@U?$Protocol@UP@@@__ObjC@@U?$Protocol@UQ@@@2@@@@Z"
 
 template <typename>
 struct S {};
 
 void f(S<__unsafe_unretained id>) {}
-// CHECK-LABEL: "?f@@YAXU?$S@PAU.objc_object@@@@@Z"
+// CHECK-LABEL: "?f@@YAXU?$S@PAUobjc_object@@@@@Z"
 
 void f(S<__autoreleasing id>) {}
-// CHECK-LABEL: "?f@@YAXU?$S@U?$Autoreleasing@PAU.objc_object@@@__ObjC@@@@@Z"
+// CHECK-LABEL: "?f@@YAXU?$S@U?$Autoreleasing@PAUobjc_object@@@__ObjC@@@@@Z"
 
 void f(S<__strong id>) {}
-// CHECK-LABEL: "?f@@YAXU?$S@U?$Strong@PAU.objc_object@@@__ObjC@@@@@Z"
+// CHECK-LABEL: "?f@@YAXU?$S@U?$Strong@PAUobjc_object@@@__ObjC@@@@@Z"
 
 void f(S<__weak id>) {}
-// CHECK-LABEL: "?f@@YAXU?$S@U?$Weak@PAU.objc_object@@@__ObjC@@@@@Z"
+// CHECK-LABEL: "?f@@YAXU?$S@U?$Weak@PAUobjc_object@@@__ObjC@@@@@Z"
 
 void w(__weak id) {}
-// CHECK-LABEL: "?w@@YAXPAU.objc_object@@@Z"
+// CHECK-LABEL: "?w@@YAXPAUobjc_object@@@Z"
 
 void s(__strong id) {}
-// CHECK-LABEL: "?s@@YAXPAU.objc_object@@@Z"
+// CHECK-LABEL: "?s@@YAXPAUobjc_object@@@Z"
 
 void a(__autoreleasing id) {}
-// CHECK-LABEL: "?a@@YAXPAU.objc_object@@@Z"
+// CHECK-LABEL: "?a@@YAXPAUobjc_object@@@Z"
 
 void u(__unsafe_unretained id) {}
-// CHECK-LABEL: "?u@@YAXPAU.objc_object@@@Z"
+// CHECK-LABEL: "?u@@YAXPAUobjc_object@@@Z"
 
 S<__autoreleasing id> g() { return S<__autoreleasing id>(); }
-// CHECK-LABEL: "?g@@YA?AU?$S@U?$Autoreleasing@PAU.objc_object@@@__ObjC@@@@XZ"
+// CHECK-LABEL: "?g@@YA?AU?$S@U?$Autoreleasing@PAUobjc_object@@@__ObjC@@@@XZ"
 
 __autoreleasing id h() { return nullptr; }
-// CHECK-LABEL: "?h@@YAPAU.objc_object@@XZ"
+// CHECK-LABEL: "?h@@YAPAUobjc_object@@XZ"
 
 void f(I *) {}
-// CHECK-LABEL: "?f@@YAXPAU.objc_cls_I@@@Z"
+// CHECK-LABEL: "?f@@YAXPAUI@@@Z"
 
 void f(__kindof I *) {}
-// CHECK-LABEL: "?f@@YAXPAU?$KindOf@U.objc_cls_I@@@__ObjC@@@Z"
+// CHECK-LABEL: "?f@@YAXPAU?$KindOf@UI@@@__ObjC@@@Z"
 
 void f(__kindof I<P> *) {}
-// CHECK-LABEL: "?f@@YAXPAU?$KindOf@U?$.objc_cls_I@U?$Protocol@UP@@@__ObjC@@@@@__ObjC@@@Z"
+// CHECK-LABEL: "?f@@YAXPAU?$KindOf@U?$I@U?$Protocol@UP@@@__ObjC@@@@@__ObjC@@@Z"
 
 void f(S<I *>) {}
-// CHECK-LABEL: "?f@@YAXU?$S@U?$Strong@PAU.objc_cls_I@@@__ObjC@@@@@Z"
+// CHECK-LABEL: "?f@@YAXU?$S@U?$Strong@PAUI@@@__ObjC@@@@@Z"
 
 void f(S<__kindof I *>) {}
-// CHECK-LABEL: "?f@@YAXU?$S@U?$Strong@PAU?$KindOf@U.objc_cls_I@@@__ObjC@@@__ObjC@@@@@Z"
+// CHECK-LABEL: "?f@@YAXU?$S@U?$Strong@PAU?$KindOf@UI@@@__ObjC@@@__ObjC@@@@@Z"
 
 void f(S<__kindof I<P> *>) {}
-// CHECK-LABEL: "?f@@YAXU?$S@U?$Strong@PAU?$KindOf@U?$.objc_cls_I@U?$Protocol@UP@@@__ObjC@@@@@__ObjC@@@__ObjC@@@@@Z"
+// CHECK-LABEL: "?f@@YAXU?$S@U?$Strong@PAU?$KindOf@U?$I@U?$Protocol@UP@@@__ObjC@@@@@__ObjC@@@__ObjC@@@@@Z"
 
 void f(S<__weak __kindof I *>) {}
-// CHECK-LABEL: "?f@@YAXU?$S@U?$Weak@PAU?$KindOf@U.objc_cls_I@@@__ObjC@@@__ObjC@@@@@Z"
+// CHECK-LABEL: "?f@@YAXU?$S@U?$Weak@PAU?$KindOf@UI@@@__ObjC@@@__ObjC@@@@@Z"
 
 void f(S<__weak __kindof I<P> *>) {}
-// CHECK-LABEL: "?f@@YAXU?$S@U?$Weak@PAU?$KindOf@U?$.objc_cls_I@U?$Protocol@UP@@@__ObjC@@@@@__ObjC@@@__ObjC@@@@@Z"
+// CHECK-LABEL: "?f@@YAXU?$S@U?$Weak@PAU?$KindOf@U?$I@U?$Protocol@UP@@@__ObjC@@@@@__ObjC@@@__ObjC@@@@@Z"
 
 void f(J<I *> *) {}
-// CHECK-LABEL: "?f@@YAXPAU?$.objc_cls_J@PAU.objc_cls_I@@@@@Z"
+// CHECK-LABEL: "?f@@YAXPAU?$J@PAUI@@@@@Z"
 
 void f(J<__kindof I *> *) {}
-// CHECK-LABEL: "?f@@YAXPAU?$.objc_cls_J@PAU?$KindOf@U.objc_cls_I@@@__ObjC@@@@@Z"
-
+// CHECK-LABEL: "?f@@YAXPAU?$J@PAU?$KindOf@UI@@@__ObjC@@@@@Z"
Index: test/CodeGenObjCXX/msabi-objc-exceptions-gnustep.mm
===================================================================
--- /dev/null
+++ test/CodeGenObjCXX/msabi-objc-exceptions-gnustep.mm
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc -fobjc-runtime=gnustep-2.0 -fexceptions -fobjc-exceptions -emit-llvm -o - %s | FileCheck -check-prefix=X86 %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fobjc-runtime=gnustep-2.0 -fexceptions -fobjc-exceptions -emit-llvm -o - %s | FileCheck -check-prefix=X64 %s
+
+// Ensure we have the .objc discriminator in the RTTI and the RTTI name.
+// X86-DAG: @"??_R0objc.PAUobjc_object@@@8" = linkonce_odr global %{{[^ ]+}} { i8** @"??_7type_info@@6B@", i8* null, [23 x i8] c".objc.PAUobjc_object@@\00" }, comdat
+// X64-DAG: @"??_R0objc.PEAUobjc_object@@@8" = linkonce_odr global %{{[^ ]+}} { i8** @"??_7type_info@@6B@", i8* null, [24 x i8] c".objc.PEAUobjc_object@@\00" }, comdat
+
+@class I;
+// X86-DAG: @"??_R0objc.PAUI@@@8" = linkonce_odr global %{{[^ ]+}} { i8** @"??_7type_info@@6B@", i8* null, [13 x i8] c".objc.PAUI@@\00" }, comdat
+// X64-DAG: @"??_R0objc.PEAUI@@@8" = linkonce_odr global %{{[^ ]+}} { i8** @"??_7type_info@@6B@", i8* null, [14 x i8] c".objc.PEAUI@@\00" }, comdat
+
+void f();
+void g() {
+  @try {
+    f();
+  } @catch (I *) {
+  } @catch (id) {
+  }
+}
Index: test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm
===================================================================
--- test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm
+++ test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm
@@ -9,7 +9,7 @@
 
 // Verify that we destruct things from left to right in the MS C++ ABI: a, b, c, d.
 //
-// CHECK-LABEL: define dso_local void @"?test_arc_order@@YAXUA@@PAU.objc_object@@01@Z"
+// CHECK-LABEL: define dso_local void @"?test_arc_order@@YAXUA@@PAUobjc_object@@01@Z"
 // CHECK:                       (<{ %struct.A, i8*, %struct.A, i8* }>* inalloca)
 void test_arc_order(A a, id __attribute__((ns_consumed)) b , A c, id __attribute__((ns_consumed)) d) {
   // CHECK: call x86_thiscallcc void @"??1A@@QAE@XZ"(%struct.A* %{{.*}})
Index: test/CodeGenObjCXX/arc-marker-funclet.mm
===================================================================
--- test/CodeGenObjCXX/arc-marker-funclet.mm
+++ test/CodeGenObjCXX/arc-marker-funclet.mm
@@ -10,7 +10,7 @@
   }
 }
 
-// CHECK: call i8* @"?f@@YAPAU.objc_object@@XZ"() [ "funclet"(token %1) ]
+// CHECK: call i8* @"?f@@YAPAUobjc_object@@XZ"() [ "funclet"(token %1) ]
 // CHECK-NEXT: call void asm sideeffect "movl{{.*}}%ebp, %ebp{{.*}}", ""() [ "funclet"(token %1) ]
 
 // The corresponding f() call was invoked from the entry basic block.
Index: lib/AST/MicrosoftMangle.cpp
===================================================================
--- lib/AST/MicrosoftMangle.cpp
+++ lib/AST/MicrosoftMangle.cpp
@@ -482,7 +482,7 @@
     mangleFunctionEncoding(FD, Context.shouldMangleDeclName(FD));
   else if (const VarDecl *VD = dyn_cast<VarDecl>(D))
     mangleVariableEncoding(VD);
-  else if (!isa<ObjCInterfaceDecl>(D))
+  else
     llvm_unreachable("Tried to mangle unexpected NamedDecl!");
 }
 
@@ -1951,13 +1951,13 @@
     llvm_unreachable("placeholder types shouldn't get to name mangling");
 
   case BuiltinType::ObjCId:
-    mangleArtificalTagType(TTK_Struct, ".objc_object");
+    mangleArtificalTagType(TTK_Struct, "objc_object");
     break;
   case BuiltinType::ObjCClass:
-    mangleArtificalTagType(TTK_Struct, ".objc_class");
+    mangleArtificalTagType(TTK_Struct, "objc_class");
     break;
   case BuiltinType::ObjCSel:
-    mangleArtificalTagType(TTK_Struct, ".objc_selector");
+    mangleArtificalTagType(TTK_Struct, "objc_selector");
     break;
 
 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
@@ -2637,10 +2637,9 @@
 
 void MicrosoftCXXNameMangler::mangleType(const ObjCInterfaceType *T, Qualifiers,
                                          SourceRange) {
-  // ObjC interfaces are mangled as if they were structs with a name that is
-  // not a valid C/C++ identifier
+  // ObjC interfaces have structs underlying them.
   mangleTagTypeKind(TTK_Struct);
-  mangle(T->getDecl(), ".objc_cls_");
+  mangleName(T->getDecl());
 }
 
 void MicrosoftCXXNameMangler::mangleType(const ObjCObjectType *T,
@@ -2661,11 +2660,11 @@
 
   Out << "?$";
   if (T->isObjCId())
-    mangleSourceName(".objc_object");
+    mangleSourceName("objc_object");
   else if (T->isObjCClass())
-    mangleSourceName(".objc_class");
+    mangleSourceName("objc_class");
   else
-    mangleSourceName((".objc_cls_" + T->getInterface()->getName()).str());
+    mangleSourceName(T->getInterface()->getName());
 
   for (const auto &Q : T->quals())
     mangleObjCProtocol(Q);
@@ -3002,14 +3001,22 @@
   msvc_hashing_ostream MHO(Out);
   MicrosoftCXXNameMangler Mangler(*this, MHO);
   Mangler.getStream() << "??_R0";
+  // Obj-C classes are mangled as C++ structs with the same name, but we want to
+  // be able to distinguish a C++ struct X from an Obj-C class X for the
+  // purposes of exception handling, so we add a discriminator.
+  if (T->isObjCObjectPointerType())
+    Mangler.getStream() << "objc.";
   Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
   Mangler.getStream() << "@8";
 }
 
 void MicrosoftMangleContextImpl::mangleCXXRTTIName(QualType T,
                                                    raw_ostream &Out) {
   MicrosoftCXXNameMangler Mangler(*this, Out);
   Mangler.getStream() << '.';
+  // See the comment in MicrosoftMangleContextImpl::mangleCXXRTTI.
+  if (T->isObjCObjectPointerType())
+    Mangler.getStream() << "objc.";
   Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
 }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to