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.y...@sony.com> <douglas.y...@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-boun...@lists.llvm.org] On Behalf Of > Tom Weaver via cfe-commits > Sent: Friday, August 10, 2018 10:01 > To: David Chisnall > Cc: cfe-commits@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@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@Z" > +// CHECK-LABEL: define dso_local void > @"?test_arc_order@@YAXUA@@PAU.objc_object@@01@Z" > // CHECK: (<{ %struct.A, i8*, %struct.A, i8* }>* > inalloca) > void test_arc_order(A a, id __attribute__((ns_consumed)) b , A c, id > __attribute__((ns_consumed)) d) { > // CHECK: call x86_thiscallcc void @"??1A@@QAE@XZ"(%struct.A* %{{.*}}) > > 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@U?$Protocol@UP@@@__ObjC@@@@PAUobjc_object@@01@Z" > +// CHECK-LABEL: > "?f@@YAXPAU?$.objc_object@U?$Protocol@UP@@@__ObjC@@@@PAU.objc_object@@01@Z" > > void f(id, id<P>, id<P>, id) {} > -// CHECK-LABEL: > "?f@@YAXPAUobjc_object@@PAU?$objc_object@U?$Protocol@UP@@@__ObjC@@@@10@Z" > +// CHECK-LABEL: > "?f@@YAXPAU.objc_object@@PAU?$.objc_object@U?$Protocol@UP@@@__ObjC@@@@10@Z" > > void f(id<P>, id<P>) {} > -// CHECK-LABEL: "?f@@YAXPAU?$objc_object@U?$Protocol@UP@@@__ObjC@@@@0@Z" > +// CHECK-LABEL: "?f@@YAXPAU?$.objc_object@U?$Protocol@UP@@@__ObjC@@@@0@Z" > > void f(id<P>) {} > -// CHECK-LABEL: "?f@@YAXPAU?$objc_object@U?$Protocol@UP@@@__ObjC@@@@@Z" > +// CHECK-LABEL: "?f@@YAXPAU?$.objc_object@U?$Protocol@UP@@@__ObjC@@@@@Z" > > void f(id<P, Q>) {} > -// CHECK-LABEL: > "?f@@YAXPAU?$objc_object@U?$Protocol@UP@@@__ObjC@@U?$Protocol@UQ@@@2@@@@Z" > +// CHECK-LABEL: > "?f@@YAXPAU?$.objc_object@U?$Protocol@UP@@@__ObjC@@U?$Protocol@UQ@@@2@@@@Z" > > void f(Class<P>) {} > -// CHECK-LABEL: "?f@@YAXPAU?$objc_class@U?$Protocol@UP@@@__ObjC@@@@@Z" > +// CHECK-LABEL: "?f@@YAXPAU?$.objc_class@U?$Protocol@UP@@@__ObjC@@@@@Z" > > void f(Class<P, Q>) {} > -// CHECK-LABEL: > "?f@@YAXPAU?$objc_class@U?$Protocol@UP@@@__ObjC@@U?$Protocol@UQ@@@2@@@@Z" > +// CHECK-LABEL: > "?f@@YAXPAU?$.objc_class@U?$Protocol@UP@@@__ObjC@@U?$Protocol@UQ@@@2@@@@Z" > > void f(I<P> *) {} > -// CHECK-LABEL: "?f@@YAXPAU?$I@U?$Protocol@UP@@@__ObjC@@@@@Z" > +// CHECK-LABEL: "?f@@YAXPAU?$.objc_cls_I@U?$Protocol@UP@@@__ObjC@@@@@Z" > > void f(I<P, Q> *) {} > -// CHECK-LABEL: > "?f@@YAXPAU?$I@U?$Protocol@UP@@@__ObjC@@U?$Protocol@UQ@@@2@@@@Z" > +// CHECK-LABEL: > "?f@@YAXPAU?$.objc_cls_I@U?$Protocol@UP@@@__ObjC@@U?$Protocol@UQ@@@2@@@@Z" > > template <typename> > struct S {}; > > void f(S<__unsafe_unretained id>) {} > -// CHECK-LABEL: "?f@@YAXU?$S@PAUobjc_object@@@@@Z" > +// CHECK-LABEL: "?f@@YAXU?$S@PAU.objc_object@@@@@Z" > > void f(S<__autoreleasing id>) {} > -// CHECK-LABEL: "?f@@YAXU?$S@U?$Autoreleasing@PAUobjc_object@@@__ObjC@@@@@Z" > +// CHECK-LABEL: "?f@@YAXU?$S@U?$Autoreleasing@PAU.objc_object@@@__ObjC@@@@@Z" > > void f(S<__strong id>) {} > -// CHECK-LABEL: "?f@@YAXU?$S@U?$Strong@PAUobjc_object@@@__ObjC@@@@@Z" > +// CHECK-LABEL: "?f@@YAXU?$S@U?$Strong@PAU.objc_object@@@__ObjC@@@@@Z" > > void f(S<__weak id>) {} > -// CHECK-LABEL: "?f@@YAXU?$S@U?$Weak@PAUobjc_object@@@__ObjC@@@@@Z" > +// CHECK-LABEL: "?f@@YAXU?$S@U?$Weak@PAU.objc_object@@@__ObjC@@@@@Z" > > void w(__weak id) {} > -// CHECK-LABEL: "?w@@YAXPAUobjc_object@@@Z" > +// CHECK-LABEL: "?w@@YAXPAU.objc_object@@@Z" > > void s(__strong id) {} > -// CHECK-LABEL: "?s@@YAXPAUobjc_object@@@Z" > +// CHECK-LABEL: "?s@@YAXPAU.objc_object@@@Z" > > void a(__autoreleasing id) {} > -// CHECK-LABEL: "?a@@YAXPAUobjc_object@@@Z" > +// CHECK-LABEL: "?a@@YAXPAU.objc_object@@@Z" > > void u(__unsafe_unretained id) {} > -// CHECK-LABEL: "?u@@YAXPAUobjc_object@@@Z" > +// CHECK-LABEL: "?u@@YAXPAU.objc_object@@@Z" > > S<__autoreleasing id> g() { return S<__autoreleasing id>(); } > -// CHECK-LABEL: "?g@@YA?AU?$S@U?$Autoreleasing@PAUobjc_object@@@__ObjC@@@@XZ" > +// CHECK-LABEL: > "?g@@YA?AU?$S@U?$Autoreleasing@PAU.objc_object@@@__ObjC@@@@XZ" > > __autoreleasing id h() { return nullptr; } > -// CHECK-LABEL: "?h@@YAPAUobjc_object@@XZ" > +// CHECK-LABEL: "?h@@YAPAU.objc_object@@XZ" > > 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@s@@QAAXPAUI@@@Z" > + // CHECK-LABEL: "?m@s@@QAAXPAU.objc_cls_I@@@Z" > > void m(const I *) {} > - // CHECK-LABEL: "?m@s@@QAAXPBUI@@@Z" > + // CHECK-LABEL: "?m@s@@QAAXPBU.objc_cls_I@@@Z" > > void m(I &) {} > - // CHECK-LABEL: "?m@s@@QAAXAAUI@@@Z" > + // CHECK-LABEL: "?m@s@@QAAXAAU.objc_cls_I@@@Z" > > void m(const I &) {} > - // CHECK-LABEL: "?m@s@@QAAXABUI@@@Z" > + // CHECK-LABEL: "?m@s@@QAAXABU.objc_cls_I@@@Z" > > void m(I &&) {} > - // CHECK-LABEL: "?m@s@@QAAX$$QAUI@@@Z" > + // CHECK-LABEL: "?m@s@@QAAX$$QAU.objc_cls_I@@@Z" > > void m(const I &&) {} > - // CHECK-LABEL: "?m@s@@QAAX$$QBUI@@@Z" > + // CHECK-LABEL: "?m@s@@QAAX$$QBU.objc_cls_I@@@Z" > > void m(id) {} > - // CHECK-LABEL: "?m@s@@QAAXPAUobjc_object@@@Z" > + // CHECK-LABEL: "?m@s@@QAAXPAU.objc_object@@@Z" > > void m(id &) {} > - // CHECK-LABEL: "?m@s@@QAAXAAPAUobjc_object@@@Z" > + // CHECK-LABEL: "?m@s@@QAAXAAPAU.objc_object@@@Z" > > void m(id &&) {} > - // CHECK-LABEL: "?m@s@@QAAX$$QAPAUobjc_object@@@Z" > + // CHECK-LABEL: "?m@s@@QAAX$$QAPAU.objc_object@@@Z" > > void m(const id &) {} > - // CHECK-LABEL: "?m@s@@QAAXABQAUobjc_object@@@Z" > + // CHECK-LABEL: "?m@s@@QAAXABQAU.objc_object@@@Z" > > void m(const id &&) {} > - // CHECK-LABEL: "?m@s@@QAAX$$QBQAUobjc_object@@@Z" > + // CHECK-LABEL: "?m@s@@QAAX$$QBQAU.objc_object@@@Z" > > void m(Class *) {} > - // CHECK-LABEL: "?m@s@@QAAXPAPAUobjc_class@@@Z" > + // CHECK-LABEL: "?m@s@@QAAXPAPAU.objc_class@@@Z" > > void m(const Class *) {} > - // CHECK-LABEL: "?m@s@@QAAXPBQAUobjc_class@@@Z" > + // CHECK-LABEL: "?m@s@@QAAXPBQAU.objc_class@@@Z" > > void m(Class) {} > - // CHECK-LABEL: "?m@s@@QAAXPAUobjc_class@@@Z" > + // CHECK-LABEL: "?m@s@@QAAXPAU.objc_class@@@Z" > > void m(Class &) {} > - // CHECK-LABEL: "?m@s@@QAAXAAPAUobjc_class@@@Z" > + // CHECK-LABEL: "?m@s@@QAAXAAPAU.objc_class@@@Z" > > void m(const Class &) {} > - // CHECK-LABEL: "?m@s@@QAAXABQAUobjc_class@@@Z" > + // CHECK-LABEL: "?m@s@@QAAXABQAU.objc_class@@@Z" > > void m(Class &&) {} > - // CHECK-LABEL: "?m@s@@QAAX$$QAPAUobjc_class@@@Z" > + // CHECK-LABEL: "?m@s@@QAAX$$QAPAU.objc_class@@@Z" > > void m(const Class &&) {} > - // CHECK-LABEL: "?m@s@@QAAX$$QBQAUobjc_class@@@Z" > + // CHECK-LABEL: "?m@s@@QAAX$$QBQAU.objc_class@@@Z" > > void m(SEL) {} > - // CHECK-LABEL: "?m@s@@QAAXPAUobjc_selector@@@Z" > + // CHECK-LABEL: "?m@s@@QAAXPAU.objc_selector@@@Z" > > void m(SEL *) {} > - // CHECK-LABEL: "?m@s@@QAAXPAPAUobjc_selector@@@Z" > + // CHECK-LABEL: "?m@s@@QAAXPAPAU.objc_selector@@@Z" > > void m(const SEL *) {} > - // CHECK-LABEL: "?m@s@@QAAXPBQAUobjc_selector@@@Z" > + // CHECK-LABEL: "?m@s@@QAAXPBQAU.objc_selector@@@Z" > > void m(SEL &) {} > - // CHECK-LABEL: "?m@s@@QAAXAAPAUobjc_selector@@@Z" > + // CHECK-LABEL: "?m@s@@QAAXAAPAU.objc_selector@@@Z" > > void m(const SEL &) {} > - // CHECK-LABEL: "?m@s@@QAAXABQAUobjc_selector@@@Z" > + // CHECK-LABEL: "?m@s@@QAAXABQAU.objc_selector@@@Z" > > void m(SEL &&) {} > - // CHECK-LABEL: "?m@s@@QAAX$$QAPAUobjc_selector@@@Z" > + // CHECK-LABEL: "?m@s@@QAAX$$QAPAU.objc_selector@@@Z" > > void m(const SEL &&) {} > - // CHECK-LABEL: "?m@s@@QAAX$$QBQAUobjc_selector@@@Z" > + // CHECK-LABEL: "?m@s@@QAAX$$QBQAU.objc_selector@@@Z" > }; > > template <typename T> > @@ -179,14 +179,14 @@ struct t { > }; > > template struct t<id>; > -// CHECK-LABEL: "??0?$t@PAUobjc_object@@@@QAA@XZ" > +// CHECK-LABEL: "??0?$t@PAU.objc_object@@@@QAA@XZ" > > template struct t<remove_pointer<id>::type>; > -// CHECK-LABEL: "??0?$t@Uobjc_object@@@@QAA@XZ" > +// CHECK-LABEL: "??0?$t@U.objc_object@@@@QAA@XZ" > > template struct t<SEL>; > -// CHECK-LABEL: "??0?$t@PAUobjc_selector@@@@QAA@XZ" > +// CHECK-LABEL: "??0?$t@PAU.objc_selector@@@@QAA@XZ" > > template struct t<remove_pointer<SEL>::type>; > -// CHECK-LABEL: "??0?$t@Uobjc_selector@@@@QAA@XZ" > +// CHECK-LABEL: "??0?$t@U.objc_selector@@@@QAA@XZ" > > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits