r339428 - Add Windows support for the GNUstep Objective-C ABI V2.

David Chisnall via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 10 05:53:13 PDT 2018


Author: theraven
Date: Fri Aug 10 05:53:13 2018
New Revision: 339428

URL: http://llvm.org/viewvc/llvm-project?rev=339428&view=rev
Log:
Add Windows support for the GNUstep Objective-C ABI V2.

Summary:
Introduces funclet-based unwinding for Objective-C and fixes an issue
where global blocks can't have their isa pointers initialised on
Windows.

After discussion with Dustin, this changes the name mangling of
Objective-C types to prevent a C++ catch statement of type struct X*
from catching an Objective-C object of type X*.

Reviewers: rjmccall, DHowett-MSFT

Reviewed By: rjmccall, DHowett-MSFT

Subscribers: mgrang, mstorsjo, smeenai, cfe-commits

Differential Revision: https://reviews.llvm.org/D50144

Modified:
    cfe/trunk/include/clang/Driver/Options.td
    cfe/trunk/lib/AST/MicrosoftMangle.cpp
    cfe/trunk/lib/CodeGen/CGException.cpp
    cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
    cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp
    cfe/trunk/lib/CodeGen/CGObjCRuntime.h
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/lib/Driver/ToolChains/Clang.cpp
    cfe/trunk/test/CodeGenObjC/gnu-init.m
    cfe/trunk/test/CodeGenObjC/gnustep2-proto.m
    cfe/trunk/test/CodeGenObjCXX/arc-marker-funclet.mm
    cfe/trunk/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm
    cfe/trunk/test/CodeGenObjCXX/msabi-objc-extensions.mm
    cfe/trunk/test/CodeGenObjCXX/msabi-objc-types.mm

Modified: cfe/trunk/include/clang/Driver/Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=339428&r1=339427&r2=339428&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Options.td (original)
+++ cfe/trunk/include/clang/Driver/Options.td Fri Aug 10 05:53:13 2018
@@ -1488,7 +1488,7 @@ def fobjc_weak : Flag<["-"], "fobjc-weak
   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>;

Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=339428&r1=339427&r2=339428&view=diff
==============================================================================
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Fri Aug 10 05:53:13 2018
@@ -445,7 +445,7 @@ void MicrosoftCXXNameMangler::mangle(con
     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 @@ void MicrosoftCXXNameMangler::mangleType
     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
 
 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 @@ void MicrosoftCXXNameMangler::mangleType
 
   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);

Modified: cfe/trunk/lib/CodeGen/CGException.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGException.cpp?rev=339428&r1=339427&r2=339428&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGException.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGException.cpp Fri Aug 10 05:53:13 2018
@@ -1829,7 +1829,7 @@ void CodeGenFunction::startOutlinedSEHHe
   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 @@ llvm::Value *CodeGenFunction::EmitSEHAbn
   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()) {

Modified: cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCGNU.cpp?rev=339428&r1=339427&r2=339428&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCGNU.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCGNU.cpp Fri Aug 10 05:53:13 2018
@@ -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"
@@ -178,6 +179,9 @@ protected:
   /// runtime provides some LLVM passes that can use this to do things like
   /// automatic IMP caching and speculative inlining.
   unsigned msgSendMDKind;
+  /// Does the current target use SEH-based exceptions? False implies
+  /// Itanium-style DWARF unwinding.
+  bool usesSEHExceptions;
 
   /// Helper to check if we are targeting a specific runtime version or later.
   bool isRuntime(ObjCRuntime::Kind kind, unsigned major, unsigned minor=0) {
@@ -217,6 +221,7 @@ protected:
       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 +815,12 @@ class CGObjCGNUstep : public CGObjCGNU {
       // 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 (usesSEHExceptions) {
+          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 +897,25 @@ class CGObjCGNUstep : public CGObjCGNU {
 /// 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 +1081,7 @@ class CGObjCGNUstep2 : public CGObjCGNUs
           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 +1259,10 @@ class CGObjCGNUstep2 : public CGObjCGNUs
       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 +1295,22 @@ class CGObjCGNUstep2 : public CGObjCGNUs
 
     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 +1327,6 @@ class CGObjCGNUstep2 : public CGObjCGNUs
     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 +1350,7 @@ class CGObjCGNUstep2 : public CGObjCGNUs
 
     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 +1383,7 @@ class CGObjCGNUstep2 : public CGObjCGNUs
           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 +1412,41 @@ class CGObjCGNUstep2 : public CGObjCGNUs
         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 +1459,9 @@ class CGObjCGNUstep2 : public CGObjCGNUs
     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 +1477,11 @@ class CGObjCGNUstep2 : public CGObjCGNUs
     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 +1500,23 @@ class CGObjCGNUstep2 : public CGObjCGNUs
     // 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 +1530,48 @@ class CGObjCGNUstep2 : public CGObjCGNUs
       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 +1838,7 @@ class CGObjCGNUstep2 : public CGObjCGNUs
     }
 
     auto *classRefSymbol = GetClassVar(className);
-    classRefSymbol->setSection(ClsRefSection);
+    classRefSymbol->setSection(sectionName<ClassReferenceSection>());
     classRefSymbol->setInitializer(llvm::ConstantExpr::getBitCast(classStruct, IdTy));
 
 
@@ -1805,7 +1869,7 @@ class CGObjCGNUstep2 : public CGObjCGNUs
     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 +1893,18 @@ class CGObjCGNUstep2 : public CGObjCGNUs
 
 };
 
+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:
@@ -1931,6 +2007,8 @@ CGObjCGNU::CGObjCGNU(CodeGenModule &cgm,
     ProtocolVersion(protocolClassVersion), ClassABIVersion(classABI) {
 
   msgSendMDKind = VMContext.getMDKindID("GNUObjCMessageSend");
+  usesSEHExceptions =
+      cgm.getContext().getTargetInfo().getTriple().isWindowsMSVCEnvironment();
 
   CodeGenTypes &Types = CGM.getTypes();
   IntTy = cast<llvm::IntegerType>(
@@ -2186,6 +2264,9 @@ llvm::Constant *CGObjCGNU::GetEHType(Qua
 }
 
 llvm::Constant *CGObjCGNUstep::GetEHType(QualType T) {
+  if (usesSEHExceptions)
+    return CGM.getCXXABI().getAddrOfRTTIDescriptor(T);
+
   if (!CGM.getLangOpts().CPlusPlus)
     return CGObjCGNU::GetEHType(T);
 
@@ -3726,6 +3807,7 @@ void CGObjCGNU::EmitThrowStmt(CodeGenFun
                               const ObjCAtThrowStmt &S,
                               bool ClearInsertionPoint) {
   llvm::Value *ExceptionAsObject;
+  bool isRethrow = false;
 
   if (const Expr *ThrowExpr = S.getThrowExpr()) {
     llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
@@ -3734,11 +3816,24 @@ void CGObjCGNU::EmitThrowStmt(CodeGenFun
     assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
            "Unexpected rethrow outside @catch block.");
     ExceptionAsObject = CGF.ObjCEHValueStack.back();
+    isRethrow = true;
+  }
+  if (isRethrow && usesSEHExceptions) {
+    // For SEH, ExceptionAsObject may be undef, because the catch handler is
+    // not passed it for catchalls and so it is not visible to the catch
+    // funclet.  The real thrown object will still be live on the stack at this
+    // point and will be rethrown.  If we are explicitly rethrowing the object
+    // that was passed into the `@catch` block, then this code path is not
+    // reached and we will instead call `objc_exception_throw` with an explicit
+    // argument.
+    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();

Modified: cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp?rev=339428&r1=339427&r2=339428&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp Fri Aug 10 05:53:13 2018
@@ -15,6 +15,7 @@
 
 #include "CGObjCRuntime.h"
 #include "CGCleanup.h"
+#include "CGCXXABI.h"
 #include "CGRecordLayout.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
@@ -22,6 +23,7 @@
 #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 @@ namespace {
     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 @@ void CGObjCRuntime::EmitTryCatchStmt(Cod
   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 @@ void CGObjCRuntime::EmitTryCatchStmt(Cod
       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 @@ void CGObjCRuntime::EmitTryCatchStmt(Cod
 
     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 @@ void CGObjCRuntime::EmitTryCatchStmt(Cod
     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 @@ void CGObjCRuntime::EmitTryCatchStmt(Cod
       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 @@ void CGObjCRuntime::EmitTryCatchStmt(Cod
     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 @@ namespace {
       : SyncExitFn(SyncExitFn), SyncArg(SyncArg) {}
 
     void Emit(CodeGenFunction &CGF, Flags flags) override {
-      CGF.Builder.CreateCall(SyncExitFn, SyncArg)->setDoesNotThrow();
+      CGF.EmitNounwindRuntimeCall(SyncExitFn, SyncArg);
     }
   };
 }

Modified: cfe/trunk/lib/CodeGen/CGObjCRuntime.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCRuntime.h?rev=339428&r1=339427&r2=339428&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCRuntime.h (original)
+++ cfe/trunk/lib/CodeGen/CGObjCRuntime.h Fri Aug 10 05:53:13 2018
@@ -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 @@ public:
   /// 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;
 

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=339428&r1=339427&r2=339428&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Fri Aug 10 05:53:13 2018
@@ -470,7 +470,7 @@ public:
   /// 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 @@ public:
   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);
 

Modified: cfe/trunk/lib/Driver/ToolChains/Clang.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Clang.cpp?rev=339428&r1=339427&r2=339428&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains/Clang.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains/Clang.cpp Fri Aug 10 05:53:13 2018
@@ -4915,7 +4915,8 @@ ObjCRuntime Clang::AddObjCRuntimeArgs(co
     }
     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();

Modified: cfe/trunk/test/CodeGenObjC/gnu-init.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/gnu-init.m?rev=339428&r1=339427&r2=339428&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/gnu-init.m (original)
+++ cfe/trunk/test/CodeGenObjC/gnu-init.m Fri Aug 10 05:53:13 2018
@@ -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
+

Modified: cfe/trunk/test/CodeGenObjC/gnustep2-proto.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/gnustep2-proto.m?rev=339428&r1=339427&r2=339428&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/gnustep2-proto.m (original)
+++ cfe/trunk/test/CodeGenObjC/gnustep2-proto.m Fri Aug 10 05:53:13 2018
@@ -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.

Modified: cfe/trunk/test/CodeGenObjCXX/arc-marker-funclet.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/arc-marker-funclet.mm?rev=339428&r1=339427&r2=339428&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjCXX/arc-marker-funclet.mm (original)
+++ cfe/trunk/test/CodeGenObjCXX/arc-marker-funclet.mm Fri Aug 10 05:53:13 2018
@@ -10,7 +10,7 @@ void g() {
   }
 }
 
-// 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.

Modified: cfe/trunk/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm?rev=339428&r1=339427&r2=339428&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm (original)
+++ cfe/trunk/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm Fri Aug 10 05:53:13 2018
@@ -9,7 +9,7 @@ struct A {
 
 // 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 at Z"
+// CHECK-LABEL: define dso_local void @"?test_arc_order@@YAXUA@@PAU.objc_object@@01 at 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 at XZ"(%struct.A* %{{.*}})

Modified: cfe/trunk/test/CodeGenObjCXX/msabi-objc-extensions.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/msabi-objc-extensions.mm?rev=339428&r1=339427&r2=339428&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjCXX/msabi-objc-extensions.mm (original)
+++ cfe/trunk/test/CodeGenObjCXX/msabi-objc-extensions.mm Fri Aug 10 05:53:13 2018
@@ -6,61 +6,61 @@
 @class I;
 
 void f(id<P>, id, id<P>, id) {}
-// CHECK-LABEL: "?f@@YAXPAU?$objc_object at U?$Protocol at UP@@@__ObjC@@@@PAUobjc_object@@01 at Z"
+// CHECK-LABEL: "?f@@YAXPAU?$.objc_object at U?$Protocol at UP@@@__ObjC@@@@PAU.objc_object@@01 at Z"
 
 void f(id, id<P>, id<P>, id) {}
-// CHECK-LABEL: "?f@@YAXPAUobjc_object@@PAU?$objc_object at U?$Protocol at UP@@@__ObjC@@@@10 at Z"
+// CHECK-LABEL: "?f@@YAXPAU.objc_object@@PAU?$.objc_object at U?$Protocol at UP@@@__ObjC@@@@10 at Z"
 
 void f(id<P>, id<P>) {}
-// CHECK-LABEL: "?f@@YAXPAU?$objc_object at U?$Protocol at UP@@@__ObjC@@@@0 at Z"
+// CHECK-LABEL: "?f@@YAXPAU?$.objc_object at U?$Protocol at UP@@@__ObjC@@@@0 at Z"
 
 void f(id<P>) {}
-// CHECK-LABEL: "?f@@YAXPAU?$objc_object at U?$Protocol at UP@@@__ObjC@@@@@Z"
+// CHECK-LABEL: "?f@@YAXPAU?$.objc_object at U?$Protocol at UP@@@__ObjC@@@@@Z"
 
 void f(id<P, Q>) {}
-// CHECK-LABEL: "?f@@YAXPAU?$objc_object at U?$Protocol at UP@@@__ObjC@@U?$Protocol at UQ@@@2@@@@Z"
+// CHECK-LABEL: "?f@@YAXPAU?$.objc_object at U?$Protocol at UP@@@__ObjC@@U?$Protocol at UQ@@@2@@@@Z"
 
 void f(Class<P>) {}
-// CHECK-LABEL: "?f@@YAXPAU?$objc_class at U?$Protocol at UP@@@__ObjC@@@@@Z"
+// CHECK-LABEL: "?f@@YAXPAU?$.objc_class at U?$Protocol at UP@@@__ObjC@@@@@Z"
 
 void f(Class<P, Q>) {}
-// CHECK-LABEL: "?f@@YAXPAU?$objc_class at U?$Protocol at UP@@@__ObjC@@U?$Protocol at UQ@@@2@@@@Z"
+// CHECK-LABEL: "?f@@YAXPAU?$.objc_class at U?$Protocol at UP@@@__ObjC@@U?$Protocol at UQ@@@2@@@@Z"
 
 void f(I<P> *) {}
-// CHECK-LABEL: "?f@@YAXPAU?$I at U?$Protocol at UP@@@__ObjC@@@@@Z"
+// CHECK-LABEL: "?f@@YAXPAU?$.objc_cls_I at U?$Protocol at UP@@@__ObjC@@@@@Z"
 
 void f(I<P, Q> *) {}
-// CHECK-LABEL: "?f@@YAXPAU?$I at U?$Protocol at UP@@@__ObjC@@U?$Protocol at UQ@@@2@@@@Z"
+// CHECK-LABEL: "?f@@YAXPAU?$.objc_cls_I at U?$Protocol at UP@@@__ObjC@@U?$Protocol at UQ@@@2@@@@Z"
 
 template <typename>
 struct S {};
 
 void f(S<__unsafe_unretained id>) {}
-// CHECK-LABEL: "?f@@YAXU?$S at PAUobjc_object@@@@@Z"
+// CHECK-LABEL: "?f@@YAXU?$S at PAU.objc_object@@@@@Z"
 
 void f(S<__autoreleasing id>) {}
-// CHECK-LABEL: "?f@@YAXU?$S at U?$Autoreleasing at PAUobjc_object@@@__ObjC@@@@@Z"
+// CHECK-LABEL: "?f@@YAXU?$S at U?$Autoreleasing at PAU.objc_object@@@__ObjC@@@@@Z"
 
 void f(S<__strong id>) {}
-// CHECK-LABEL: "?f@@YAXU?$S at U?$Strong at PAUobjc_object@@@__ObjC@@@@@Z"
+// CHECK-LABEL: "?f@@YAXU?$S at U?$Strong at PAU.objc_object@@@__ObjC@@@@@Z"
 
 void f(S<__weak id>) {}
-// CHECK-LABEL: "?f@@YAXU?$S at U?$Weak at PAUobjc_object@@@__ObjC@@@@@Z"
+// CHECK-LABEL: "?f@@YAXU?$S at U?$Weak at 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 at U?$Autoreleasing at PAUobjc_object@@@__ObjC@@@@XZ"
+// CHECK-LABEL: "?g@@YA?AU?$S at U?$Autoreleasing at PAU.objc_object@@@__ObjC@@@@XZ"
 
 __autoreleasing id h() { return nullptr; }
-// CHECK-LABEL: "?h@@YAPAUobjc_object@@XZ"
+// CHECK-LABEL: "?h@@YAPAU.objc_object@@XZ"

Modified: cfe/trunk/test/CodeGenObjCXX/msabi-objc-types.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/msabi-objc-types.mm?rev=339428&r1=339427&r2=339428&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjCXX/msabi-objc-types.mm (original)
+++ cfe/trunk/test/CodeGenObjCXX/msabi-objc-types.mm Fri Aug 10 05:53:13 2018
@@ -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 at s@@QAAXPAUI@@@Z"
+  // CHECK-LABEL: "?m at s@@QAAXPAU.objc_cls_I@@@Z"
 
   void m(const I *) {}
-  // CHECK-LABEL: "?m at s@@QAAXPBUI@@@Z"
+  // CHECK-LABEL: "?m at s@@QAAXPBU.objc_cls_I@@@Z"
 
   void m(I &) {}
-  // CHECK-LABEL: "?m at s@@QAAXAAUI@@@Z"
+  // CHECK-LABEL: "?m at s@@QAAXAAU.objc_cls_I@@@Z"
 
   void m(const I &) {}
-  // CHECK-LABEL: "?m at s@@QAAXABUI@@@Z"
+  // CHECK-LABEL: "?m at s@@QAAXABU.objc_cls_I@@@Z"
 
   void m(I &&) {}
-  // CHECK-LABEL: "?m at s@@QAAX$$QAUI@@@Z"
+  // CHECK-LABEL: "?m at s@@QAAX$$QAU.objc_cls_I@@@Z"
 
   void m(const I &&) {}
-  // CHECK-LABEL: "?m at s@@QAAX$$QBUI@@@Z"
+  // CHECK-LABEL: "?m at s@@QAAX$$QBU.objc_cls_I@@@Z"
 
   void m(id) {}
-  // CHECK-LABEL: "?m at s@@QAAXPAUobjc_object@@@Z"
+  // CHECK-LABEL: "?m at s@@QAAXPAU.objc_object@@@Z"
 
   void m(id &) {}
-  // CHECK-LABEL: "?m at s@@QAAXAAPAUobjc_object@@@Z"
+  // CHECK-LABEL: "?m at s@@QAAXAAPAU.objc_object@@@Z"
 
   void m(id &&) {}
-  // CHECK-LABEL: "?m at s@@QAAX$$QAPAUobjc_object@@@Z"
+  // CHECK-LABEL: "?m at s@@QAAX$$QAPAU.objc_object@@@Z"
 
   void m(const id &) {}
-  // CHECK-LABEL: "?m at s@@QAAXABQAUobjc_object@@@Z"
+  // CHECK-LABEL: "?m at s@@QAAXABQAU.objc_object@@@Z"
 
   void m(const id &&) {}
-  // CHECK-LABEL: "?m at s@@QAAX$$QBQAUobjc_object@@@Z"
+  // CHECK-LABEL: "?m at s@@QAAX$$QBQAU.objc_object@@@Z"
 
   void m(Class *) {}
-  // CHECK-LABEL: "?m at s@@QAAXPAPAUobjc_class@@@Z"
+  // CHECK-LABEL: "?m at s@@QAAXPAPAU.objc_class@@@Z"
 
   void m(const Class *) {}
-  // CHECK-LABEL: "?m at s@@QAAXPBQAUobjc_class@@@Z"
+  // CHECK-LABEL: "?m at s@@QAAXPBQAU.objc_class@@@Z"
 
   void m(Class) {}
-  // CHECK-LABEL: "?m at s@@QAAXPAUobjc_class@@@Z"
+  // CHECK-LABEL: "?m at s@@QAAXPAU.objc_class@@@Z"
 
   void m(Class &) {}
-  // CHECK-LABEL: "?m at s@@QAAXAAPAUobjc_class@@@Z"
+  // CHECK-LABEL: "?m at s@@QAAXAAPAU.objc_class@@@Z"
 
   void m(const Class &) {}
-  // CHECK-LABEL: "?m at s@@QAAXABQAUobjc_class@@@Z"
+  // CHECK-LABEL: "?m at s@@QAAXABQAU.objc_class@@@Z"
 
   void m(Class &&) {}
-  // CHECK-LABEL: "?m at s@@QAAX$$QAPAUobjc_class@@@Z"
+  // CHECK-LABEL: "?m at s@@QAAX$$QAPAU.objc_class@@@Z"
 
   void m(const Class &&) {}
-  // CHECK-LABEL: "?m at s@@QAAX$$QBQAUobjc_class@@@Z"
+  // CHECK-LABEL: "?m at s@@QAAX$$QBQAU.objc_class@@@Z"
 
   void m(SEL) {}
-  // CHECK-LABEL: "?m at s@@QAAXPAUobjc_selector@@@Z"
+  // CHECK-LABEL: "?m at s@@QAAXPAU.objc_selector@@@Z"
 
   void m(SEL *) {}
-  // CHECK-LABEL: "?m at s@@QAAXPAPAUobjc_selector@@@Z"
+  // CHECK-LABEL: "?m at s@@QAAXPAPAU.objc_selector@@@Z"
 
   void m(const SEL *) {}
-  // CHECK-LABEL: "?m at s@@QAAXPBQAUobjc_selector@@@Z"
+  // CHECK-LABEL: "?m at s@@QAAXPBQAU.objc_selector@@@Z"
 
   void m(SEL &) {}
-  // CHECK-LABEL: "?m at s@@QAAXAAPAUobjc_selector@@@Z"
+  // CHECK-LABEL: "?m at s@@QAAXAAPAU.objc_selector@@@Z"
 
   void m(const SEL &) {}
-  // CHECK-LABEL: "?m at s@@QAAXABQAUobjc_selector@@@Z"
+  // CHECK-LABEL: "?m at s@@QAAXABQAU.objc_selector@@@Z"
 
   void m(SEL &&) {}
-  // CHECK-LABEL: "?m at s@@QAAX$$QAPAUobjc_selector@@@Z"
+  // CHECK-LABEL: "?m at s@@QAAX$$QAPAU.objc_selector@@@Z"
 
   void m(const SEL &&) {}
-  // CHECK-LABEL: "?m at s@@QAAX$$QBQAUobjc_selector@@@Z"
+  // CHECK-LABEL: "?m at s@@QAAX$$QBQAU.objc_selector@@@Z"
 };
 
 template <typename T>
@@ -179,14 +179,14 @@ struct t {
 };
 
 template struct t<id>;
-// CHECK-LABEL: "??0?$t at PAUobjc_object@@@@QAA at XZ"
+// CHECK-LABEL: "??0?$t at PAU.objc_object@@@@QAA at XZ"
 
 template struct t<remove_pointer<id>::type>;
-// CHECK-LABEL: "??0?$t at Uobjc_object@@@@QAA at XZ"
+// CHECK-LABEL: "??0?$t at U.objc_object@@@@QAA at XZ"
 
 template struct t<SEL>;
-// CHECK-LABEL: "??0?$t at PAUobjc_selector@@@@QAA at XZ"
+// CHECK-LABEL: "??0?$t at PAU.objc_selector@@@@QAA at XZ"
 
 template struct t<remove_pointer<SEL>::type>;
-// CHECK-LABEL: "??0?$t at Uobjc_selector@@@@QAA at XZ"
+// CHECK-LABEL: "??0?$t at U.objc_selector@@@@QAA at XZ"
 




More information about the cfe-commits mailing list