theraven updated this revision to Diff 159868.
theraven added a comment.

- Address rjmcall's review comments.
- Revert blocks part of the patch to put in a separate review.


Repository:
  rC Clang

https://reviews.llvm.org/D50144

Files:
  include/clang/Driver/Options.td
  lib/AST/MicrosoftMangle.cpp
  lib/CodeGen/CGException.cpp
  lib/CodeGen/CGObjCGNU.cpp
  lib/CodeGen/CGObjCRuntime.cpp
  lib/CodeGen/CGObjCRuntime.h
  lib/CodeGen/CodeGenFunction.h
  lib/Driver/ToolChains/Clang.cpp
  test/CodeGenObjC/gnu-init.m
  test/CodeGenObjC/gnustep2-proto.m
  test/CodeGenObjCXX/arc-marker-funclet.mm
  test/CodeGenObjCXX/microsoft-abi-arc-param-order.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@@3PAUobjc_object@@A" =  dso_local global
+// CHECK: @"?kid@@3PAU.objc_object@@A" =  dso_local global
 
 Class klass;
-// CHECK: @"?klass@@3PAUobjc_class@@A" = dso_local global
+// CHECK: @"?klass@@3PAU.objc_class@@A" = dso_local global
 
 I *kI;
-// CHECK: @"?kI@@3PAUI@@A" = dso_local global
+// CHECK: @"?kI@@3PAU.objc_cls_I@@A" = dso_local global
 
 void f(I *) {}
-// CHECK-LABEL: "?f@@YAXPAUI@@@Z"
+// CHECK-LABEL: "?f@@YAXPAU.objc_cls_I@@@Z"
 
 void f(const I *) {}
-// CHECK-LABEL: "?f@@YAXPBUI@@@Z"
+// CHECK-LABEL: "?f@@YAXPBU.objc_cls_I@@@Z"
 
 void f(I &) {}
-// CHECK-LABEL: "?f@@YAXAAUI@@@Z"
+// CHECK-LABEL: "?f@@YAXAAU.objc_cls_I@@@Z"
 
 void f(const I &) {}
-// CHECK-LABEL: "?f@@YAXABUI@@@Z"
+// CHECK-LABEL: "?f@@YAXABU.objc_cls_I@@@Z"
 
 void f(const I &&) {}
-// CHECK-LABEL: "?f@@YAX$$QBUI@@@Z"
+// CHECK-LABEL: "?f@@YAX$$QBU.objc_cls_I@@@Z"
 
 void g(id) {}
-// CHECK-LABEL: "?g@@YAXPAUobjc_object@@@Z"
+// CHECK-LABEL: "?g@@YAXPAU.objc_object@@@Z"
 
 void g(id &) {}
-// CHECK-LABEL: "?g@@YAXAAPAUobjc_object@@@Z"
+// CHECK-LABEL: "?g@@YAXAAPAU.objc_object@@@Z"
 
 void g(const id &) {}
-// CHECK-LABEL: "?g@@YAXABQAUobjc_object@@@Z"
+// CHECK-LABEL: "?g@@YAXABQAU.objc_object@@@Z"
 
 void g(id &&) {}
-// CHECK-LABEL: "?g@@YAX$$QAPAUobjc_object@@@Z"
+// CHECK-LABEL: "?g@@YAX$$QAPAU.objc_object@@@Z"
 
 void h(Class) {}
-// CHECK-LABEL: "?h@@YAXPAUobjc_class@@@Z"
+// CHECK-LABEL: "?h@@YAXPAU.objc_class@@@Z"
 
 void h(Class &) {}
-// CHECK-LABEL: "?h@@YAXAAPAUobjc_class@@@Z"
+// CHECK-LABEL: "?h@@YAXAAPAU.objc_class@@@Z"
 
 void h(const Class &) {}
-// CHECK-LABEL: "?h@@YAXABQAUobjc_class@@@Z"
+// CHECK-LABEL: "?h@@YAXABQAU.objc_class@@@Z"
 
 void h(Class &&) {}
-// CHECK-LABEL: "?h@@YAX$$QAPAUobjc_class@@@Z"
+// CHECK-LABEL: "?h@@YAX$$QAPAU.objc_class@@@Z"
 
 I *i() { return nullptr; }
-// CHECK-LABEL: "?i@@YAPAUI@@XZ"
+// CHECK-LABEL: "?i@@YAPAU.objc_cls_I@@XZ"
 
 const I *j() { return nullptr; }
-// CHECK-LABEL: "?j@@YAPBUI@@XZ"
+// CHECK-LABEL: "?j@@YAPBU.objc_cls_I@@XZ"
 
 I &k() { return *kI; }
-// CHECK-LABEL: "?k@@YAAAUI@@XZ"
+// CHECK-LABEL: "?k@@YAAAU.objc_cls_I@@XZ"
 
 const I &l() { return *kI; }
-// CHECK-LABEL: "?l@@YAABUI@@XZ"
+// CHECK-LABEL: "?l@@YAABU.objc_cls_I@@XZ"
 
 void m(const id) {}
-// CHECK-LABEL: "?m@@YAXQAUobjc_object@@@Z"
+// CHECK-LABEL: "?m@@YAXQAU.objc_object@@@Z"
 
 void m(const I *) {}
-// CHECK-LABEL: "?m@@YAXPBUI@@@Z"
+// CHECK-LABEL: "?m@@YAXPBU.objc_cls_I@@@Z"
 
 void n(SEL) {}
-// CHECK-LABEL: "?n@@YAXPAUobjc_selector@@@Z"
+// CHECK-LABEL: "?n@@YAXPAU.objc_selector@@@Z"
 
 void n(SEL *) {}
-// CHECK-LABEL: "?n@@YAXPAPAUobjc_selector@@@Z"
+// CHECK-LABEL: "?n@@YAXPAPAU.objc_selector@@@Z"
 
 void n(const SEL *) {}
-// CHECK-LABEL: "?n@@YAXPBQAUobjc_selector@@@Z"
+// CHECK-LABEL: "?n@@YAXPBQAU.objc_selector@@@Z"
 
 void n(SEL &) {}
-// CHECK-LABEL: "?n@@YAXAAPAUobjc_selector@@@Z"
+// CHECK-LABEL: "?n@@YAXAAPAU.objc_selector@@@Z"
 
 void n(const SEL &) {}
-// CHECK-LABEL: "?n@@YAXABQAUobjc_selector@@@Z"
+// CHECK-LABEL: "?n@@YAXABQAU.objc_selector@@@Z"
 
 void n(SEL &&) {}
-// CHECK-LABEL: "?n@@YAX$$QAPAUobjc_selector@@@Z"
+// CHECK-LABEL: "?n@@YAX$$QAPAU.objc_selector@@@Z"
 
 struct __declspec(dllexport) s {
   struct s &operator=(const struct s &) = delete;
 
   void m(I *) {}
-  // CHECK-LABEL: "?m@s@@QAAXPAUI@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXPAU.objc_cls_I@@@Z"
 
   void m(const I *) {}
-  // CHECK-LABEL: "?m@s@@QAAXPBUI@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXPBU.objc_cls_I@@@Z"
 
   void m(I &) {}
-  // CHECK-LABEL: "?m@s@@QAAXAAUI@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXAAU.objc_cls_I@@@Z"
 
   void m(const I &) {}
-  // CHECK-LABEL: "?m@s@@QAAXABUI@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXABU.objc_cls_I@@@Z"
 
   void m(I &&) {}
-  // CHECK-LABEL: "?m@s@@QAAX$$QAUI@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAX$$QAU.objc_cls_I@@@Z"
 
   void m(const I &&) {}
-  // CHECK-LABEL: "?m@s@@QAAX$$QBUI@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAX$$QBU.objc_cls_I@@@Z"
 
   void m(id) {}
-  // CHECK-LABEL: "?m@s@@QAAXPAUobjc_object@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXPAU.objc_object@@@Z"
 
   void m(id &) {}
-  // CHECK-LABEL: "?m@s@@QAAXAAPAUobjc_object@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXAAPAU.objc_object@@@Z"
 
   void m(id &&) {}
-  // CHECK-LABEL: "?m@s@@QAAX$$QAPAUobjc_object@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAX$$QAPAU.objc_object@@@Z"
 
   void m(const id &) {}
-  // CHECK-LABEL: "?m@s@@QAAXABQAUobjc_object@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXABQAU.objc_object@@@Z"
 
   void m(const id &&) {}
-  // CHECK-LABEL: "?m@s@@QAAX$$QBQAUobjc_object@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAX$$QBQAU.objc_object@@@Z"
 
   void m(Class *) {}
-  // CHECK-LABEL: "?m@s@@QAAXPAPAUobjc_class@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXPAPAU.objc_class@@@Z"
 
   void m(const Class *) {}
-  // CHECK-LABEL: "?m@s@@QAAXPBQAUobjc_class@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXPBQAU.objc_class@@@Z"
 
   void m(Class) {}
-  // CHECK-LABEL: "?m@s@@QAAXPAUobjc_class@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXPAU.objc_class@@@Z"
 
   void m(Class &) {}
-  // CHECK-LABEL: "?m@s@@QAAXAAPAUobjc_class@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXAAPAU.objc_class@@@Z"
 
   void m(const Class &) {}
-  // CHECK-LABEL: "?m@s@@QAAXABQAUobjc_class@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXABQAU.objc_class@@@Z"
 
   void m(Class &&) {}
-  // CHECK-LABEL: "?m@s@@QAAX$$QAPAUobjc_class@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAX$$QAPAU.objc_class@@@Z"
 
   void m(const Class &&) {}
-  // CHECK-LABEL: "?m@s@@QAAX$$QBQAUobjc_class@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAX$$QBQAU.objc_class@@@Z"
 
   void m(SEL) {}
-  // CHECK-LABEL: "?m@s@@QAAXPAUobjc_selector@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXPAU.objc_selector@@@Z"
 
   void m(SEL *) {}
-  // CHECK-LABEL: "?m@s@@QAAXPAPAUobjc_selector@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXPAPAU.objc_selector@@@Z"
 
   void m(const SEL *) {}
-  // CHECK-LABEL: "?m@s@@QAAXPBQAUobjc_selector@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXPBQAU.objc_selector@@@Z"
 
   void m(SEL &) {}
-  // CHECK-LABEL: "?m@s@@QAAXAAPAUobjc_selector@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXAAPAU.objc_selector@@@Z"
 
   void m(const SEL &) {}
-  // CHECK-LABEL: "?m@s@@QAAXABQAUobjc_selector@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAXABQAU.objc_selector@@@Z"
 
   void m(SEL &&) {}
-  // CHECK-LABEL: "?m@s@@QAAX$$QAPAUobjc_selector@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAX$$QAPAU.objc_selector@@@Z"
 
   void m(const SEL &&) {}
-  // CHECK-LABEL: "?m@s@@QAAX$$QBQAUobjc_selector@@@Z"
+  // CHECK-LABEL: "?m@s@@QAAX$$QBQAU.objc_selector@@@Z"
 };
 
 template <typename T>
@@ -179,14 +179,14 @@
 };
 
 template struct t<id>;
-// CHECK-LABEL: "??0?$t@PAUobjc_object@@@@QAA@XZ"
+// CHECK-LABEL: "??0?$t@PAU.objc_object@@@@QAA@XZ"
 
 template struct t<remove_pointer<id>::type>;
-// CHECK-LABEL: "??0?$t@Uobjc_object@@@@QAA@XZ"
+// CHECK-LABEL: "??0?$t@U.objc_object@@@@QAA@XZ"
 
 template struct t<SEL>;
-// CHECK-LABEL: "??0?$t@PAUobjc_selector@@@@QAA@XZ"
+// CHECK-LABEL: "??0?$t@PAU.objc_selector@@@@QAA@XZ"
 
 template struct t<remove_pointer<SEL>::type>;
-// CHECK-LABEL: "??0?$t@Uobjc_selector@@@@QAA@XZ"
+// CHECK-LABEL: "??0?$t@U.objc_selector@@@@QAA@XZ"
 
Index: test/CodeGenObjCXX/msabi-objc-extensions.mm
===================================================================
--- test/CodeGenObjCXX/msabi-objc-extensions.mm
+++ test/CodeGenObjCXX/msabi-objc-extensions.mm
@@ -6,61 +6,61 @@
 @class I;
 
 void f(id<P>, id, id<P>, id) {}
-// CHECK-LABEL: "?f@@YAXPAU?$objc_object@U?$Protocol@UP@@@__ObjC@@@@PAUobjc_object@@01@Z"
+// CHECK-LABEL: "?f@@YAXPAU?$.objc_object@U?$Protocol@UP@@@__ObjC@@@@PAU.objc_object@@01@Z"
 
 void f(id, id<P>, id<P>, id) {}
-// CHECK-LABEL: "?f@@YAXPAUobjc_object@@PAU?$objc_object@U?$Protocol@UP@@@__ObjC@@@@10@Z"
+// CHECK-LABEL: "?f@@YAXPAU.objc_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?$I@U?$Protocol@UP@@@__ObjC@@@@@Z"
+// CHECK-LABEL: "?f@@YAXPAU?$.objc_cls_I@U?$Protocol@UP@@@__ObjC@@@@@Z"
 
 void f(I<P, Q> *) {}
-// CHECK-LABEL: "?f@@YAXPAU?$I@U?$Protocol@UP@@@__ObjC@@U?$Protocol@UQ@@@2@@@@Z"
+// CHECK-LABEL: "?f@@YAXPAU?$.objc_cls_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@PAUobjc_object@@@@@Z"
+// CHECK-LABEL: "?f@@YAXU?$S@PAU.objc_object@@@@@Z"
 
 void f(S<__autoreleasing id>) {}
-// CHECK-LABEL: "?f@@YAXU?$S@U?$Autoreleasing@PAUobjc_object@@@__ObjC@@@@@Z"
+// CHECK-LABEL: "?f@@YAXU?$S@U?$Autoreleasing@PAU.objc_object@@@__ObjC@@@@@Z"
 
 void f(S<__strong id>) {}
-// CHECK-LABEL: "?f@@YAXU?$S@U?$Strong@PAUobjc_object@@@__ObjC@@@@@Z"
+// CHECK-LABEL: "?f@@YAXU?$S@U?$Strong@PAU.objc_object@@@__ObjC@@@@@Z"
 
 void f(S<__weak id>) {}
-// CHECK-LABEL: "?f@@YAXU?$S@U?$Weak@PAUobjc_object@@@__ObjC@@@@@Z"
+// CHECK-LABEL: "?f@@YAXU?$S@U?$Weak@PAU.objc_object@@@__ObjC@@@@@Z"
 
 void w(__weak id) {}
-// CHECK-LABEL: "?w@@YAXPAUobjc_object@@@Z"
+// CHECK-LABEL: "?w@@YAXPAU.objc_object@@@Z"
 
 void s(__strong id) {}
-// CHECK-LABEL: "?s@@YAXPAUobjc_object@@@Z"
+// CHECK-LABEL: "?s@@YAXPAU.objc_object@@@Z"
 
 void a(__autoreleasing id) {}
-// CHECK-LABEL: "?a@@YAXPAUobjc_object@@@Z"
+// CHECK-LABEL: "?a@@YAXPAU.objc_object@@@Z"
 
 void u(__unsafe_unretained id) {}
-// CHECK-LABEL: "?u@@YAXPAUobjc_object@@@Z"
+// CHECK-LABEL: "?u@@YAXPAU.objc_object@@@Z"
 
 S<__autoreleasing id> g() { return S<__autoreleasing id>(); }
-// CHECK-LABEL: "?g@@YA?AU?$S@U?$Autoreleasing@PAUobjc_object@@@__ObjC@@@@XZ"
+// CHECK-LABEL: "?g@@YA?AU?$S@U?$Autoreleasing@PAU.objc_object@@@__ObjC@@@@XZ"
 
 __autoreleasing id h() { return nullptr; }
-// CHECK-LABEL: "?h@@YAPAUobjc_object@@XZ"
+// CHECK-LABEL: "?h@@YAPAU.objc_object@@XZ"
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@@PAUobjc_object@@01@Z"
+// CHECK-LABEL: define dso_local void @"?test_arc_order@@YAXUA@@PAU.objc_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@@YAPAUobjc_object@@XZ"() [ "funclet"(token %1) ]
+// CHECK: call i8* @"?f@@YAPAU.objc_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: test/CodeGenObjC/gnustep2-proto.m
===================================================================
--- test/CodeGenObjC/gnustep2-proto.m
+++ test/CodeGenObjC/gnustep2-proto.m
@@ -22,11 +22,11 @@
 
 // Check that we're emitting the protocol and a correctly initialised
 // indirection variable.
-// CHECK: @._OBJC_PROTOCOL_X = global 
+// CHECK: @._OBJC_PROTOCOL_X = global
 // CHECK-SAME: , section "__objc_protocols", comdat, align 8
-// CHECK: @._OBJC_REF_PROTOCOL_X = global 
+// CHECK: @._OBJC_REF_PROTOCOL_X = linkonce_odr global
 // CHECK-SAME: @._OBJC_PROTOCOL_X
-// CHECK-SAME: , section "__objc_protocol_refs", align 8
+// CHECK-SAME: , section "__objc_protocol_refs", comdat, align 8
 
 
 // Check that we load from the indirection variable on protocol references.
Index: test/CodeGenObjC/gnu-init.m
===================================================================
--- test/CodeGenObjC/gnu-init.m
+++ test/CodeGenObjC/gnu-init.m
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-unknown-freebsd -S -emit-llvm -fobjc-runtime=gnustep-2.0 -o - %s | FileCheck %s -check-prefix=CHECK-NEW
+// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -S -emit-llvm -fobjc-runtime=gnustep-2.0 -o - %s | FileCheck %s -check-prefix=CHECK-WIN
 // RUN: %clang_cc1 -triple x86_64-unknown-freebsd -S -emit-llvm -fobjc-runtime=gnustep-1.8 -o - %s | FileCheck %s -check-prefix=CHECK-OLD
 
 // Almost minimal Objective-C file, check that it emits calls to the correct
@@ -49,9 +50,9 @@
 // CHECK-NEW: @.objc_null_class_alias = linkonce_odr hidden global { i8*, i8* } zeroinitializer, section "__objc_class_aliases", comdat, align 8
 // CHECK-NEW: @.objc_null_constant_string = linkonce_odr hidden global { i8*, i32, i32, i32, i32, i8* } zeroinitializer, section "__objc_constant_string", comdat, align 8
 // Make sure that the null symbols are not going to be removed, even by linking.
-// CHECK-NEW: @llvm.used = appending global [7 x i8*] [i8* bitcast ({ { i8*, i8*, i8*, i64, i64, i64, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i64, i8* }*, i8*, i8*, i64, i64, i64, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i64, i8* }** @._OBJC_INIT_CLASS_X to i8*), i8* bitcast ({ i8*, i8* }* @.objc_null_selector to i8*), i8* bitcast ({ i8*, i8*, i8*, i8*, i8*, i8*, i8* }* @.objc_null_category to i8*), i8* bitcast ({ i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8* }* @.objc_null_protocol to i8*), i8* bitcast ({ i8* }* @.objc_null_protocol_ref to i8*), i8* bitcast ({ i8*, i8* }* @.objc_null_class_alias to i8*), i8* bitcast ({ i8*, i32, i32, i32, i32, i8* }* @.objc_null_constant_string to i8*)], section "llvm.metadata"
+// CHECK-NEW: @llvm.used = appending global [8 x i8*] [i8* bitcast ({ { i8*, i8*, i8*, i64, i64, i64, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i64, i8* }*, i8*, i8*, i64, i64, i64, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i64, i8* }** @._OBJC_INIT_CLASS_X to i8*), i8* bitcast (void ()** @.objc_ctor to i8*), i8* bitcast ({ i8*, i8* }* @.objc_null_selector to i8*), i8* bitcast ({ i8*, i8*, i8*, i8*, i8*, i8*, i8* }* @.objc_null_category to i8*), i8* bitcast ({ i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8* }* @.objc_null_protocol to i8*), i8* bitcast ({ i8* }* @.objc_null_protocol_ref to i8*), i8* bitcast ({ i8*, i8* }* @.objc_null_class_alias to i8*), i8* bitcast ({ i8*, i32, i32, i32, i32, i8* }* @.objc_null_constant_string to i8*)], section "llvm.metadata"
 // Make sure that the load function and the reference to it are marked as used.
-// CHECK-NEW: @llvm.compiler.used = appending global [2 x i8*] [i8* bitcast (void ()* @.objcv2_load_function to i8*), i8* bitcast (void ()** @.objc_ctor to i8*)], section "llvm.metadata"
+// CHECK-NEW: @llvm.compiler.used = appending global [1 x i8*] [i8* bitcast (void ()* @.objcv2_load_function to i8*)], section "llvm.metadata"
 
 // Check that we emit the load function in a comdat and that it does the right thing.
 // CHECK-NEW: define linkonce_odr hidden void @.objcv2_load_function() comdat {
@@ -67,3 +68,37 @@
 // CHECK-OLD-NEXT: entry:
 // CHECK-OLD-NEXT: call void ({ i64, i64, i8*, { i64, { i8*, i8* }*, i16, i16, [4 x i8*] }* }*, ...) @__objc_exec_class({ i64, i64, i8*, { i64, { i8*, i8* }*, i16, i16, [4 x i8*] }* }* @4)
 
+
+
+// Make sure all of our section boundary variables are emitted correctly.
+// CHECK-WIN: @__start___objc_selectors = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_selectors$a", comdat, align 1
+// CHECK-WIN: @__stop__objc_selectors = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_selectors$z", comdat, align 1
+// CHECK-WIN: @__start___objc_classes = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_classes$a", comdat, align 1
+// CHECK-WIN: @__stop__objc_classes = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_classes$z", comdat, align 1
+// CHECK-WIN: @__start___objc_class_refs = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_class_refs$a", comdat, align 1
+// CHECK-WIN: @__stop__objc_class_refs = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_class_refs$z", comdat, align 1
+// CHECK-WIN: @__start___objc_cats = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_cats$a", comdat, align 1
+// CHECK-WIN: @__stop__objc_cats = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_cats$z", comdat, align 1
+// CHECK-WIN: @__start___objc_protocols = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_protocols$a", comdat, align 1
+// CHECK-WIN: @__stop__objc_protocols = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_protocols$z", comdat, align 1
+// CHECK-WIN: @__start___objc_protocol_refs = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_protocol_refs$a", comdat, align 1
+// CHECK-WIN: @__stop__objc_protocol_refs = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_protocol_refs$z", comdat, align 1
+// CHECK-WIN: @__start___objc_class_aliases = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_class_aliases$a", comdat, align 1
+// CHECK-WIN: @__stop__objc_class_aliases = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_class_aliases$z", comdat, align 1
+// CHECK-WIN: @__start___objc_constant_string = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_constant_string$a", comdat, align 1
+// CHECK-WIN: @__stop__objc_constant_string = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_constant_string$z", comdat, align 1
+// CHECK-WIN: @.objc_init = linkonce_odr hidden global { i64, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel* } { i64 0, %.objc_section_sentinel* @__start___objc_selectors, %.objc_section_sentinel* @__stop__objc_selectors, %.objc_section_sentinel* @__start___objc_classes, %.objc_section_sentinel* @__stop__objc_classes, %.objc_section_sentinel* @__start___objc_class_refs, %.objc_section_sentinel* @__stop__objc_class_refs, %.objc_section_sentinel* @__start___objc_cats, %.objc_section_sentinel* @__stop__objc_cats, %.objc_section_sentinel* @__start___objc_protocols, %.objc_section_sentinel* @__stop__objc_protocols, %.objc_section_sentinel* @__start___objc_protocol_refs, %.objc_section_sentinel* @__stop__objc_protocol_refs, %.objc_section_sentinel* @__start___objc_class_aliases, %.objc_section_sentinel* @__stop__objc_class_aliases, %.objc_section_sentinel* @__start___objc_constant_string, %.objc_section_sentinel* @__stop__objc_constant_string }, comdat, align 8
+
+// Make sure our init variable is in the correct section for late library init.
+// CHECK-WIN: @.objc_ctor = linkonce hidden constant void ()* @.objcv2_load_function, section ".CRT$XCLz", comdat
+
+// We shouldn't have emitted any null placeholders on Windows.
+// CHECK-WIN: @llvm.used = appending global [2 x i8*] [i8* bitcast ({ { i8*, i8*, i8*, i32, i32, i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i32, i8* }*, i8*, i8*, i32, i32, i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i32, i8* }** @._OBJC_INIT_CLASS_X to i8*), i8* bitcast (void ()** @.objc_ctor to i8*)], section "llvm.metadata"
+// CHECK-WIN: @llvm.compiler.used = appending global [1 x i8*] [i8* bitcast (void ()* @.objcv2_load_function to i8*)], section "llvm.metadata"
+
+// Check our load function is in a comdat.
+// CHECK-WIN: define linkonce_odr hidden void @.objcv2_load_function() comdat {
+
+// Make sure we have dllimport on the load function
+// CHECK-WIN: declare dllimport void @__objc_load
+
Index: lib/Driver/ToolChains/Clang.cpp
===================================================================
--- lib/Driver/ToolChains/Clang.cpp
+++ lib/Driver/ToolChains/Clang.cpp
@@ -4915,7 +4915,8 @@
     }
     if ((runtime.getKind() == ObjCRuntime::GNUstep) &&
         (runtime.getVersion() >= VersionTuple(2, 0)))
-      if (!getToolChain().getTriple().isOSBinFormatELF()) {
+      if (!getToolChain().getTriple().isOSBinFormatELF() &&
+          !getToolChain().getTriple().isOSBinFormatCOFF()) {
         getToolChain().getDriver().Diag(
             diag::err_drv_gnustep_objc_runtime_incompatible_binary)
           << runtime.getVersion().getMajor();
Index: lib/CodeGen/CodeGenFunction.h
===================================================================
--- lib/CodeGen/CodeGenFunction.h
+++ lib/CodeGen/CodeGenFunction.h
@@ -470,7 +470,7 @@
   /// potentially set the return value.
   bool SawAsmBlock = false;
 
-  const FunctionDecl *CurSEHParent = nullptr;
+  const NamedDecl *CurSEHParent = nullptr;
 
   /// True if the current function is an outlined SEH helper. This can be a
   /// finally block or filter expression.
@@ -2878,6 +2878,8 @@
   void EnterSEHTryStmt(const SEHTryStmt &S);
   void ExitSEHTryStmt(const SEHTryStmt &S);
 
+  void pushSEHCleanup(CleanupKind kind,
+                      llvm::Function *FinallyFunc);
   void startOutlinedSEHHelper(CodeGenFunction &ParentCGF, bool IsFilter,
                               const Stmt *OutlinedStmt);
 
Index: lib/CodeGen/CGObjCRuntime.h
===================================================================
--- lib/CodeGen/CGObjCRuntime.h
+++ lib/CodeGen/CGObjCRuntime.h
@@ -17,6 +17,7 @@
 #define LLVM_CLANG_LIB_CODEGEN_CGOBJCRUNTIME_H
 #include "CGBuilder.h"
 #include "CGCall.h"
+#include "CGCleanup.h"
 #include "CGValue.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/Basic/IdentifierTable.h" // Selector
@@ -141,6 +142,8 @@
   /// error to Sema.
   virtual llvm::Constant *GetEHType(QualType T) = 0;
 
+  virtual CatchTypeInfo getCatchAllTypeInfo() { return { nullptr, 0 }; }
+
   /// Generate a constant string object.
   virtual ConstantAddress GenerateConstantString(const StringLiteral *) = 0;
 
Index: lib/CodeGen/CGObjCRuntime.cpp
===================================================================
--- lib/CodeGen/CGObjCRuntime.cpp
+++ lib/CodeGen/CGObjCRuntime.cpp
@@ -15,13 +15,15 @@
 
 #include "CGObjCRuntime.h"
 #include "CGCleanup.h"
+#include "CGCXXABI.h"
 #include "CGRecordLayout.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/AST/StmtObjC.h"
 #include "clang/CodeGen/CGFunctionInfo.h"
 #include "llvm/IR/CallSite.h"
+#include "llvm/Support/SaveAndRestore.h"
 
 using namespace clang;
 using namespace CodeGen;
@@ -120,6 +122,8 @@
     const Stmt *Body;
     llvm::BasicBlock *Block;
     llvm::Constant *TypeInfo;
+    /// Flags used to differentiate cleanups and catchalls in Windows SEH
+    unsigned Flags;
   };
 
   struct CallObjCEndCatch final : EHScopeStack::Cleanup {
@@ -148,13 +152,17 @@
   if (S.getNumCatchStmts())
     Cont = CGF.getJumpDestInCurrentScope("eh.cont");
 
+  bool useFunclets = EHPersonality::get(CGF).usesFuncletPads();
+
   CodeGenFunction::FinallyInfo FinallyInfo;
-  if (const ObjCAtFinallyStmt *Finally = S.getFinallyStmt())
-    FinallyInfo.enter(CGF, Finally->getFinallyBody(),
-                      beginCatchFn, endCatchFn, exceptionRethrowFn);
+  if (!useFunclets)
+    if (const ObjCAtFinallyStmt *Finally = S.getFinallyStmt())
+      FinallyInfo.enter(CGF, Finally->getFinallyBody(),
+                        beginCatchFn, endCatchFn, exceptionRethrowFn);
 
   SmallVector<CatchHandler, 8> Handlers;
 
+
   // Enter the catch, if there is one.
   if (S.getNumCatchStmts()) {
     for (unsigned I = 0, N = S.getNumCatchStmts(); I != N; ++I) {
@@ -166,10 +174,13 @@
       Handler.Variable = CatchDecl;
       Handler.Body = CatchStmt->getCatchBody();
       Handler.Block = CGF.createBasicBlock("catch");
+      Handler.Flags = 0;
 
       // @catch(...) always matches.
       if (!CatchDecl) {
-        Handler.TypeInfo = nullptr; // catch-all
+        auto catchAll = getCatchAllTypeInfo();
+        Handler.TypeInfo = catchAll.RTTI;
+        Handler.Flags = catchAll.Flags;
         // Don't consider any other catches.
         break;
       }
@@ -179,9 +190,31 @@
 
     EHCatchScope *Catch = CGF.EHStack.pushCatch(Handlers.size());
     for (unsigned I = 0, E = Handlers.size(); I != E; ++I)
-      Catch->setHandler(I, Handlers[I].TypeInfo, Handlers[I].Block);
+      Catch->setHandler(I, { Handlers[I].TypeInfo, Handlers[I].Flags }, Handlers[I].Block);
   }
 
+  if (useFunclets)
+    if (const ObjCAtFinallyStmt *Finally = S.getFinallyStmt()) {
+        CodeGenFunction HelperCGF(CGM, /*suppressNewContext=*/true);
+        if (!CGF.CurSEHParent)
+            CGF.CurSEHParent = cast<NamedDecl>(CGF.CurFuncDecl);
+        // Outline the finally block.
+        const Stmt *FinallyBlock = Finally->getFinallyBody();
+        HelperCGF.startOutlinedSEHHelper(CGF, /*isFilter*/false, FinallyBlock);
+
+        // Emit the original filter expression, convert to i32, and return.
+        HelperCGF.EmitStmt(FinallyBlock);
+
+        HelperCGF.FinishFunction(FinallyBlock->getLocEnd());
+
+        llvm::Function *FinallyFunc = HelperCGF.CurFn;
+
+
+        // Push a cleanup for __finally blocks.
+        CGF.pushSEHCleanup(NormalAndEHCleanup, FinallyFunc);
+    }
+
+  
   // Emit the try body.
   CGF.EmitStmt(S.getTryBody());
 
@@ -197,6 +230,13 @@
     CatchHandler &Handler = Handlers[I];
 
     CGF.EmitBlock(Handler.Block);
+    llvm::CatchPadInst *CPI = nullptr;
+    SaveAndRestore<llvm::Instruction *> RestoreCurrentFuncletPad(CGF.CurrentFuncletPad);
+    if (useFunclets)
+      if ((CPI = dyn_cast_or_null<llvm::CatchPadInst>(Handler.Block->getFirstNonPHI()))) {
+        CGF.CurrentFuncletPad = CPI;
+        CPI->setOperand(2, CGF.getExceptionSlot().getPointer());
+      }
     llvm::Value *RawExn = CGF.getExceptionFromSlot();
 
     // Enter the catch.
@@ -223,6 +263,8 @@
       CGF.EmitAutoVarDecl(*CatchParam);
       EmitInitOfCatchParam(CGF, CastExn, CatchParam);
     }
+    if (CPI)
+        CGF.EHStack.pushCleanup<CatchRetScope>(NormalCleanup, CPI);
 
     CGF.ObjCEHValueStack.push_back(Exn);
     CGF.EmitStmt(Handler.Body);
@@ -232,13 +274,13 @@
     cleanups.ForceCleanup();
 
     CGF.EmitBranchThroughCleanup(Cont);
-  }
+  }  
 
   // Go back to the try-statement fallthrough.
   CGF.Builder.restoreIP(SavedIP);
 
   // Pop out of the finally.
-  if (S.getFinallyStmt())
+  if (!useFunclets && S.getFinallyStmt())
     FinallyInfo.exit(CGF);
 
   if (Cont.isValid())
@@ -277,7 +319,7 @@
       : SyncExitFn(SyncExitFn), SyncArg(SyncArg) {}
 
     void Emit(CodeGenFunction &CGF, Flags flags) override {
-      CGF.Builder.CreateCall(SyncExitFn, SyncArg)->setDoesNotThrow();
+      CGF.EmitNounwindRuntimeCall(SyncExitFn, SyncArg);
     }
   };
 }
Index: lib/CodeGen/CGObjCGNU.cpp
===================================================================
--- lib/CodeGen/CGObjCGNU.cpp
+++ lib/CodeGen/CGObjCGNU.cpp
@@ -18,6 +18,7 @@
 #include "CGCleanup.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
+#include "CGCXXABI.h"
 #include "clang/CodeGen/ConstantInitBuilder.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
@@ -217,6 +218,7 @@
       llvm::Constant *value = llvm::ConstantDataArray::getString(VMContext,Str);
       auto *GV = new llvm::GlobalVariable(TheModule, value->getType(), true,
               llvm::GlobalValue::LinkOnceODRLinkage, value, name);
+      GV->setComdat(TheModule.getOrInsertComdat(name));
       if (Private)
         GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
       ConstStr = GV;
@@ -810,8 +812,12 @@
       // Slot_t objc_slot_lookup_super(struct objc_super*, SEL);
       SlotLookupSuperFn.init(&CGM, "objc_slot_lookup_super", SlotTy,
                              PtrToObjCSuperTy, SelectorTy);
-      // If we're in ObjC++ mode, then we want to make
-      if (CGM.getLangOpts().CPlusPlus) {
+      // If we're in ObjC++ mode, then we want to make 
+      if (CGM.getContext().getTargetInfo().getTriple().isOSMSVCRT()) {
+          llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
+          // void objc_exception_rethrow(void)
+          ExceptionReThrowFn.init(&CGM, "objc_exception_rethrow", VoidTy);
+      } else if (CGM.getLangOpts().CPlusPlus) {
         llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
         // void *__cxa_begin_catch(void *e)
         EnterCatchFn.init(&CGM, "__cxa_begin_catch", PtrTy, PtrTy);
@@ -888,22 +894,25 @@
 /// This is the ABI that provides a clean break with the legacy GCC ABI and
 /// cleans up a number of things that were added to work around 1980s linkers.
 class CGObjCGNUstep2 : public CGObjCGNUstep {
-  /// The section for selectors.
-  static constexpr const char *const SelSection = "__objc_selectors";
-  /// The section for classes.
-  static constexpr const char *const ClsSection = "__objc_classes";
-  /// The section for references to classes.
-  static constexpr const char *const ClsRefSection = "__objc_class_refs";
-  /// The section for categories.
-  static constexpr const char *const CatSection = "__objc_cats";
-  /// The section for protocols.
-  static constexpr const char *const ProtocolSection = "__objc_protocols";
-  /// The section for protocol references.
-  static constexpr const char *const ProtocolRefSection = "__objc_protocol_refs";
-  /// The section for class aliases
-  static constexpr const char *const ClassAliasSection = "__objc_class_aliases";
-  /// The section for constexpr constant strings
-  static constexpr const char *const ConstantStringSection = "__objc_constant_string";
+  enum SectionKind
+  {
+    SelectorSection = 0,
+    ClassSection,
+    ClassReferenceSection,
+    CategorySection,
+    ProtocolSection,
+    ProtocolReferenceSection,
+    ClassAliasSection,
+    ConstantStringSection
+  };
+  static const char *const SectionsBaseNames[8];
+  template<SectionKind K>
+  std::string sectionName() {
+    std::string name(SectionsBaseNames[K]);
+    if (CGM.getTriple().isOSBinFormatCOFF())
+      name += "$m";
+    return name;
+  }
   /// The GCC ABI superclass message lookup function.  Takes a pointer to a
   /// structure describing the receiver and the class, and a selector as
   /// arguments.  Returns the IMP for the corresponding method.
@@ -1069,7 +1078,7 @@
           isNamed ? StringRef(StringName) : ".objc_string",
           Align, false, isNamed ? llvm::GlobalValue::LinkOnceODRLinkage
                                 : llvm::GlobalValue::PrivateLinkage);
-    ObjCStrGV->setSection(ConstantStringSection);
+    ObjCStrGV->setSection(sectionName<ConstantStringSection>());
     if (isNamed) {
       ObjCStrGV->setComdat(TheModule.getOrInsertComdat(StringName));
       ObjCStrGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
@@ -1247,9 +1256,10 @@
       assert(!TheModule.getGlobalVariable(RefName));
       // Emit a reference symbol.
       auto GV = new llvm::GlobalVariable(TheModule, ProtocolPtrTy,
-          false, llvm::GlobalValue::ExternalLinkage,
+          false, llvm::GlobalValue::LinkOnceODRLinkage,
           llvm::ConstantExpr::getBitCast(Protocol, ProtocolPtrTy), RefName);
-      GV->setSection(ProtocolRefSection);
+      GV->setComdat(TheModule.getOrInsertComdat(RefName));
+      GV->setSection(sectionName<ProtocolReferenceSection>());
       GV->setAlignment(CGM.getPointerAlign().getQuantity());
       Ref = GV;
     }
@@ -1282,9 +1292,22 @@
 
     EmittedProtocol = true;
 
+    auto SymName = SymbolForProtocol(ProtocolName);
+    auto *OldGV = TheModule.getGlobalVariable(SymName);
+
     // Use the protocol definition, if there is one.
     if (const ObjCProtocolDecl *Def = PD->getDefinition())
       PD = Def;
+    else {
+      // If there is no definition, then create an external linkage symbol and
+      // hope that someone else fills it in for us (and fail to link if they
+      // don't).
+      assert(!OldGV);
+      Protocol = new llvm::GlobalVariable(TheModule, ProtocolTy,
+        /*isConstant*/false,
+        llvm::GlobalValue::ExternalLinkage, nullptr, SymName);
+      return Protocol;
+    }
 
     SmallVector<llvm::Constant*, 16> Protocols;
     for (const auto *PI : PD->protocols())
@@ -1301,8 +1324,6 @@
     EmitProtocolMethodList(PD->class_methods(), ClassMethodList,
         OptionalClassMethodList);
 
-    auto SymName = SymbolForProtocol(ProtocolName);
-    auto *OldGV = TheModule.getGlobalVariable(SymName);
     // The isa pointer must be set to a magic number so the runtime knows it's
     // the correct layout.
     ConstantInitBuilder builder(CGM);
@@ -1326,7 +1347,7 @@
 
     auto *GV = ProtocolBuilder.finishAndCreateGlobal(SymName,
         CGM.getPointerAlign(), false, llvm::GlobalValue::ExternalLinkage);
-    GV->setSection(ProtocolSection);
+    GV->setSection(sectionName<ProtocolSection>());
     GV->setComdat(TheModule.getOrInsertComdat(SymName));
     if (OldGV) {
       OldGV->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(GV,
@@ -1359,6 +1380,7 @@
           TypeEncoding);
       auto *GV = new llvm::GlobalVariable(TheModule, Init->getType(),
           true, llvm::GlobalValue::LinkOnceODRLinkage, Init, TypesVarName);
+      GV->setComdat(TheModule.getOrInsertComdat(TypesVarName));
       GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
       TypesGlobal = GV;
     }
@@ -1387,12 +1409,41 @@
         CGM.getPointerAlign(), false, llvm::GlobalValue::LinkOnceODRLinkage);
     GV->setComdat(TheModule.getOrInsertComdat(SelVarName));
     GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
-    GV->setSection(SelSection);
+    GV->setSection(sectionName<SelectorSection>());
     auto *SelVal = EnforceType(GV, SelectorTy);
     return SelVal;
   }
+  llvm::StructType *emptyStruct = nullptr;
+
+  /// Return pointers to the start and end of a section.  On ELF platforms, we
+  /// use the __start_ and __stop_ symbols that GNU-compatible linkers will set
+  /// to the start and end of section names, as long as those section names are
+  /// valid identifiers and the symbols are referenced but not defined.  On
+  /// Windows, we use the fact that MSVC-compatible linkers will lexically sort
+  /// by subsections and place everything that we want to reference in a middle
+  /// subsection and then insert zero-sized symbols in subsections a and z.
   std::pair<llvm::Constant*,llvm::Constant*>
   GetSectionBounds(StringRef Section) {
+    if (CGM.getTriple().isOSBinFormatCOFF()) {
+      if (emptyStruct == nullptr) {
+        emptyStruct = llvm::StructType::create(VMContext, ".objc_section_sentinel");
+        emptyStruct->setBody({}, /*isPacked*/true);
+      }
+      auto ZeroInit = llvm::Constant::getNullValue(emptyStruct);
+      auto Sym = [&](StringRef Prefix, StringRef SecSuffix) {
+        auto *Sym = new llvm::GlobalVariable(TheModule, emptyStruct,
+            /*isConstant*/false,
+            llvm::GlobalValue::LinkOnceODRLinkage, ZeroInit, Prefix +
+            Section);
+        Sym->setVisibility(llvm::GlobalValue::HiddenVisibility);
+        Sym->setSection((Section + SecSuffix).str());
+        Sym->setComdat(TheModule.getOrInsertComdat((Prefix +
+            Section).str()));
+        Sym->setAlignment(1);
+        return Sym;
+      };
+      return { Sym("__start_", "$a"), Sym("__stop", "$z") };
+    }
     auto *Start = new llvm::GlobalVariable(TheModule, PtrTy,
         /*isConstant*/false,
         llvm::GlobalValue::ExternalLinkage, nullptr, StringRef("__start_") +
@@ -1405,6 +1456,9 @@
     Stop->setVisibility(llvm::GlobalValue::HiddenVisibility);
     return { Start, Stop };
   }
+  CatchTypeInfo getCatchAllTypeInfo() override {
+    return CGM.getCXXABI().getCatchAllTypeInfo();
+  }
   llvm::Function *ModuleInitFunction() override {
     llvm::Function *LoadFunction = llvm::Function::Create(
       llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), false),
@@ -1420,19 +1474,11 @@
     ConstantInitBuilder builder(CGM);
     auto InitStructBuilder = builder.beginStruct();
     InitStructBuilder.addInt(Int64Ty, 0);
-    auto addSection = [&](const char *section) {
-      auto bounds = GetSectionBounds(section);
+    for (auto *s : SectionsBaseNames) {
+      auto bounds = GetSectionBounds(s);
       InitStructBuilder.add(bounds.first);
       InitStructBuilder.add(bounds.second);
     };
-    addSection(SelSection);
-    addSection(ClsSection);
-    addSection(ClsRefSection);
-    addSection(CatSection);
-    addSection(ProtocolSection);
-    addSection(ProtocolRefSection);
-    addSection(ClassAliasSection);
-    addSection(ConstantStringSection);
     auto *InitStruct = InitStructBuilder.finishAndCreateGlobal(".objc_init",
         CGM.getPointerAlign(), false, llvm::GlobalValue::LinkOnceODRLinkage);
     InitStruct->setVisibility(llvm::GlobalValue::HiddenVisibility);
@@ -1451,18 +1497,23 @@
     // Check that this hasn't been renamed.  This shouldn't happen, because
     // this function should be called precisely once.
     assert(InitVar->getName() == ".objc_ctor");
-    InitVar->setSection(".ctors");
+    // In Windows, initialisers are sorted by the suffix.  XCL is for library
+    // initialisers, which run before user initialisers.  We are running
+    // Objective-C loads at the end of library load.  This means +load methods
+    // will run before any other static constructors, but that static
+    // constructors can see a fully initialised Objective-C state.
+    if (CGM.getTriple().isOSBinFormatCOFF())
+        InitVar->setSection(".CRT$XCLz");
+    else
+      InitVar->setSection(".ctors");
     InitVar->setVisibility(llvm::GlobalValue::HiddenVisibility);
     InitVar->setComdat(TheModule.getOrInsertComdat(".objc_ctor"));
-    CGM.addCompilerUsedGlobal(InitVar);
+    CGM.addUsedGlobal(InitVar);
     for (auto *C : Categories) {
       auto *Cat = cast<llvm::GlobalVariable>(C->stripPointerCasts());
-      Cat->setSection(CatSection);
+      Cat->setSection(sectionName<CategorySection>());
       CGM.addUsedGlobal(Cat);
     }
-    // Add a null value fore each special section so that we can always
-    // guarantee that the _start and _stop symbols will exist and be
-    // meaningful.
     auto createNullGlobal = [&](StringRef Name, ArrayRef<llvm::Constant*> Init,
         StringRef Section) {
       auto nullBuilder = builder.beginStruct();
@@ -1476,38 +1527,48 @@
       CGM.addUsedGlobal(GV);
       return GV;
     };
-    createNullGlobal(".objc_null_selector", {NULLPtr, NULLPtr}, SelSection);
-    if (Categories.empty())
-      createNullGlobal(".objc_null_category", {NULLPtr, NULLPtr,
-                    NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr}, CatSection);
-    if (!EmittedClass) {
-      createNullGlobal(".objc_null_cls_init_ref", NULLPtr, ClsSection);
-      createNullGlobal(".objc_null_class_ref", { NULLPtr, NULLPtr },
-          ClsRefSection);
-    }
-    if (!EmittedProtocol)
-      createNullGlobal(".objc_null_protocol", {NULLPtr, NULLPtr, NULLPtr,
-          NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr,
-          NULLPtr}, ProtocolSection);
-    if (!EmittedProtocolRef)
-      createNullGlobal(".objc_null_protocol_ref", {NULLPtr}, ProtocolRefSection);
-    if (!ClassAliases.empty())
-      for (auto clsAlias : ClassAliases)
-        createNullGlobal(std::string(".objc_class_alias") +
-            clsAlias.second, { MakeConstantString(clsAlias.second),
-            GetClassVar(clsAlias.first) }, ClassAliasSection);
-    else
-      createNullGlobal(".objc_null_class_alias", { NULLPtr, NULLPtr },
-          ClassAliasSection);
-    if (ConstantStrings.empty()) {
-      auto i32Zero = llvm::ConstantInt::get(Int32Ty, 0);
-      createNullGlobal(".objc_null_constant_string", { NULLPtr, i32Zero,
-          i32Zero, i32Zero, i32Zero, NULLPtr }, ConstantStringSection);
+    for (auto clsAlias : ClassAliases)
+      createNullGlobal(std::string(".objc_class_alias") +
+          clsAlias.second, { MakeConstantString(clsAlias.second),
+          GetClassVar(clsAlias.first) }, sectionName<ClassAliasSection>());
+    // On ELF platforms, add a null value for each special section so that we
+    // can always guarantee that the _start and _stop symbols will exist and be
+    // meaningful.  This is not required on COFF platforms, where our start and
+    // stop symbols will create the section.
+    if (!CGM.getTriple().isOSBinFormatCOFF()) {
+      createNullGlobal(".objc_null_selector", {NULLPtr, NULLPtr},
+          sectionName<SelectorSection>());
+      if (Categories.empty())
+        createNullGlobal(".objc_null_category", {NULLPtr, NULLPtr,
+                      NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr},
+            sectionName<CategorySection>());
+      if (!EmittedClass) {
+        createNullGlobal(".objc_null_cls_init_ref", NULLPtr,
+            sectionName<ClassReferenceSection>());
+        createNullGlobal(".objc_null_class_ref", { NULLPtr, NULLPtr },
+            sectionName<ClassReferenceSection>());
+      }
+      if (!EmittedProtocol)
+        createNullGlobal(".objc_null_protocol", {NULLPtr, NULLPtr, NULLPtr,
+            NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr,
+            NULLPtr}, sectionName<ProtocolSection>());
+      if (!EmittedProtocolRef)
+        createNullGlobal(".objc_null_protocol_ref", {NULLPtr},
+            sectionName<ProtocolReferenceSection>());
+      if (ClassAliases.empty())
+        createNullGlobal(".objc_null_class_alias", { NULLPtr, NULLPtr },
+            sectionName<ClassAliasSection>());
+      if (ConstantStrings.empty()) {
+        auto i32Zero = llvm::ConstantInt::get(Int32Ty, 0);
+        createNullGlobal(".objc_null_constant_string", { NULLPtr, i32Zero,
+            i32Zero, i32Zero, i32Zero, NULLPtr },
+            sectionName<ConstantStringSection>());
+      }
     }
     ConstantStrings.clear();
     Categories.clear();
     Classes.clear();
-    return nullptr;//CGObjCGNU::ModuleInitFunction();
+    return nullptr;
   }
   /// In the v2 ABI, ivar offset variables use the type encoding in their name
   /// to trigger linker failures if the types don't match.
@@ -1774,7 +1835,7 @@
     }
 
     auto *classRefSymbol = GetClassVar(className);
-    classRefSymbol->setSection(ClsRefSection);
+    classRefSymbol->setSection(sectionName<ClassReferenceSection>());
     classRefSymbol->setInitializer(llvm::ConstantExpr::getBitCast(classStruct, IdTy));
 
 
@@ -1805,7 +1866,7 @@
     auto classInitRef = new llvm::GlobalVariable(TheModule,
         classStruct->getType(), false, llvm::GlobalValue::ExternalLinkage,
         classStruct, "._OBJC_INIT_CLASS_" + className);
-    classInitRef->setSection(ClsSection);
+    classInitRef->setSection(sectionName<ClassSection>());
     CGM.addUsedGlobal(classInitRef);
 
     EmittedClass = true;
@@ -1829,6 +1890,18 @@
 
 };
 
+const char *const CGObjCGNUstep2::SectionsBaseNames[8] =
+{
+"__objc_selectors",
+"__objc_classes",
+"__objc_class_refs",
+"__objc_cats",
+"__objc_protocols",
+"__objc_protocol_refs",
+"__objc_class_aliases",
+"__objc_constant_string"
+};
+
 /// Support for the ObjFW runtime.
 class CGObjCObjFW: public CGObjCGNU {
 protected:
@@ -2186,6 +2259,9 @@
 }
 
 llvm::Constant *CGObjCGNUstep::GetEHType(QualType T) {
+  if (CGM.getContext().getTargetInfo().getTriple().isWindowsMSVCEnvironment())
+    return CGM.getCXXABI().getAddrOfRTTIDescriptor(T);
+
   if (!CGM.getLangOpts().CPlusPlus)
     return CGObjCGNU::GetEHType(T);
 
@@ -3726,19 +3802,26 @@
                               const ObjCAtThrowStmt &S,
                               bool ClearInsertionPoint) {
   llvm::Value *ExceptionAsObject;
+  bool isRethrow = false;
 
   if (const Expr *ThrowExpr = S.getThrowExpr()) {
     llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
     ExceptionAsObject = Exception;
   } else {
     assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
            "Unexpected rethrow outside @catch block.");
     ExceptionAsObject = CGF.ObjCEHValueStack.back();
+    isRethrow = true;
+  }
+  if (isRethrow && CGF.CGM.getTarget().getTriple().isWindowsMSVCEnvironment()) {
+    CGF.EmitRuntimeCallOrInvoke(ExceptionReThrowFn).setDoesNotReturn();
+  }
+  else {
+    ExceptionAsObject = CGF.Builder.CreateBitCast(ExceptionAsObject, IdTy);
+    llvm::CallSite Throw =
+        CGF.EmitRuntimeCallOrInvoke(ExceptionThrowFn, ExceptionAsObject);
+    Throw.setDoesNotReturn();
   }
-  ExceptionAsObject = CGF.Builder.CreateBitCast(ExceptionAsObject, IdTy);
-  llvm::CallSite Throw =
-      CGF.EmitRuntimeCallOrInvoke(ExceptionThrowFn, ExceptionAsObject);
-  Throw.setDoesNotReturn();
   CGF.Builder.CreateUnreachable();
   if (ClearInsertionPoint)
     CGF.Builder.ClearInsertionPoint();
@@ -3812,40 +3895,10 @@
   // is.  This allows code compiled with non-fragile ivars to work correctly
   // when linked against code which isn't (most of the time).
   llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
-  if (!IvarOffsetPointer) {
-    // This will cause a run-time crash if we accidentally use it.  A value of
-    // 0 would seem more sensible, but will silently overwrite the isa pointer
-    // causing a great deal of confusion.
-    uint64_t Offset = -1;
-    // We can't call ComputeIvarBaseOffset() here if we have the
-    // implementation, because it will create an invalid ASTRecordLayout object
-    // that we are then stuck with forever, so we only initialize the ivar
-    // offset variable with a guess if we only have the interface.  The
-    // initializer will be reset later anyway, when we are generating the class
-    // description.
-    if (!CGM.getContext().getObjCImplementation(
-              const_cast<ObjCInterfaceDecl *>(ID)))
-      Offset = ComputeIvarBaseOffset(CGM, ID, Ivar);
-
-    llvm::ConstantInt *OffsetGuess = llvm::ConstantInt::get(Int32Ty, Offset,
-                             /*isSigned*/true);
-    // Don't emit the guess in non-PIC code because the linker will not be able
-    // to replace it with the real version for a library.  In non-PIC code you
-    // must compile with the fragile ABI if you want to use ivars from a
-    // GCC-compiled class.
-    if (CGM.getLangOpts().PICLevel) {
-      llvm::GlobalVariable *IvarOffsetGV = new llvm::GlobalVariable(TheModule,
-            Int32Ty, false,
-            llvm::GlobalValue::PrivateLinkage, OffsetGuess, Name+".guess");
-      IvarOffsetPointer = new llvm::GlobalVariable(TheModule,
-            IvarOffsetGV->getType(), false, llvm::GlobalValue::LinkOnceAnyLinkage,
-            IvarOffsetGV, Name);
-    } else {
-      IvarOffsetPointer = new llvm::GlobalVariable(TheModule,
-              llvm::Type::getInt32PtrTy(VMContext), false,
-              llvm::GlobalValue::ExternalLinkage, nullptr, Name);
-    }
-  }
+  if (!IvarOffsetPointer)
+    IvarOffsetPointer = new llvm::GlobalVariable(TheModule,
+            llvm::Type::getInt32PtrTy(VMContext), false,
+            llvm::GlobalValue::ExternalLinkage, nullptr, Name);
   return IvarOffsetPointer;
 }
 
Index: lib/CodeGen/CGException.cpp
===================================================================
--- lib/CodeGen/CGException.cpp
+++ lib/CodeGen/CGException.cpp
@@ -1829,7 +1829,7 @@
   SmallString<128> Name;
   {
     llvm::raw_svector_ostream OS(Name);
-    const FunctionDecl *ParentSEHFn = ParentCGF.CurSEHParent;
+    const NamedDecl *ParentSEHFn = ParentCGF.CurSEHParent;
     assert(ParentSEHFn && "No CurSEHParent!");
     MangleContext &Mangler = CGM.getCXXABI().getMangleContext();
     if (IsFilter)
@@ -1972,6 +1972,11 @@
   return Builder.CreateZExt(&*AI, Int32Ty);
 }
 
+void CodeGenFunction::pushSEHCleanup(CleanupKind Kind,
+                                     llvm::Function *FinallyFunc) {
+  EHStack.pushCleanup<PerformSEHFinally>(Kind, FinallyFunc);
+}
+
 void CodeGenFunction::EnterSEHTryStmt(const SEHTryStmt &S) {
   CodeGenFunction HelperCGF(CGM, /*suppressNewContext=*/true);
   if (const SEHFinallyStmt *Finally = S.getFinallyHandler()) {
Index: lib/AST/MicrosoftMangle.cpp
===================================================================
--- lib/AST/MicrosoftMangle.cpp
+++ lib/AST/MicrosoftMangle.cpp
@@ -445,7 +445,7 @@
     mangleFunctionEncoding(FD, Context.shouldMangleDeclName(FD));
   else if (const VarDecl *VD = dyn_cast<VarDecl>(D))
     mangleVariableEncoding(VD);
-  else
+  else if (!isa<ObjCInterfaceDecl>(D))
     llvm_unreachable("Tried to mangle unexpected NamedDecl!");
 }
 
@@ -1884,13 +1884,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) \
@@ -2570,9 +2570,10 @@
 
 void MicrosoftCXXNameMangler::mangleType(const ObjCInterfaceType *T, Qualifiers,
                                          SourceRange) {
-  // ObjC interfaces have structs underlying them.
+  // ObjC interfaces are mangled as if they were structs with a name that is
+  // not a valid C/C++ identifier
   mangleTagTypeKind(TTK_Struct);
-  mangleName(T->getDecl());
+  mangle(T->getDecl(), ".objc_cls_");
 }
 
 void MicrosoftCXXNameMangler::mangleType(const ObjCObjectType *T, Qualifiers,
@@ -2590,11 +2591,11 @@
 
   Out << "?$";
   if (T->isObjCId())
-    mangleSourceName("objc_object");
+    mangleSourceName(".objc_object");
   else if (T->isObjCClass())
-    mangleSourceName("objc_class");
+    mangleSourceName(".objc_class");
   else
-    mangleSourceName(T->getInterface()->getName());
+    mangleSourceName((".objc_cls_" + T->getInterface()->getName()).str());
 
   for (const auto &Q : T->quals())
     mangleObjCProtocol(Q);
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -1488,7 +1488,7 @@
   HelpText<"Enable ARC-style weak references in Objective-C">;
 
 // Objective-C ABI options.
-def fobjc_runtime_EQ : Joined<["-"], "fobjc-runtime=">, Group<f_Group>, Flags<[CC1Option]>,
+def fobjc_runtime_EQ : Joined<["-"], "fobjc-runtime=">, Group<f_Group>, Flags<[CC1Option, CoreOption]>,
   HelpText<"Specify the target Objective-C runtime kind and version">;
 def fobjc_abi_version_EQ : Joined<["-"], "fobjc-abi-version=">, Group<f_Group>;
 def fobjc_nonfragile_abi_version_EQ : Joined<["-"], "fobjc-nonfragile-abi-version=">, Group<f_Group>;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to