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

David Chisnall via cfe-commits cfe-commits at lists.llvm.org
Sat Aug 11 01:34:29 PDT 2018


Thanks,

That fix looks exactly what is needed - and is something I didn’t realise FileCheck could do!  The order of those matters in the linked binary, but not in the IR - the linker will arrange them sensibly based on the subsection name.

Thanks again,

David

> On 11 Aug 2018, at 04:12, <douglas.yung at sony.com> <douglas.yung at sony.com> wrote:
> 
> 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> 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
>     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"
> 
> 
> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits



More information about the cfe-commits mailing list