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@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.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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits