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

Hans Wennborg via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 13 00:59:56 PDT 2018


Merged both of these to 7.0 in r339538.

On Sat, Aug 11, 2018 at 10:34 AM, David Chisnall via cfe-commits
<cfe-commits at lists.llvm.org> wrote:
> 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
>
> _______________________________________________
> 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