r339428 - Add Windows support for the GNUstep Objective-C ABI V2.
David Chisnall via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 10 13:40:45 PDT 2018
Hi Tom,
I’ll take a look over the weekend and see if I can reproduce locally. It’s odd that a test for a Windows triple would be behaving differently on a Windows host.
David
> On 10 Aug 2018, at 18:01, Tom Weaver <chackz0x12 at gmail.com> wrote:
>
> Hi David,
>
> revision 339428 seems to have caused failing tests on a couple of windows build bots, any chance you can take a look please?
>
> http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast/builds/18985
>
> ********************
> Failing Tests (1):
> Clang :: CodeGenObjC/gnu-init.m
>
> Expected Passes : 30627
> Expected Failures : 65
> Unsupported Tests : 12223
> Unexpected Failures: 1
>
>
> Thanks
>
> Tom Weaver
>
> On 10 August 2018 at 13:53, David Chisnall via cfe-commits <cfe-commits at lists.llvm.org> wrote:
> Author: theraven
> Date: Fri Aug 10 05:53:13 2018
> New Revision: 339428
>
> URL: http://llvm.org/viewvc/llvm-project?rev=339428&view=rev
> Log:
> Add Windows support for the GNUstep Objective-C ABI V2.
>
> Summary:
> Introduces funclet-based unwinding for Objective-C and fixes an issue
> where global blocks can't have their isa pointers initialised on
> Windows.
>
> After discussion with Dustin, this changes the name mangling of
> Objective-C types to prevent a C++ catch statement of type struct X*
> from catching an Objective-C object of type X*.
>
> Reviewers: rjmccall, DHowett-MSFT
>
> Reviewed By: rjmccall, DHowett-MSFT
>
> Subscribers: mgrang, mstorsjo, smeenai, cfe-commits
>
> Differential Revision: https://reviews.llvm.org/D50144
>
> Modified:
> cfe/trunk/include/clang/Driver/Options.td
> cfe/trunk/lib/AST/MicrosoftMangle.cpp
> cfe/trunk/lib/CodeGen/CGException.cpp
> cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
> cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp
> cfe/trunk/lib/CodeGen/CGObjCRuntime.h
> cfe/trunk/lib/CodeGen/CodeGenFunction.h
> cfe/trunk/lib/Driver/ToolChains/Clang.cpp
> cfe/trunk/test/CodeGenObjC/gnu-init.m
> cfe/trunk/test/CodeGenObjC/gnustep2-proto.m
> cfe/trunk/test/CodeGenObjCXX/arc-marker-funclet.mm
> cfe/trunk/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm
> cfe/trunk/test/CodeGenObjCXX/msabi-objc-extensions.mm
> cfe/trunk/test/CodeGenObjCXX/msabi-objc-types.mm
>
> Modified: cfe/trunk/include/clang/Driver/Options.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=339428&r1=339427&r2=339428&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Driver/Options.td (original)
> +++ cfe/trunk/include/clang/Driver/Options.td Fri Aug 10 05:53:13 2018
> @@ -1488,7 +1488,7 @@ def fobjc_weak : Flag<["-"], "fobjc-weak
> HelpText<"Enable ARC-style weak references in Objective-C">;
>
> // Objective-C ABI options.
> -def fobjc_runtime_EQ : Joined<["-"], "fobjc-runtime=">, Group<f_Group>, Flags<[CC1Option]>,
> +def fobjc_runtime_EQ : Joined<["-"], "fobjc-runtime=">, Group<f_Group>, Flags<[CC1Option, CoreOption]>,
> HelpText<"Specify the target Objective-C runtime kind and version">;
> def fobjc_abi_version_EQ : Joined<["-"], "fobjc-abi-version=">, Group<f_Group>;
> def fobjc_nonfragile_abi_version_EQ : Joined<["-"], "fobjc-nonfragile-abi-version=">, Group<f_Group>;
>
> Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=339428&r1=339427&r2=339428&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
> +++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Fri Aug 10 05:53:13 2018
> @@ -445,7 +445,7 @@ void MicrosoftCXXNameMangler::mangle(con
> mangleFunctionEncoding(FD, Context.shouldMangleDeclName(FD));
> else if (const VarDecl *VD = dyn_cast<VarDecl>(D))
> mangleVariableEncoding(VD);
> - else
> + else if (!isa<ObjCInterfaceDecl>(D))
> llvm_unreachable("Tried to mangle unexpected NamedDecl!");
> }
>
> @@ -1884,13 +1884,13 @@ void MicrosoftCXXNameMangler::mangleType
> llvm_unreachable("placeholder types shouldn't get to name mangling");
>
> case BuiltinType::ObjCId:
> - mangleArtificalTagType(TTK_Struct, "objc_object");
> + mangleArtificalTagType(TTK_Struct, ".objc_object");
> break;
> case BuiltinType::ObjCClass:
> - mangleArtificalTagType(TTK_Struct, "objc_class");
> + mangleArtificalTagType(TTK_Struct, ".objc_class");
> break;
> case BuiltinType::ObjCSel:
> - mangleArtificalTagType(TTK_Struct, "objc_selector");
> + mangleArtificalTagType(TTK_Struct, ".objc_selector");
> break;
>
> #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
> @@ -2570,9 +2570,10 @@ void MicrosoftCXXNameMangler::mangleType
>
> void MicrosoftCXXNameMangler::mangleType(const ObjCInterfaceType *T, Qualifiers,
> SourceRange) {
> - // ObjC interfaces have structs underlying them.
> + // ObjC interfaces are mangled as if they were structs with a name that is
> + // not a valid C/C++ identifier
> mangleTagTypeKind(TTK_Struct);
> - mangleName(T->getDecl());
> + mangle(T->getDecl(), ".objc_cls_");
> }
>
> void MicrosoftCXXNameMangler::mangleType(const ObjCObjectType *T, Qualifiers,
> @@ -2590,11 +2591,11 @@ void MicrosoftCXXNameMangler::mangleType
>
> Out << "?$";
> if (T->isObjCId())
> - mangleSourceName("objc_object");
> + mangleSourceName(".objc_object");
> else if (T->isObjCClass())
> - mangleSourceName("objc_class");
> + mangleSourceName(".objc_class");
> else
> - mangleSourceName(T->getInterface()->getName());
> + mangleSourceName((".objc_cls_" + T->getInterface()->getName()).str());
>
> for (const auto &Q : T->quals())
> mangleObjCProtocol(Q);
>
> Modified: cfe/trunk/lib/CodeGen/CGException.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGException.cpp?rev=339428&r1=339427&r2=339428&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGException.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGException.cpp Fri Aug 10 05:53:13 2018
> @@ -1829,7 +1829,7 @@ void CodeGenFunction::startOutlinedSEHHe
> SmallString<128> Name;
> {
> llvm::raw_svector_ostream OS(Name);
> - const FunctionDecl *ParentSEHFn = ParentCGF.CurSEHParent;
> + const NamedDecl *ParentSEHFn = ParentCGF.CurSEHParent;
> assert(ParentSEHFn && "No CurSEHParent!");
> MangleContext &Mangler = CGM.getCXXABI().getMangleContext();
> if (IsFilter)
> @@ -1972,6 +1972,11 @@ llvm::Value *CodeGenFunction::EmitSEHAbn
> return Builder.CreateZExt(&*AI, Int32Ty);
> }
>
> +void CodeGenFunction::pushSEHCleanup(CleanupKind Kind,
> + llvm::Function *FinallyFunc) {
> + EHStack.pushCleanup<PerformSEHFinally>(Kind, FinallyFunc);
> +}
> +
> void CodeGenFunction::EnterSEHTryStmt(const SEHTryStmt &S) {
> CodeGenFunction HelperCGF(CGM, /*suppressNewContext=*/true);
> if (const SEHFinallyStmt *Finally = S.getFinallyHandler()) {
>
> Modified: cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCGNU.cpp?rev=339428&r1=339427&r2=339428&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGObjCGNU.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGObjCGNU.cpp Fri Aug 10 05:53:13 2018
> @@ -18,6 +18,7 @@
> #include "CGCleanup.h"
> #include "CodeGenFunction.h"
> #include "CodeGenModule.h"
> +#include "CGCXXABI.h"
> #include "clang/CodeGen/ConstantInitBuilder.h"
> #include "clang/AST/ASTContext.h"
> #include "clang/AST/Decl.h"
> @@ -178,6 +179,9 @@ protected:
> /// runtime provides some LLVM passes that can use this to do things like
> /// automatic IMP caching and speculative inlining.
> unsigned msgSendMDKind;
> + /// Does the current target use SEH-based exceptions? False implies
> + /// Itanium-style DWARF unwinding.
> + bool usesSEHExceptions;
>
> /// Helper to check if we are targeting a specific runtime version or later.
> bool isRuntime(ObjCRuntime::Kind kind, unsigned major, unsigned minor=0) {
> @@ -217,6 +221,7 @@ protected:
> llvm::Constant *value = llvm::ConstantDataArray::getString(VMContext,Str);
> auto *GV = new llvm::GlobalVariable(TheModule, value->getType(), true,
> llvm::GlobalValue::LinkOnceODRLinkage, value, name);
> + GV->setComdat(TheModule.getOrInsertComdat(name));
> if (Private)
> GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
> ConstStr = GV;
> @@ -810,8 +815,12 @@ class CGObjCGNUstep : public CGObjCGNU {
> // Slot_t objc_slot_lookup_super(struct objc_super*, SEL);
> SlotLookupSuperFn.init(&CGM, "objc_slot_lookup_super", SlotTy,
> PtrToObjCSuperTy, SelectorTy);
> - // If we're in ObjC++ mode, then we want to make
> - if (CGM.getLangOpts().CPlusPlus) {
> + // If we're in ObjC++ mode, then we want to make
> + if (usesSEHExceptions) {
> + llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
> + // void objc_exception_rethrow(void)
> + ExceptionReThrowFn.init(&CGM, "objc_exception_rethrow", VoidTy);
> + } else if (CGM.getLangOpts().CPlusPlus) {
> llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
> // void *__cxa_begin_catch(void *e)
> EnterCatchFn.init(&CGM, "__cxa_begin_catch", PtrTy, PtrTy);
> @@ -888,22 +897,25 @@ class CGObjCGNUstep : public CGObjCGNU {
> /// This is the ABI that provides a clean break with the legacy GCC ABI and
> /// cleans up a number of things that were added to work around 1980s linkers.
> class CGObjCGNUstep2 : public CGObjCGNUstep {
> - /// The section for selectors.
> - static constexpr const char *const SelSection = "__objc_selectors";
> - /// The section for classes.
> - static constexpr const char *const ClsSection = "__objc_classes";
> - /// The section for references to classes.
> - static constexpr const char *const ClsRefSection = "__objc_class_refs";
> - /// The section for categories.
> - static constexpr const char *const CatSection = "__objc_cats";
> - /// The section for protocols.
> - static constexpr const char *const ProtocolSection = "__objc_protocols";
> - /// The section for protocol references.
> - static constexpr const char *const ProtocolRefSection = "__objc_protocol_refs";
> - /// The section for class aliases
> - static constexpr const char *const ClassAliasSection = "__objc_class_aliases";
> - /// The section for constexpr constant strings
> - static constexpr const char *const ConstantStringSection = "__objc_constant_string";
> + enum SectionKind
> + {
> + SelectorSection = 0,
> + ClassSection,
> + ClassReferenceSection,
> + CategorySection,
> + ProtocolSection,
> + ProtocolReferenceSection,
> + ClassAliasSection,
> + ConstantStringSection
> + };
> + static const char *const SectionsBaseNames[8];
> + template<SectionKind K>
> + std::string sectionName() {
> + std::string name(SectionsBaseNames[K]);
> + if (CGM.getTriple().isOSBinFormatCOFF())
> + name += "$m";
> + return name;
> + }
> /// The GCC ABI superclass message lookup function. Takes a pointer to a
> /// structure describing the receiver and the class, and a selector as
> /// arguments. Returns the IMP for the corresponding method.
> @@ -1069,7 +1081,7 @@ class CGObjCGNUstep2 : public CGObjCGNUs
> isNamed ? StringRef(StringName) : ".objc_string",
> Align, false, isNamed ? llvm::GlobalValue::LinkOnceODRLinkage
> : llvm::GlobalValue::PrivateLinkage);
> - ObjCStrGV->setSection(ConstantStringSection);
> + ObjCStrGV->setSection(sectionName<ConstantStringSection>());
> if (isNamed) {
> ObjCStrGV->setComdat(TheModule.getOrInsertComdat(StringName));
> ObjCStrGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
> @@ -1247,9 +1259,10 @@ class CGObjCGNUstep2 : public CGObjCGNUs
> assert(!TheModule.getGlobalVariable(RefName));
> // Emit a reference symbol.
> auto GV = new llvm::GlobalVariable(TheModule, ProtocolPtrTy,
> - false, llvm::GlobalValue::ExternalLinkage,
> + false, llvm::GlobalValue::LinkOnceODRLinkage,
> llvm::ConstantExpr::getBitCast(Protocol, ProtocolPtrTy), RefName);
> - GV->setSection(ProtocolRefSection);
> + GV->setComdat(TheModule.getOrInsertComdat(RefName));
> + GV->setSection(sectionName<ProtocolReferenceSection>());
> GV->setAlignment(CGM.getPointerAlign().getQuantity());
> Ref = GV;
> }
> @@ -1282,9 +1295,22 @@ class CGObjCGNUstep2 : public CGObjCGNUs
>
> EmittedProtocol = true;
>
> + auto SymName = SymbolForProtocol(ProtocolName);
> + auto *OldGV = TheModule.getGlobalVariable(SymName);
> +
> // Use the protocol definition, if there is one.
> if (const ObjCProtocolDecl *Def = PD->getDefinition())
> PD = Def;
> + else {
> + // If there is no definition, then create an external linkage symbol and
> + // hope that someone else fills it in for us (and fail to link if they
> + // don't).
> + assert(!OldGV);
> + Protocol = new llvm::GlobalVariable(TheModule, ProtocolTy,
> + /*isConstant*/false,
> + llvm::GlobalValue::ExternalLinkage, nullptr, SymName);
> + return Protocol;
> + }
>
> SmallVector<llvm::Constant*, 16> Protocols;
> for (const auto *PI : PD->protocols())
> @@ -1301,8 +1327,6 @@ class CGObjCGNUstep2 : public CGObjCGNUs
> EmitProtocolMethodList(PD->class_methods(), ClassMethodList,
> OptionalClassMethodList);
>
> - auto SymName = SymbolForProtocol(ProtocolName);
> - auto *OldGV = TheModule.getGlobalVariable(SymName);
> // The isa pointer must be set to a magic number so the runtime knows it's
> // the correct layout.
> ConstantInitBuilder builder(CGM);
> @@ -1326,7 +1350,7 @@ class CGObjCGNUstep2 : public CGObjCGNUs
>
> auto *GV = ProtocolBuilder.finishAndCreateGlobal(SymName,
> CGM.getPointerAlign(), false, llvm::GlobalValue::ExternalLinkage);
> - GV->setSection(ProtocolSection);
> + GV->setSection(sectionName<ProtocolSection>());
> GV->setComdat(TheModule.getOrInsertComdat(SymName));
> if (OldGV) {
> OldGV->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(GV,
> @@ -1359,6 +1383,7 @@ class CGObjCGNUstep2 : public CGObjCGNUs
> TypeEncoding);
> auto *GV = new llvm::GlobalVariable(TheModule, Init->getType(),
> true, llvm::GlobalValue::LinkOnceODRLinkage, Init, TypesVarName);
> + GV->setComdat(TheModule.getOrInsertComdat(TypesVarName));
> GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
> TypesGlobal = GV;
> }
> @@ -1387,12 +1412,41 @@ class CGObjCGNUstep2 : public CGObjCGNUs
> CGM.getPointerAlign(), false, llvm::GlobalValue::LinkOnceODRLinkage);
> GV->setComdat(TheModule.getOrInsertComdat(SelVarName));
> GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
> - GV->setSection(SelSection);
> + GV->setSection(sectionName<SelectorSection>());
> auto *SelVal = EnforceType(GV, SelectorTy);
> return SelVal;
> }
> + llvm::StructType *emptyStruct = nullptr;
> +
> + /// Return pointers to the start and end of a section. On ELF platforms, we
> + /// use the __start_ and __stop_ symbols that GNU-compatible linkers will set
> + /// to the start and end of section names, as long as those section names are
> + /// valid identifiers and the symbols are referenced but not defined. On
> + /// Windows, we use the fact that MSVC-compatible linkers will lexically sort
> + /// by subsections and place everything that we want to reference in a middle
> + /// subsection and then insert zero-sized symbols in subsections a and z.
> std::pair<llvm::Constant*,llvm::Constant*>
> GetSectionBounds(StringRef Section) {
> + if (CGM.getTriple().isOSBinFormatCOFF()) {
> + if (emptyStruct == nullptr) {
> + emptyStruct = llvm::StructType::create(VMContext, ".objc_section_sentinel");
> + emptyStruct->setBody({}, /*isPacked*/true);
> + }
> + auto ZeroInit = llvm::Constant::getNullValue(emptyStruct);
> + auto Sym = [&](StringRef Prefix, StringRef SecSuffix) {
> + auto *Sym = new llvm::GlobalVariable(TheModule, emptyStruct,
> + /*isConstant*/false,
> + llvm::GlobalValue::LinkOnceODRLinkage, ZeroInit, Prefix +
> + Section);
> + Sym->setVisibility(llvm::GlobalValue::HiddenVisibility);
> + Sym->setSection((Section + SecSuffix).str());
> + Sym->setComdat(TheModule.getOrInsertComdat((Prefix +
> + Section).str()));
> + Sym->setAlignment(1);
> + return Sym;
> + };
> + return { Sym("__start_", "$a"), Sym("__stop", "$z") };
> + }
> auto *Start = new llvm::GlobalVariable(TheModule, PtrTy,
> /*isConstant*/false,
> llvm::GlobalValue::ExternalLinkage, nullptr, StringRef("__start_") +
> @@ -1405,6 +1459,9 @@ class CGObjCGNUstep2 : public CGObjCGNUs
> Stop->setVisibility(llvm::GlobalValue::HiddenVisibility);
> return { Start, Stop };
> }
> + CatchTypeInfo getCatchAllTypeInfo() override {
> + return CGM.getCXXABI().getCatchAllTypeInfo();
> + }
> llvm::Function *ModuleInitFunction() override {
> llvm::Function *LoadFunction = llvm::Function::Create(
> llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), false),
> @@ -1420,19 +1477,11 @@ class CGObjCGNUstep2 : public CGObjCGNUs
> ConstantInitBuilder builder(CGM);
> auto InitStructBuilder = builder.beginStruct();
> InitStructBuilder.addInt(Int64Ty, 0);
> - auto addSection = [&](const char *section) {
> - auto bounds = GetSectionBounds(section);
> + for (auto *s : SectionsBaseNames) {
> + auto bounds = GetSectionBounds(s);
> InitStructBuilder.add(bounds.first);
> InitStructBuilder.add(bounds.second);
> };
> - addSection(SelSection);
> - addSection(ClsSection);
> - addSection(ClsRefSection);
> - addSection(CatSection);
> - addSection(ProtocolSection);
> - addSection(ProtocolRefSection);
> - addSection(ClassAliasSection);
> - addSection(ConstantStringSection);
> auto *InitStruct = InitStructBuilder.finishAndCreateGlobal(".objc_init",
> CGM.getPointerAlign(), false, llvm::GlobalValue::LinkOnceODRLinkage);
> InitStruct->setVisibility(llvm::GlobalValue::HiddenVisibility);
> @@ -1451,18 +1500,23 @@ class CGObjCGNUstep2 : public CGObjCGNUs
> // Check that this hasn't been renamed. This shouldn't happen, because
> // this function should be called precisely once.
> assert(InitVar->getName() == ".objc_ctor");
> - InitVar->setSection(".ctors");
> + // In Windows, initialisers are sorted by the suffix. XCL is for library
> + // initialisers, which run before user initialisers. We are running
> + // Objective-C loads at the end of library load. This means +load methods
> + // will run before any other static constructors, but that static
> + // constructors can see a fully initialised Objective-C state.
> + if (CGM.getTriple().isOSBinFormatCOFF())
> + InitVar->setSection(".CRT$XCLz");
> + else
> + InitVar->setSection(".ctors");
> InitVar->setVisibility(llvm::GlobalValue::HiddenVisibility);
> InitVar->setComdat(TheModule.getOrInsertComdat(".objc_ctor"));
> - CGM.addCompilerUsedGlobal(InitVar);
> + CGM.addUsedGlobal(InitVar);
> for (auto *C : Categories) {
> auto *Cat = cast<llvm::GlobalVariable>(C->stripPointerCasts());
> - Cat->setSection(CatSection);
> + Cat->setSection(sectionName<CategorySection>());
> CGM.addUsedGlobal(Cat);
> }
> - // Add a null value fore each special section so that we can always
> - // guarantee that the _start and _stop symbols will exist and be
> - // meaningful.
> auto createNullGlobal = [&](StringRef Name, ArrayRef<llvm::Constant*> Init,
> StringRef Section) {
> auto nullBuilder = builder.beginStruct();
> @@ -1476,38 +1530,48 @@ class CGObjCGNUstep2 : public CGObjCGNUs
> CGM.addUsedGlobal(GV);
> return GV;
> };
> - createNullGlobal(".objc_null_selector", {NULLPtr, NULLPtr}, SelSection);
> - if (Categories.empty())
> - createNullGlobal(".objc_null_category", {NULLPtr, NULLPtr,
> - NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr}, CatSection);
> - if (!EmittedClass) {
> - createNullGlobal(".objc_null_cls_init_ref", NULLPtr, ClsSection);
> - createNullGlobal(".objc_null_class_ref", { NULLPtr, NULLPtr },
> - ClsRefSection);
> - }
> - if (!EmittedProtocol)
> - createNullGlobal(".objc_null_protocol", {NULLPtr, NULLPtr, NULLPtr,
> - NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr,
> - NULLPtr}, ProtocolSection);
> - if (!EmittedProtocolRef)
> - createNullGlobal(".objc_null_protocol_ref", {NULLPtr}, ProtocolRefSection);
> - if (!ClassAliases.empty())
> - for (auto clsAlias : ClassAliases)
> - createNullGlobal(std::string(".objc_class_alias") +
> - clsAlias.second, { MakeConstantString(clsAlias.second),
> - GetClassVar(clsAlias.first) }, ClassAliasSection);
> - else
> - createNullGlobal(".objc_null_class_alias", { NULLPtr, NULLPtr },
> - ClassAliasSection);
> - if (ConstantStrings.empty()) {
> - auto i32Zero = llvm::ConstantInt::get(Int32Ty, 0);
> - createNullGlobal(".objc_null_constant_string", { NULLPtr, i32Zero,
> - i32Zero, i32Zero, i32Zero, NULLPtr }, ConstantStringSection);
> + for (auto clsAlias : ClassAliases)
> + createNullGlobal(std::string(".objc_class_alias") +
> + clsAlias.second, { MakeConstantString(clsAlias.second),
> + GetClassVar(clsAlias.first) }, sectionName<ClassAliasSection>());
> + // On ELF platforms, add a null value for each special section so that we
> + // can always guarantee that the _start and _stop symbols will exist and be
> + // meaningful. This is not required on COFF platforms, where our start and
> + // stop symbols will create the section.
> + if (!CGM.getTriple().isOSBinFormatCOFF()) {
> + createNullGlobal(".objc_null_selector", {NULLPtr, NULLPtr},
> + sectionName<SelectorSection>());
> + if (Categories.empty())
> + createNullGlobal(".objc_null_category", {NULLPtr, NULLPtr,
> + NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr},
> + sectionName<CategorySection>());
> + if (!EmittedClass) {
> + createNullGlobal(".objc_null_cls_init_ref", NULLPtr,
> + sectionName<ClassReferenceSection>());
> + createNullGlobal(".objc_null_class_ref", { NULLPtr, NULLPtr },
> + sectionName<ClassReferenceSection>());
> + }
> + if (!EmittedProtocol)
> + createNullGlobal(".objc_null_protocol", {NULLPtr, NULLPtr, NULLPtr,
> + NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr,
> + NULLPtr}, sectionName<ProtocolSection>());
> + if (!EmittedProtocolRef)
> + createNullGlobal(".objc_null_protocol_ref", {NULLPtr},
> + sectionName<ProtocolReferenceSection>());
> + if (ClassAliases.empty())
> + createNullGlobal(".objc_null_class_alias", { NULLPtr, NULLPtr },
> + sectionName<ClassAliasSection>());
> + if (ConstantStrings.empty()) {
> + auto i32Zero = llvm::ConstantInt::get(Int32Ty, 0);
> + createNullGlobal(".objc_null_constant_string", { NULLPtr, i32Zero,
> + i32Zero, i32Zero, i32Zero, NULLPtr },
> + sectionName<ConstantStringSection>());
> + }
> }
> ConstantStrings.clear();
> Categories.clear();
> Classes.clear();
> - return nullptr;//CGObjCGNU::ModuleInitFunction();
> + return nullptr;
> }
> /// In the v2 ABI, ivar offset variables use the type encoding in their name
> /// to trigger linker failures if the types don't match.
> @@ -1774,7 +1838,7 @@ class CGObjCGNUstep2 : public CGObjCGNUs
> }
>
> auto *classRefSymbol = GetClassVar(className);
> - classRefSymbol->setSection(ClsRefSection);
> + classRefSymbol->setSection(sectionName<ClassReferenceSection>());
> classRefSymbol->setInitializer(llvm::ConstantExpr::getBitCast(classStruct, IdTy));
>
>
> @@ -1805,7 +1869,7 @@ class CGObjCGNUstep2 : public CGObjCGNUs
> auto classInitRef = new llvm::GlobalVariable(TheModule,
> classStruct->getType(), false, llvm::GlobalValue::ExternalLinkage,
> classStruct, "._OBJC_INIT_CLASS_" + className);
> - classInitRef->setSection(ClsSection);
> + classInitRef->setSection(sectionName<ClassSection>());
> CGM.addUsedGlobal(classInitRef);
>
> EmittedClass = true;
> @@ -1829,6 +1893,18 @@ class CGObjCGNUstep2 : public CGObjCGNUs
>
> };
>
> +const char *const CGObjCGNUstep2::SectionsBaseNames[8] =
> +{
> +"__objc_selectors",
> +"__objc_classes",
> +"__objc_class_refs",
> +"__objc_cats",
> +"__objc_protocols",
> +"__objc_protocol_refs",
> +"__objc_class_aliases",
> +"__objc_constant_string"
> +};
> +
> /// Support for the ObjFW runtime.
> class CGObjCObjFW: public CGObjCGNU {
> protected:
> @@ -1931,6 +2007,8 @@ CGObjCGNU::CGObjCGNU(CodeGenModule &cgm,
> ProtocolVersion(protocolClassVersion), ClassABIVersion(classABI) {
>
> msgSendMDKind = VMContext.getMDKindID("GNUObjCMessageSend");
> + usesSEHExceptions =
> + cgm.getContext().getTargetInfo().getTriple().isWindowsMSVCEnvironment();
>
> CodeGenTypes &Types = CGM.getTypes();
> IntTy = cast<llvm::IntegerType>(
> @@ -2186,6 +2264,9 @@ llvm::Constant *CGObjCGNU::GetEHType(Qua
> }
>
> llvm::Constant *CGObjCGNUstep::GetEHType(QualType T) {
> + if (usesSEHExceptions)
> + return CGM.getCXXABI().getAddrOfRTTIDescriptor(T);
> +
> if (!CGM.getLangOpts().CPlusPlus)
> return CGObjCGNU::GetEHType(T);
>
> @@ -3726,6 +3807,7 @@ void CGObjCGNU::EmitThrowStmt(CodeGenFun
> const ObjCAtThrowStmt &S,
> bool ClearInsertionPoint) {
> llvm::Value *ExceptionAsObject;
> + bool isRethrow = false;
>
> if (const Expr *ThrowExpr = S.getThrowExpr()) {
> llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
> @@ -3734,11 +3816,24 @@ void CGObjCGNU::EmitThrowStmt(CodeGenFun
> assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
> "Unexpected rethrow outside @catch block.");
> ExceptionAsObject = CGF.ObjCEHValueStack.back();
> + isRethrow = true;
> + }
> + if (isRethrow && usesSEHExceptions) {
> + // For SEH, ExceptionAsObject may be undef, because the catch handler is
> + // not passed it for catchalls and so it is not visible to the catch
> + // funclet. The real thrown object will still be live on the stack at this
> + // point and will be rethrown. If we are explicitly rethrowing the object
> + // that was passed into the `@catch` block, then this code path is not
> + // reached and we will instead call `objc_exception_throw` with an explicit
> + // argument.
> + CGF.EmitRuntimeCallOrInvoke(ExceptionReThrowFn).setDoesNotReturn();
> + }
> + else {
> + ExceptionAsObject = CGF.Builder.CreateBitCast(ExceptionAsObject, IdTy);
> + llvm::CallSite Throw =
> + CGF.EmitRuntimeCallOrInvoke(ExceptionThrowFn, ExceptionAsObject);
> + Throw.setDoesNotReturn();
> }
> - ExceptionAsObject = CGF.Builder.CreateBitCast(ExceptionAsObject, IdTy);
> - llvm::CallSite Throw =
> - CGF.EmitRuntimeCallOrInvoke(ExceptionThrowFn, ExceptionAsObject);
> - Throw.setDoesNotReturn();
> CGF.Builder.CreateUnreachable();
> if (ClearInsertionPoint)
> CGF.Builder.ClearInsertionPoint();
>
> Modified: cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp?rev=339428&r1=339427&r2=339428&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp Fri Aug 10 05:53:13 2018
> @@ -15,6 +15,7 @@
>
> #include "CGObjCRuntime.h"
> #include "CGCleanup.h"
> +#include "CGCXXABI.h"
> #include "CGRecordLayout.h"
> #include "CodeGenFunction.h"
> #include "CodeGenModule.h"
> @@ -22,6 +23,7 @@
> #include "clang/AST/StmtObjC.h"
> #include "clang/CodeGen/CGFunctionInfo.h"
> #include "llvm/IR/CallSite.h"
> +#include "llvm/Support/SaveAndRestore.h"
>
> using namespace clang;
> using namespace CodeGen;
> @@ -120,6 +122,8 @@ namespace {
> const Stmt *Body;
> llvm::BasicBlock *Block;
> llvm::Constant *TypeInfo;
> + /// Flags used to differentiate cleanups and catchalls in Windows SEH
> + unsigned Flags;
> };
>
> struct CallObjCEndCatch final : EHScopeStack::Cleanup {
> @@ -148,13 +152,17 @@ void CGObjCRuntime::EmitTryCatchStmt(Cod
> if (S.getNumCatchStmts())
> Cont = CGF.getJumpDestInCurrentScope("eh.cont");
>
> + bool useFunclets = EHPersonality::get(CGF).usesFuncletPads();
> +
> CodeGenFunction::FinallyInfo FinallyInfo;
> - if (const ObjCAtFinallyStmt *Finally = S.getFinallyStmt())
> - FinallyInfo.enter(CGF, Finally->getFinallyBody(),
> - beginCatchFn, endCatchFn, exceptionRethrowFn);
> + if (!useFunclets)
> + if (const ObjCAtFinallyStmt *Finally = S.getFinallyStmt())
> + FinallyInfo.enter(CGF, Finally->getFinallyBody(),
> + beginCatchFn, endCatchFn, exceptionRethrowFn);
>
> SmallVector<CatchHandler, 8> Handlers;
>
> +
> // Enter the catch, if there is one.
> if (S.getNumCatchStmts()) {
> for (unsigned I = 0, N = S.getNumCatchStmts(); I != N; ++I) {
> @@ -166,10 +174,13 @@ void CGObjCRuntime::EmitTryCatchStmt(Cod
> Handler.Variable = CatchDecl;
> Handler.Body = CatchStmt->getCatchBody();
> Handler.Block = CGF.createBasicBlock("catch");
> + Handler.Flags = 0;
>
> // @catch(...) always matches.
> if (!CatchDecl) {
> - Handler.TypeInfo = nullptr; // catch-all
> + auto catchAll = getCatchAllTypeInfo();
> + Handler.TypeInfo = catchAll.RTTI;
> + Handler.Flags = catchAll.Flags;
> // Don't consider any other catches.
> break;
> }
> @@ -179,9 +190,31 @@ void CGObjCRuntime::EmitTryCatchStmt(Cod
>
> EHCatchScope *Catch = CGF.EHStack.pushCatch(Handlers.size());
> for (unsigned I = 0, E = Handlers.size(); I != E; ++I)
> - Catch->setHandler(I, Handlers[I].TypeInfo, Handlers[I].Block);
> + Catch->setHandler(I, { Handlers[I].TypeInfo, Handlers[I].Flags }, Handlers[I].Block);
> }
>
> + if (useFunclets)
> + if (const ObjCAtFinallyStmt *Finally = S.getFinallyStmt()) {
> + CodeGenFunction HelperCGF(CGM, /*suppressNewContext=*/true);
> + if (!CGF.CurSEHParent)
> + CGF.CurSEHParent = cast<NamedDecl>(CGF.CurFuncDecl);
> + // Outline the finally block.
> + const Stmt *FinallyBlock = Finally->getFinallyBody();
> + HelperCGF.startOutlinedSEHHelper(CGF, /*isFilter*/false, FinallyBlock);
> +
> + // Emit the original filter expression, convert to i32, and return.
> + HelperCGF.EmitStmt(FinallyBlock);
> +
> + HelperCGF.FinishFunction(FinallyBlock->getLocEnd());
> +
> + llvm::Function *FinallyFunc = HelperCGF.CurFn;
> +
> +
> + // Push a cleanup for __finally blocks.
> + CGF.pushSEHCleanup(NormalAndEHCleanup, FinallyFunc);
> + }
> +
> +
> // Emit the try body.
> CGF.EmitStmt(S.getTryBody());
>
> @@ -197,6 +230,13 @@ void CGObjCRuntime::EmitTryCatchStmt(Cod
> CatchHandler &Handler = Handlers[I];
>
> CGF.EmitBlock(Handler.Block);
> + llvm::CatchPadInst *CPI = nullptr;
> + SaveAndRestore<llvm::Instruction *> RestoreCurrentFuncletPad(CGF.CurrentFuncletPad);
> + if (useFunclets)
> + if ((CPI = dyn_cast_or_null<llvm::CatchPadInst>(Handler.Block->getFirstNonPHI()))) {
> + CGF.CurrentFuncletPad = CPI;
> + CPI->setOperand(2, CGF.getExceptionSlot().getPointer());
> + }
> llvm::Value *RawExn = CGF.getExceptionFromSlot();
>
> // Enter the catch.
> @@ -223,6 +263,8 @@ void CGObjCRuntime::EmitTryCatchStmt(Cod
> CGF.EmitAutoVarDecl(*CatchParam);
> EmitInitOfCatchParam(CGF, CastExn, CatchParam);
> }
> + if (CPI)
> + CGF.EHStack.pushCleanup<CatchRetScope>(NormalCleanup, CPI);
>
> CGF.ObjCEHValueStack.push_back(Exn);
> CGF.EmitStmt(Handler.Body);
> @@ -232,13 +274,13 @@ void CGObjCRuntime::EmitTryCatchStmt(Cod
> cleanups.ForceCleanup();
>
> CGF.EmitBranchThroughCleanup(Cont);
> - }
> + }
>
> // Go back to the try-statement fallthrough.
> CGF.Builder.restoreIP(SavedIP);
>
> // Pop out of the finally.
> - if (S.getFinallyStmt())
> + if (!useFunclets && S.getFinallyStmt())
> FinallyInfo.exit(CGF);
>
> if (Cont.isValid())
> @@ -277,7 +319,7 @@ namespace {
> : SyncExitFn(SyncExitFn), SyncArg(SyncArg) {}
>
> void Emit(CodeGenFunction &CGF, Flags flags) override {
> - CGF.Builder.CreateCall(SyncExitFn, SyncArg)->setDoesNotThrow();
> + CGF.EmitNounwindRuntimeCall(SyncExitFn, SyncArg);
> }
> };
> }
>
> Modified: cfe/trunk/lib/CodeGen/CGObjCRuntime.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCRuntime.h?rev=339428&r1=339427&r2=339428&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGObjCRuntime.h (original)
> +++ cfe/trunk/lib/CodeGen/CGObjCRuntime.h Fri Aug 10 05:53:13 2018
> @@ -17,6 +17,7 @@
> #define LLVM_CLANG_LIB_CODEGEN_CGOBJCRUNTIME_H
> #include "CGBuilder.h"
> #include "CGCall.h"
> +#include "CGCleanup.h"
> #include "CGValue.h"
> #include "clang/AST/DeclObjC.h"
> #include "clang/Basic/IdentifierTable.h" // Selector
> @@ -141,6 +142,8 @@ public:
> /// error to Sema.
> virtual llvm::Constant *GetEHType(QualType T) = 0;
>
> + virtual CatchTypeInfo getCatchAllTypeInfo() { return { nullptr, 0 }; }
> +
> /// Generate a constant string object.
> virtual ConstantAddress GenerateConstantString(const StringLiteral *) = 0;
>
>
> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=339428&r1=339427&r2=339428&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Fri Aug 10 05:53:13 2018
> @@ -470,7 +470,7 @@ public:
> /// potentially set the return value.
> bool SawAsmBlock = false;
>
> - const FunctionDecl *CurSEHParent = nullptr;
> + const NamedDecl *CurSEHParent = nullptr;
>
> /// True if the current function is an outlined SEH helper. This can be a
> /// finally block or filter expression.
> @@ -2878,6 +2878,8 @@ public:
> void EnterSEHTryStmt(const SEHTryStmt &S);
> void ExitSEHTryStmt(const SEHTryStmt &S);
>
> + void pushSEHCleanup(CleanupKind kind,
> + llvm::Function *FinallyFunc);
> void startOutlinedSEHHelper(CodeGenFunction &ParentCGF, bool IsFilter,
> const Stmt *OutlinedStmt);
>
>
> Modified: cfe/trunk/lib/Driver/ToolChains/Clang.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Clang.cpp?rev=339428&r1=339427&r2=339428&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Driver/ToolChains/Clang.cpp (original)
> +++ cfe/trunk/lib/Driver/ToolChains/Clang.cpp Fri Aug 10 05:53:13 2018
> @@ -4915,7 +4915,8 @@ ObjCRuntime Clang::AddObjCRuntimeArgs(co
> }
> if ((runtime.getKind() == ObjCRuntime::GNUstep) &&
> (runtime.getVersion() >= VersionTuple(2, 0)))
> - if (!getToolChain().getTriple().isOSBinFormatELF()) {
> + if (!getToolChain().getTriple().isOSBinFormatELF() &&
> + !getToolChain().getTriple().isOSBinFormatCOFF()) {
> getToolChain().getDriver().Diag(
> diag::err_drv_gnustep_objc_runtime_incompatible_binary)
> << runtime.getVersion().getMajor();
>
> Modified: cfe/trunk/test/CodeGenObjC/gnu-init.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/gnu-init.m?rev=339428&r1=339427&r2=339428&view=diff
> ==============================================================================
> --- cfe/trunk/test/CodeGenObjC/gnu-init.m (original)
> +++ cfe/trunk/test/CodeGenObjC/gnu-init.m Fri Aug 10 05:53:13 2018
> @@ -1,4 +1,5 @@
> // RUN: %clang_cc1 -triple x86_64-unknown-freebsd -S -emit-llvm -fobjc-runtime=gnustep-2.0 -o - %s | FileCheck %s -check-prefix=CHECK-NEW
> +// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -S -emit-llvm -fobjc-runtime=gnustep-2.0 -o - %s | FileCheck %s -check-prefix=CHECK-WIN
> // RUN: %clang_cc1 -triple x86_64-unknown-freebsd -S -emit-llvm -fobjc-runtime=gnustep-1.8 -o - %s | FileCheck %s -check-prefix=CHECK-OLD
>
> // Almost minimal Objective-C file, check that it emits calls to the correct
> @@ -49,9 +50,9 @@
> // CHECK-NEW: @.objc_null_class_alias = linkonce_odr hidden global { i8*, i8* } zeroinitializer, section "__objc_class_aliases", comdat, align 8
> // CHECK-NEW: @.objc_null_constant_string = linkonce_odr hidden global { i8*, i32, i32, i32, i32, i8* } zeroinitializer, section "__objc_constant_string", comdat, align 8
> // Make sure that the null symbols are not going to be removed, even by linking.
> -// CHECK-NEW: @llvm.used = appending global [7 x i8*] [i8* bitcast ({ { i8*, i8*, i8*, i64, i64, i64, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i64, i8* }*, i8*, i8*, i64, i64, i64, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i64, i8* }** @._OBJC_INIT_CLASS_X to i8*), i8* bitcast ({ i8*, i8* }* @.objc_null_selector to i8*), i8* bitcast ({ i8*, i8*, i8*, i8*, i8*, i8*, i8* }* @.objc_null_category to i8*), i8* bitcast ({ i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8* }* @.objc_null_protocol to i8*), i8* bitcast ({ i8* }* @.objc_null_protocol_ref to i8*), i8* bitcast ({ i8*, i8* }* @.objc_null_class_alias to i8*), i8* bitcast ({ i8*, i32, i32, i32, i32, i8* }* @.objc_null_constant_string to i8*)], section "llvm.metadata"
> +// CHECK-NEW: @llvm.used = appending global [8 x i8*] [i8* bitcast ({ { i8*, i8*, i8*, i64, i64, i64, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i64, i8* }*, i8*, i8*, i64, i64, i64, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i64, i8* }** @._OBJC_INIT_CLASS_X to i8*), i8* bitcast (void ()** @.objc_ctor to i8*), i8* bitcast ({ i8*, i8* }* @.objc_null_selector to i8*), i8* bitcast ({ i8*, i8*, i8*, i8*, i8*, i8*, i8* }* @.objc_null_category to i8*), i8* bitcast ({ i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8* }* @.objc_null_protocol to i8*), i8* bitcast ({ i8* }* @.objc_null_protocol_ref to i8*), i8* bitcast ({ i8*, i8* }* @.objc_null_class_alias to i8*), i8* bitcast ({ i8*, i32, i32, i32, i32, i8* }* @.objc_null_constant_string to i8*)], section "llvm.metadata"
> // Make sure that the load function and the reference to it are marked as used.
> -// CHECK-NEW: @llvm.compiler.used = appending global [2 x i8*] [i8* bitcast (void ()* @.objcv2_load_function to i8*), i8* bitcast (void ()** @.objc_ctor to i8*)], section "llvm.metadata"
> +// CHECK-NEW: @llvm.compiler.used = appending global [1 x i8*] [i8* bitcast (void ()* @.objcv2_load_function to i8*)], section "llvm.metadata"
>
> // Check that we emit the load function in a comdat and that it does the right thing.
> // CHECK-NEW: define linkonce_odr hidden void @.objcv2_load_function() comdat {
> @@ -67,3 +68,37 @@
> // CHECK-OLD-NEXT: entry:
> // CHECK-OLD-NEXT: call void ({ i64, i64, i8*, { i64, { i8*, i8* }*, i16, i16, [4 x i8*] }* }*, ...) @__objc_exec_class({ i64, i64, i8*, { i64, { i8*, i8* }*, i16, i16, [4 x i8*] }* }* @4)
>
> +
> +
> +// Make sure all of our section boundary variables are emitted correctly.
> +// CHECK-WIN: @__start___objc_selectors = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_selectors$a", comdat, align 1
> +// CHECK-WIN: @__stop__objc_selectors = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_selectors$z", comdat, align 1
> +// CHECK-WIN: @__start___objc_classes = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_classes$a", comdat, align 1
> +// CHECK-WIN: @__stop__objc_classes = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_classes$z", comdat, align 1
> +// CHECK-WIN: @__start___objc_class_refs = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_class_refs$a", comdat, align 1
> +// CHECK-WIN: @__stop__objc_class_refs = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_class_refs$z", comdat, align 1
> +// CHECK-WIN: @__start___objc_cats = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_cats$a", comdat, align 1
> +// CHECK-WIN: @__stop__objc_cats = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_cats$z", comdat, align 1
> +// CHECK-WIN: @__start___objc_protocols = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_protocols$a", comdat, align 1
> +// CHECK-WIN: @__stop__objc_protocols = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_protocols$z", comdat, align 1
> +// CHECK-WIN: @__start___objc_protocol_refs = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_protocol_refs$a", comdat, align 1
> +// CHECK-WIN: @__stop__objc_protocol_refs = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_protocol_refs$z", comdat, align 1
> +// CHECK-WIN: @__start___objc_class_aliases = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_class_aliases$a", comdat, align 1
> +// CHECK-WIN: @__stop__objc_class_aliases = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_class_aliases$z", comdat, align 1
> +// CHECK-WIN: @__start___objc_constant_string = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_constant_string$a", comdat, align 1
> +// CHECK-WIN: @__stop__objc_constant_string = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_constant_string$z", comdat, align 1
> +// CHECK-WIN: @.objc_init = linkonce_odr hidden global { i64, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel* } { i64 0, %.objc_section_sentinel* @__start___objc_selectors, %.objc_section_sentinel* @__stop__objc_selectors, %.objc_section_sentinel* @__start___objc_classes, %.objc_section_sentinel* @__stop__objc_classes, %.objc_section_sentinel* @__start___objc_class_refs, %.objc_section_sentinel* @__stop__objc_class_refs, %.objc_section_sentinel* @__start___objc_cats, %.objc_section_sentinel* @__stop__objc_cats, %.objc_section_sentinel* @__start___objc_protocols, %.objc_section_sentinel* @__stop__objc_protocols, %.objc_section_sentinel* @__start___objc_protocol_refs, %.objc_section_sentinel* @__stop__objc_protocol_refs, %.objc_section_sentinel* @__start___objc_class_aliases, %.objc_section_sentinel* @__stop__objc_class_aliases, %.objc_section_sentinel* @__start___objc_constant_string, %.objc_section_sentinel* @__stop__objc_constant_string }, comdat, align 8
> +
> +// Make sure our init variable is in the correct section for late library init.
> +// CHECK-WIN: @.objc_ctor = linkonce hidden constant void ()* @.objcv2_load_function, section ".CRT$XCLz", comdat
> +
> +// We shouldn't have emitted any null placeholders on Windows.
> +// CHECK-WIN: @llvm.used = appending global [2 x i8*] [i8* bitcast ({ { i8*, i8*, i8*, i32, i32, i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i32, i8* }*, i8*, i8*, i32, i32, i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i32, i8* }** @._OBJC_INIT_CLASS_X to i8*), i8* bitcast (void ()** @.objc_ctor to i8*)], section "llvm.metadata"
> +// CHECK-WIN: @llvm.compiler.used = appending global [1 x i8*] [i8* bitcast (void ()* @.objcv2_load_function to i8*)], section "llvm.metadata"
> +
> +// Check our load function is in a comdat.
> +// CHECK-WIN: define linkonce_odr hidden void @.objcv2_load_function() comdat {
> +
> +// Make sure we have dllimport on the load function
> +// CHECK-WIN: declare dllimport void @__objc_load
> +
>
> Modified: cfe/trunk/test/CodeGenObjC/gnustep2-proto.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/gnustep2-proto.m?rev=339428&r1=339427&r2=339428&view=diff
> ==============================================================================
> --- cfe/trunk/test/CodeGenObjC/gnustep2-proto.m (original)
> +++ cfe/trunk/test/CodeGenObjC/gnustep2-proto.m Fri Aug 10 05:53:13 2018
> @@ -22,11 +22,11 @@
>
> // Check that we're emitting the protocol and a correctly initialised
> // indirection variable.
> -// CHECK: @._OBJC_PROTOCOL_X = global
> +// CHECK: @._OBJC_PROTOCOL_X = global
> // CHECK-SAME: , section "__objc_protocols", comdat, align 8
> -// CHECK: @._OBJC_REF_PROTOCOL_X = global
> +// CHECK: @._OBJC_REF_PROTOCOL_X = linkonce_odr global
> // CHECK-SAME: @._OBJC_PROTOCOL_X
> -// CHECK-SAME: , section "__objc_protocol_refs", align 8
> +// CHECK-SAME: , section "__objc_protocol_refs", comdat, align 8
>
>
> // Check that we load from the indirection variable on protocol references.
>
> Modified: cfe/trunk/test/CodeGenObjCXX/arc-marker-funclet.mm
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/arc-marker-funclet.mm?rev=339428&r1=339427&r2=339428&view=diff
> ==============================================================================
> --- cfe/trunk/test/CodeGenObjCXX/arc-marker-funclet.mm (original)
> +++ cfe/trunk/test/CodeGenObjCXX/arc-marker-funclet.mm Fri Aug 10 05:53:13 2018
> @@ -10,7 +10,7 @@ void g() {
> }
> }
>
> -// CHECK: call i8* @"?f@@YAPAUobjc_object@@XZ"() [ "funclet"(token %1) ]
> +// CHECK: call i8* @"?f@@YAPAU.objc_object@@XZ"() [ "funclet"(token %1) ]
> // CHECK-NEXT: call void asm sideeffect "movl{{.*}}%ebp, %ebp{{.*}}", ""() [ "funclet"(token %1) ]
>
> // The corresponding f() call was invoked from the entry basic block.
>
> Modified: cfe/trunk/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm?rev=339428&r1=339427&r2=339428&view=diff
> ==============================================================================
> --- cfe/trunk/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm (original)
> +++ cfe/trunk/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm Fri Aug 10 05:53:13 2018
> @@ -9,7 +9,7 @@ struct A {
>
> // Verify that we destruct things from left to right in the MS C++ ABI: a, b, c, d.
> //
> -// CHECK-LABEL: define dso_local void @"?test_arc_order@@YAXUA@@PAUobjc_object@@01 at Z"
> +// CHECK-LABEL: define dso_local void @"?test_arc_order@@YAXUA@@PAU.objc_object@@01 at Z"
> // CHECK: (<{ %struct.A, i8*, %struct.A, i8* }>* inalloca)
> void test_arc_order(A a, id __attribute__((ns_consumed)) b , A c, id __attribute__((ns_consumed)) d) {
> // CHECK: call x86_thiscallcc void @"??1A@@QAE at XZ"(%struct.A* %{{.*}})
>
> Modified: cfe/trunk/test/CodeGenObjCXX/msabi-objc-extensions.mm
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/msabi-objc-extensions.mm?rev=339428&r1=339427&r2=339428&view=diff
> ==============================================================================
> --- cfe/trunk/test/CodeGenObjCXX/msabi-objc-extensions.mm (original)
> +++ cfe/trunk/test/CodeGenObjCXX/msabi-objc-extensions.mm Fri Aug 10 05:53:13 2018
> @@ -6,61 +6,61 @@
> @class I;
>
> void f(id<P>, id, id<P>, id) {}
> -// CHECK-LABEL: "?f@@YAXPAU?$objc_object at U?$Protocol at UP@@@__ObjC@@@@PAUobjc_object@@01 at Z"
> +// CHECK-LABEL: "?f@@YAXPAU?$.objc_object at U?$Protocol at UP@@@__ObjC@@@@PAU.objc_object@@01 at Z"
>
> void f(id, id<P>, id<P>, id) {}
> -// CHECK-LABEL: "?f@@YAXPAUobjc_object@@PAU?$objc_object at U?$Protocol at UP@@@__ObjC@@@@10 at Z"
> +// CHECK-LABEL: "?f@@YAXPAU.objc_object@@PAU?$.objc_object at U?$Protocol at UP@@@__ObjC@@@@10 at Z"
>
> void f(id<P>, id<P>) {}
> -// CHECK-LABEL: "?f@@YAXPAU?$objc_object at U?$Protocol at UP@@@__ObjC@@@@0 at Z"
> +// CHECK-LABEL: "?f@@YAXPAU?$.objc_object at U?$Protocol at UP@@@__ObjC@@@@0 at Z"
>
> void f(id<P>) {}
> -// CHECK-LABEL: "?f@@YAXPAU?$objc_object at U?$Protocol at UP@@@__ObjC@@@@@Z"
> +// CHECK-LABEL: "?f@@YAXPAU?$.objc_object at U?$Protocol at UP@@@__ObjC@@@@@Z"
>
> void f(id<P, Q>) {}
> -// CHECK-LABEL: "?f@@YAXPAU?$objc_object at U?$Protocol at UP@@@__ObjC@@U?$Protocol at UQ@@@2@@@@Z"
> +// CHECK-LABEL: "?f@@YAXPAU?$.objc_object at U?$Protocol at UP@@@__ObjC@@U?$Protocol at UQ@@@2@@@@Z"
>
> void f(Class<P>) {}
> -// CHECK-LABEL: "?f@@YAXPAU?$objc_class at U?$Protocol at UP@@@__ObjC@@@@@Z"
> +// CHECK-LABEL: "?f@@YAXPAU?$.objc_class at U?$Protocol at UP@@@__ObjC@@@@@Z"
>
> void f(Class<P, Q>) {}
> -// CHECK-LABEL: "?f@@YAXPAU?$objc_class at U?$Protocol at UP@@@__ObjC@@U?$Protocol at UQ@@@2@@@@Z"
> +// CHECK-LABEL: "?f@@YAXPAU?$.objc_class at U?$Protocol at UP@@@__ObjC@@U?$Protocol at UQ@@@2@@@@Z"
>
> void f(I<P> *) {}
> -// CHECK-LABEL: "?f@@YAXPAU?$I at U?$Protocol at UP@@@__ObjC@@@@@Z"
> +// CHECK-LABEL: "?f@@YAXPAU?$.objc_cls_I at U?$Protocol at UP@@@__ObjC@@@@@Z"
>
> void f(I<P, Q> *) {}
> -// CHECK-LABEL: "?f@@YAXPAU?$I at U?$Protocol at UP@@@__ObjC@@U?$Protocol at UQ@@@2@@@@Z"
> +// CHECK-LABEL: "?f@@YAXPAU?$.objc_cls_I at U?$Protocol at UP@@@__ObjC@@U?$Protocol at UQ@@@2@@@@Z"
>
> template <typename>
> struct S {};
>
> void f(S<__unsafe_unretained id>) {}
> -// CHECK-LABEL: "?f@@YAXU?$S at PAUobjc_object@@@@@Z"
> +// CHECK-LABEL: "?f@@YAXU?$S at PAU.objc_object@@@@@Z"
>
> void f(S<__autoreleasing id>) {}
> -// CHECK-LABEL: "?f@@YAXU?$S at U?$Autoreleasing at PAUobjc_object@@@__ObjC@@@@@Z"
> +// CHECK-LABEL: "?f@@YAXU?$S at U?$Autoreleasing at PAU.objc_object@@@__ObjC@@@@@Z"
>
> void f(S<__strong id>) {}
> -// CHECK-LABEL: "?f@@YAXU?$S at U?$Strong at PAUobjc_object@@@__ObjC@@@@@Z"
> +// CHECK-LABEL: "?f@@YAXU?$S at U?$Strong at PAU.objc_object@@@__ObjC@@@@@Z"
>
> void f(S<__weak id>) {}
> -// CHECK-LABEL: "?f@@YAXU?$S at U?$Weak at PAUobjc_object@@@__ObjC@@@@@Z"
> +// CHECK-LABEL: "?f@@YAXU?$S at U?$Weak at PAU.objc_object@@@__ObjC@@@@@Z"
>
> void w(__weak id) {}
> -// CHECK-LABEL: "?w@@YAXPAUobjc_object@@@Z"
> +// CHECK-LABEL: "?w@@YAXPAU.objc_object@@@Z"
>
> void s(__strong id) {}
> -// CHECK-LABEL: "?s@@YAXPAUobjc_object@@@Z"
> +// CHECK-LABEL: "?s@@YAXPAU.objc_object@@@Z"
>
> void a(__autoreleasing id) {}
> -// CHECK-LABEL: "?a@@YAXPAUobjc_object@@@Z"
> +// CHECK-LABEL: "?a@@YAXPAU.objc_object@@@Z"
>
> void u(__unsafe_unretained id) {}
> -// CHECK-LABEL: "?u@@YAXPAUobjc_object@@@Z"
> +// CHECK-LABEL: "?u@@YAXPAU.objc_object@@@Z"
>
> S<__autoreleasing id> g() { return S<__autoreleasing id>(); }
> -// CHECK-LABEL: "?g@@YA?AU?$S at U?$Autoreleasing at PAUobjc_object@@@__ObjC@@@@XZ"
> +// CHECK-LABEL: "?g@@YA?AU?$S at U?$Autoreleasing at PAU.objc_object@@@__ObjC@@@@XZ"
>
> __autoreleasing id h() { return nullptr; }
> -// CHECK-LABEL: "?h@@YAPAUobjc_object@@XZ"
> +// CHECK-LABEL: "?h@@YAPAU.objc_object@@XZ"
>
> Modified: cfe/trunk/test/CodeGenObjCXX/msabi-objc-types.mm
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/msabi-objc-types.mm?rev=339428&r1=339427&r2=339428&view=diff
> ==============================================================================
> --- cfe/trunk/test/CodeGenObjCXX/msabi-objc-types.mm (original)
> +++ cfe/trunk/test/CodeGenObjCXX/msabi-objc-types.mm Fri Aug 10 05:53:13 2018
> @@ -3,166 +3,166 @@
> @class I;
>
> id kid;
> -// CHECK: @"?kid@@3PAUobjc_object@@A" = dso_local global
> +// CHECK: @"?kid@@3PAU.objc_object@@A" = dso_local global
>
> Class klass;
> -// CHECK: @"?klass@@3PAUobjc_class@@A" = dso_local global
> +// CHECK: @"?klass@@3PAU.objc_class@@A" = dso_local global
>
> I *kI;
> -// CHECK: @"?kI@@3PAUI@@A" = dso_local global
> +// CHECK: @"?kI@@3PAU.objc_cls_I@@A" = dso_local global
>
> void f(I *) {}
> -// CHECK-LABEL: "?f@@YAXPAUI@@@Z"
> +// CHECK-LABEL: "?f@@YAXPAU.objc_cls_I@@@Z"
>
> void f(const I *) {}
> -// CHECK-LABEL: "?f@@YAXPBUI@@@Z"
> +// CHECK-LABEL: "?f@@YAXPBU.objc_cls_I@@@Z"
>
> void f(I &) {}
> -// CHECK-LABEL: "?f@@YAXAAUI@@@Z"
> +// CHECK-LABEL: "?f@@YAXAAU.objc_cls_I@@@Z"
>
> void f(const I &) {}
> -// CHECK-LABEL: "?f@@YAXABUI@@@Z"
> +// CHECK-LABEL: "?f@@YAXABU.objc_cls_I@@@Z"
>
> void f(const I &&) {}
> -// CHECK-LABEL: "?f@@YAX$$QBUI@@@Z"
> +// CHECK-LABEL: "?f@@YAX$$QBU.objc_cls_I@@@Z"
>
> void g(id) {}
> -// CHECK-LABEL: "?g@@YAXPAUobjc_object@@@Z"
> +// CHECK-LABEL: "?g@@YAXPAU.objc_object@@@Z"
>
> void g(id &) {}
> -// CHECK-LABEL: "?g@@YAXAAPAUobjc_object@@@Z"
> +// CHECK-LABEL: "?g@@YAXAAPAU.objc_object@@@Z"
>
> void g(const id &) {}
> -// CHECK-LABEL: "?g@@YAXABQAUobjc_object@@@Z"
> +// CHECK-LABEL: "?g@@YAXABQAU.objc_object@@@Z"
>
> void g(id &&) {}
> -// CHECK-LABEL: "?g@@YAX$$QAPAUobjc_object@@@Z"
> +// CHECK-LABEL: "?g@@YAX$$QAPAU.objc_object@@@Z"
>
> void h(Class) {}
> -// CHECK-LABEL: "?h@@YAXPAUobjc_class@@@Z"
> +// CHECK-LABEL: "?h@@YAXPAU.objc_class@@@Z"
>
> void h(Class &) {}
> -// CHECK-LABEL: "?h@@YAXAAPAUobjc_class@@@Z"
> +// CHECK-LABEL: "?h@@YAXAAPAU.objc_class@@@Z"
>
> void h(const Class &) {}
> -// CHECK-LABEL: "?h@@YAXABQAUobjc_class@@@Z"
> +// CHECK-LABEL: "?h@@YAXABQAU.objc_class@@@Z"
>
> void h(Class &&) {}
> -// CHECK-LABEL: "?h@@YAX$$QAPAUobjc_class@@@Z"
> +// CHECK-LABEL: "?h@@YAX$$QAPAU.objc_class@@@Z"
>
> I *i() { return nullptr; }
> -// CHECK-LABEL: "?i@@YAPAUI@@XZ"
> +// CHECK-LABEL: "?i@@YAPAU.objc_cls_I@@XZ"
>
> const I *j() { return nullptr; }
> -// CHECK-LABEL: "?j@@YAPBUI@@XZ"
> +// CHECK-LABEL: "?j@@YAPBU.objc_cls_I@@XZ"
>
> I &k() { return *kI; }
> -// CHECK-LABEL: "?k@@YAAAUI@@XZ"
> +// CHECK-LABEL: "?k@@YAAAU.objc_cls_I@@XZ"
>
> const I &l() { return *kI; }
> -// CHECK-LABEL: "?l@@YAABUI@@XZ"
> +// CHECK-LABEL: "?l@@YAABU.objc_cls_I@@XZ"
>
> void m(const id) {}
> -// CHECK-LABEL: "?m@@YAXQAUobjc_object@@@Z"
> +// CHECK-LABEL: "?m@@YAXQAU.objc_object@@@Z"
>
> void m(const I *) {}
> -// CHECK-LABEL: "?m@@YAXPBUI@@@Z"
> +// CHECK-LABEL: "?m@@YAXPBU.objc_cls_I@@@Z"
>
> void n(SEL) {}
> -// CHECK-LABEL: "?n@@YAXPAUobjc_selector@@@Z"
> +// CHECK-LABEL: "?n@@YAXPAU.objc_selector@@@Z"
>
> void n(SEL *) {}
> -// CHECK-LABEL: "?n@@YAXPAPAUobjc_selector@@@Z"
> +// CHECK-LABEL: "?n@@YAXPAPAU.objc_selector@@@Z"
>
> void n(const SEL *) {}
> -// CHECK-LABEL: "?n@@YAXPBQAUobjc_selector@@@Z"
> +// CHECK-LABEL: "?n@@YAXPBQAU.objc_selector@@@Z"
>
> void n(SEL &) {}
> -// CHECK-LABEL: "?n@@YAXAAPAUobjc_selector@@@Z"
> +// CHECK-LABEL: "?n@@YAXAAPAU.objc_selector@@@Z"
>
> void n(const SEL &) {}
> -// CHECK-LABEL: "?n@@YAXABQAUobjc_selector@@@Z"
> +// CHECK-LABEL: "?n@@YAXABQAU.objc_selector@@@Z"
>
> void n(SEL &&) {}
> -// CHECK-LABEL: "?n@@YAX$$QAPAUobjc_selector@@@Z"
> +// CHECK-LABEL: "?n@@YAX$$QAPAU.objc_selector@@@Z"
>
> struct __declspec(dllexport) s {
> struct s &operator=(const struct s &) = delete;
>
> void m(I *) {}
> - // CHECK-LABEL: "?m at s@@QAAXPAUI@@@Z"
> + // CHECK-LABEL: "?m at s@@QAAXPAU.objc_cls_I@@@Z"
>
> void m(const I *) {}
> - // CHECK-LABEL: "?m at s@@QAAXPBUI@@@Z"
> + // CHECK-LABEL: "?m at s@@QAAXPBU.objc_cls_I@@@Z"
>
> void m(I &) {}
> - // CHECK-LABEL: "?m at s@@QAAXAAUI@@@Z"
> + // CHECK-LABEL: "?m at s@@QAAXAAU.objc_cls_I@@@Z"
>
> void m(const I &) {}
> - // CHECK-LABEL: "?m at s@@QAAXABUI@@@Z"
> + // CHECK-LABEL: "?m at s@@QAAXABU.objc_cls_I@@@Z"
>
> void m(I &&) {}
> - // CHECK-LABEL: "?m at s@@QAAX$$QAUI@@@Z"
> + // CHECK-LABEL: "?m at s@@QAAX$$QAU.objc_cls_I@@@Z"
>
> void m(const I &&) {}
> - // CHECK-LABEL: "?m at s@@QAAX$$QBUI@@@Z"
> + // CHECK-LABEL: "?m at s@@QAAX$$QBU.objc_cls_I@@@Z"
>
> void m(id) {}
> - // CHECK-LABEL: "?m at s@@QAAXPAUobjc_object@@@Z"
> + // CHECK-LABEL: "?m at s@@QAAXPAU.objc_object@@@Z"
>
> void m(id &) {}
> - // CHECK-LABEL: "?m at s@@QAAXAAPAUobjc_object@@@Z"
> + // CHECK-LABEL: "?m at s@@QAAXAAPAU.objc_object@@@Z"
>
> void m(id &&) {}
> - // CHECK-LABEL: "?m at s@@QAAX$$QAPAUobjc_object@@@Z"
> + // CHECK-LABEL: "?m at s@@QAAX$$QAPAU.objc_object@@@Z"
>
> void m(const id &) {}
> - // CHECK-LABEL: "?m at s@@QAAXABQAUobjc_object@@@Z"
> + // CHECK-LABEL: "?m at s@@QAAXABQAU.objc_object@@@Z"
>
> void m(const id &&) {}
> - // CHECK-LABEL: "?m at s@@QAAX$$QBQAUobjc_object@@@Z"
> + // CHECK-LABEL: "?m at s@@QAAX$$QBQAU.objc_object@@@Z"
>
> void m(Class *) {}
> - // CHECK-LABEL: "?m at s@@QAAXPAPAUobjc_class@@@Z"
> + // CHECK-LABEL: "?m at s@@QAAXPAPAU.objc_class@@@Z"
>
> void m(const Class *) {}
> - // CHECK-LABEL: "?m at s@@QAAXPBQAUobjc_class@@@Z"
> + // CHECK-LABEL: "?m at s@@QAAXPBQAU.objc_class@@@Z"
>
> void m(Class) {}
> - // CHECK-LABEL: "?m at s@@QAAXPAUobjc_class@@@Z"
> + // CHECK-LABEL: "?m at s@@QAAXPAU.objc_class@@@Z"
>
> void m(Class &) {}
> - // CHECK-LABEL: "?m at s@@QAAXAAPAUobjc_class@@@Z"
> + // CHECK-LABEL: "?m at s@@QAAXAAPAU.objc_class@@@Z"
>
> void m(const Class &) {}
> - // CHECK-LABEL: "?m at s@@QAAXABQAUobjc_class@@@Z"
> + // CHECK-LABEL: "?m at s@@QAAXABQAU.objc_class@@@Z"
>
> void m(Class &&) {}
> - // CHECK-LABEL: "?m at s@@QAAX$$QAPAUobjc_class@@@Z"
> + // CHECK-LABEL: "?m at s@@QAAX$$QAPAU.objc_class@@@Z"
>
> void m(const Class &&) {}
> - // CHECK-LABEL: "?m at s@@QAAX$$QBQAUobjc_class@@@Z"
> + // CHECK-LABEL: "?m at s@@QAAX$$QBQAU.objc_class@@@Z"
>
> void m(SEL) {}
> - // CHECK-LABEL: "?m at s@@QAAXPAUobjc_selector@@@Z"
> + // CHECK-LABEL: "?m at s@@QAAXPAU.objc_selector@@@Z"
>
> void m(SEL *) {}
> - // CHECK-LABEL: "?m at s@@QAAXPAPAUobjc_selector@@@Z"
> + // CHECK-LABEL: "?m at s@@QAAXPAPAU.objc_selector@@@Z"
>
> void m(const SEL *) {}
> - // CHECK-LABEL: "?m at s@@QAAXPBQAUobjc_selector@@@Z"
> + // CHECK-LABEL: "?m at s@@QAAXPBQAU.objc_selector@@@Z"
>
> void m(SEL &) {}
> - // CHECK-LABEL: "?m at s@@QAAXAAPAUobjc_selector@@@Z"
> + // CHECK-LABEL: "?m at s@@QAAXAAPAU.objc_selector@@@Z"
>
> void m(const SEL &) {}
> - // CHECK-LABEL: "?m at s@@QAAXABQAUobjc_selector@@@Z"
> + // CHECK-LABEL: "?m at s@@QAAXABQAU.objc_selector@@@Z"
>
> void m(SEL &&) {}
> - // CHECK-LABEL: "?m at s@@QAAX$$QAPAUobjc_selector@@@Z"
> + // CHECK-LABEL: "?m at s@@QAAX$$QAPAU.objc_selector@@@Z"
>
> void m(const SEL &&) {}
> - // CHECK-LABEL: "?m at s@@QAAX$$QBQAUobjc_selector@@@Z"
> + // CHECK-LABEL: "?m at s@@QAAX$$QBQAU.objc_selector@@@Z"
> };
>
> template <typename T>
> @@ -179,14 +179,14 @@ struct t {
> };
>
> template struct t<id>;
> -// CHECK-LABEL: "??0?$t at PAUobjc_object@@@@QAA at XZ"
> +// CHECK-LABEL: "??0?$t at PAU.objc_object@@@@QAA at XZ"
>
> template struct t<remove_pointer<id>::type>;
> -// CHECK-LABEL: "??0?$t at Uobjc_object@@@@QAA at XZ"
> +// CHECK-LABEL: "??0?$t at U.objc_object@@@@QAA at XZ"
>
> template struct t<SEL>;
> -// CHECK-LABEL: "??0?$t at PAUobjc_selector@@@@QAA at XZ"
> +// CHECK-LABEL: "??0?$t at PAU.objc_selector@@@@QAA at XZ"
>
> template struct t<remove_pointer<SEL>::type>;
> -// CHECK-LABEL: "??0?$t at Uobjc_selector@@@@QAA at XZ"
> +// CHECK-LABEL: "??0?$t at U.objc_selector@@@@QAA at XZ"
>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
More information about the cfe-commits
mailing list