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

via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 10 20:12:38 PDT 2018


Hi David,

I made an attempt to fix the Windows bot test failures in r339494 by making the checks for the section boundaries not depend on the order they were emitted.

It seems that when using Visual Studio to build clang, the compiler that is generated emits the __stop_ section boundaries before the __start_ ones, thus causing your checks to fail. For example, you were checking for the following:

@__start___objc_selectors = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_selectors$a", comdat, align 1
@__stop__objc_selectors = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_selectors$z", comdat, align 1
@__start___objc_classes = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_classes$a", comdat, align 1
@__stop__objc_classes = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_classes$z", comdat, align 1

However the Visual Studio built clang was producing the following output:

@__stop__objc_selectors = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_selectors$z", comdat, align 1
@__start___objc_selectors = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_selectors$a", comdat, align 1
@__stop__objc_classes = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_classes$z", comdat, align 1
@__start___objc_classes = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_classes$a", comdat, align 1

I don’t think that the order matters, only that they are actually emitted, but if I am wrong, I apologize, and please revert my change and look into the problem.

Douglas Yung

From: cfe-commits [mailto:cfe-commits-bounces at lists.llvm.org] On Behalf Of Tom Weaver via cfe-commits
Sent: Friday, August 10, 2018 10:01
To: David Chisnall
Cc: cfe-commits at lists.llvm.org
Subject: Re: r339428 - Add Windows support for the GNUstep Objective-C ABI V2.

Hi David,

revision 339428 seems to have caused failing tests on a couple of windows build bots, any chance you can take a look please?

http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast/builds/18985


********************

Failing Tests (1):

    Clang :: CodeGenObjC/gnu-init.m



  Expected Passes    : 30627

  Expected Failures  : 65

  Unsupported Tests  : 12223

  Unexpected Failures: 1

Thanks

Tom Weaver

On 10 August 2018 at 13:53, David Chisnall via cfe-commits <cfe-commits at lists.llvm.org<mailto:cfe-commits at lists.llvm.org>> wrote:
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<http://arc-marker-funclet.mm>
    cfe/trunk/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm<http://microsoft-abi-arc-param-order.mm>
    cfe/trunk/test/CodeGenObjCXX/msabi-objc-extensions.mm<http://msabi-objc-extensions.mm>
    cfe/trunk/test/CodeGenObjCXX/msabi-objc-types.mm<http://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<http://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<http://arc-marker-funclet.mm> (original)
+++ cfe/trunk/test/CodeGenObjCXX/arc-marker-funclet.mm<http://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<http://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<http://microsoft-abi-arc-param-order.mm> (original)
+++ cfe/trunk/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm<http://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<http://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<http://msabi-objc-extensions.mm> (original)
+++ cfe/trunk/test/CodeGenObjCXX/msabi-objc-extensions.mm<http://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<http://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<http://msabi-objc-types.mm> (original)
+++ cfe/trunk/test/CodeGenObjCXX/msabi-objc-types.mm<http://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"



_______________________________________________
cfe-commits mailing list
cfe-commits at lists.llvm.org<mailto:cfe-commits at lists.llvm.org>
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180811/3aee65a1/attachment-0001.html>


More information about the cfe-commits mailing list