diff options
Diffstat (limited to 'lib/CodeGen/CGObjCGNU.cpp')
-rw-r--r-- | lib/CodeGen/CGObjCGNU.cpp | 317 |
1 files changed, 209 insertions, 108 deletions
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index 548bd6b3fd..ee5c12aa35 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -1,9 +1,8 @@ //===------- CGObjCGNU.cpp - Emit LLVM Code from ASTs for a Module --------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -29,7 +28,6 @@ #include "clang/Basic/SourceManager.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" -#include "llvm/IR/CallSite.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/LLVMContext.h" @@ -60,7 +58,7 @@ class LazyRuntimeFunction { CodeGenModule *CGM; llvm::FunctionType *FTy; const char *FunctionName; - llvm::Constant *Function; + llvm::FunctionCallee Function; public: /// Constructor leaves this class uninitialized, because it is intended to @@ -90,7 +88,7 @@ public: /// Overloaded cast operator, allows the class to be implicitly cast to an /// LLVM constant. - operator llvm::Constant *() { + operator llvm::FunctionCallee() { if (!Function) { if (!FunctionName) return nullptr; @@ -98,9 +96,6 @@ public: } return Function; } - operator llvm::Function *() { - return cast<llvm::Function>((llvm::Constant *)*this); - } }; @@ -190,12 +185,16 @@ protected: (R.getVersion() >= VersionTuple(major, minor)); } - std::string SymbolForProtocol(StringRef Name) { - return (StringRef("._OBJC_PROTOCOL_") + Name).str(); + std::string ManglePublicSymbol(StringRef Name) { + return (StringRef(CGM.getTriple().isOSBinFormatCOFF() ? "$_" : "._") + Name).str(); + } + + std::string SymbolForProtocol(Twine Name) { + return (ManglePublicSymbol("OBJC_PROTOCOL_") + Name).str(); } std::string SymbolForProtocolRef(StringRef Name) { - return (StringRef("._OBJC_REF_PROTOCOL_") + Name).str(); + return (ManglePublicSymbol("OBJC_REF_PROTOCOL_") + Name).str(); } @@ -614,15 +613,15 @@ public: const ObjCProtocolDecl *PD) override; void GenerateProtocol(const ObjCProtocolDecl *PD) override; llvm::Function *ModuleInitFunction() override; - llvm::Constant *GetPropertyGetFunction() override; - llvm::Constant *GetPropertySetFunction() override; - llvm::Constant *GetOptimizedPropertySetFunction(bool atomic, - bool copy) override; - llvm::Constant *GetSetStructFunction() override; - llvm::Constant *GetGetStructFunction() override; - llvm::Constant *GetCppAtomicObjectGetFunction() override; - llvm::Constant *GetCppAtomicObjectSetFunction() override; - llvm::Constant *EnumerationMutationFunction() override; + llvm::FunctionCallee GetPropertyGetFunction() override; + llvm::FunctionCallee GetPropertySetFunction() override; + llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic, + bool copy) override; + llvm::FunctionCallee GetSetStructFunction() override; + llvm::FunctionCallee GetGetStructFunction() override; + llvm::FunctionCallee GetCppAtomicObjectGetFunction() override; + llvm::FunctionCallee GetCppAtomicObjectSetFunction() override; + llvm::FunctionCallee EnumerationMutationFunction() override; void EmitTryStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S) override; @@ -691,9 +690,9 @@ protected: llvm::Value *args[] = { EnforceType(Builder, Receiver, IdTy), EnforceType(Builder, cmd, SelectorTy) }; - llvm::CallSite imp = CGF.EmitRuntimeCallOrInvoke(MsgLookupFn, args); + llvm::CallBase *imp = CGF.EmitRuntimeCallOrInvoke(MsgLookupFn, args); imp->setMetadata(msgSendMDKind, node); - return imp.getInstruction(); + return imp; } llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, Address ObjCSuper, @@ -750,7 +749,7 @@ class CGObjCGNUstep : public CGObjCGNU { llvm::Value *cmd, llvm::MDNode *node, MessageSendInfo &MSI) override { CGBuilderTy &Builder = CGF.Builder; - llvm::Function *LookupFn = SlotLookupFn; + llvm::FunctionCallee LookupFn = SlotLookupFn; // Store the receiver on the stack so that we can reload it later Address ReceiverPtr = @@ -766,20 +765,20 @@ class CGObjCGNUstep : public CGObjCGNU { } // The lookup function is guaranteed not to capture the receiver pointer. - LookupFn->addParamAttr(0, llvm::Attribute::NoCapture); + if (auto *LookupFn2 = dyn_cast<llvm::Function>(LookupFn.getCallee())) + LookupFn2->addParamAttr(0, llvm::Attribute::NoCapture); llvm::Value *args[] = { EnforceType(Builder, ReceiverPtr.getPointer(), PtrToIdTy), EnforceType(Builder, cmd, SelectorTy), EnforceType(Builder, self, IdTy) }; - llvm::CallSite slot = CGF.EmitRuntimeCallOrInvoke(LookupFn, args); - slot.setOnlyReadsMemory(); + llvm::CallBase *slot = CGF.EmitRuntimeCallOrInvoke(LookupFn, args); + slot->setOnlyReadsMemory(); slot->setMetadata(msgSendMDKind, node); // Load the imp from the slot llvm::Value *imp = Builder.CreateAlignedLoad( - Builder.CreateStructGEP(nullptr, slot.getInstruction(), 4), - CGF.getPointerAlign()); + Builder.CreateStructGEP(nullptr, slot, 4), CGF.getPointerAlign()); // The lookup function may have changed the receiver, so make sure we use // the new one. @@ -859,7 +858,7 @@ class CGObjCGNUstep : public CGObjCGNU { PtrTy, PtrTy); } - llvm::Constant *GetCppAtomicObjectGetFunction() override { + llvm::FunctionCallee GetCppAtomicObjectGetFunction() override { // The optimised functions were added in version 1.7 of the GNUstep // runtime. assert (CGM.getLangOpts().ObjCRuntime.getVersion() >= @@ -867,7 +866,7 @@ class CGObjCGNUstep : public CGObjCGNU { return CxxAtomicObjectGetFn; } - llvm::Constant *GetCppAtomicObjectSetFunction() override { + llvm::FunctionCallee GetCppAtomicObjectSetFunction() override { // The optimised functions were added in version 1.7 of the GNUstep // runtime. assert (CGM.getLangOpts().ObjCRuntime.getVersion() >= @@ -875,8 +874,8 @@ class CGObjCGNUstep : public CGObjCGNU { return CxxAtomicObjectSetFn; } - llvm::Constant *GetOptimizedPropertySetFunction(bool atomic, - bool copy) override { + llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic, + bool copy) override { // The optimised property functions omit the GC check, and so are not // safe to use in GC mode. The standard functions are fast in GC mode, // so there is less advantage in using them. @@ -911,12 +910,15 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { ConstantStringSection }; static const char *const SectionsBaseNames[8]; + static const char *const PECOFFSectionsBaseNames[8]; template<SectionKind K> std::string sectionName() { - std::string name(SectionsBaseNames[K]); - if (CGM.getTriple().isOSBinFormatCOFF()) + if (CGM.getTriple().isOSBinFormatCOFF()) { + std::string name(PECOFFSectionsBaseNames[K]); name += "$m"; - return name; + return name; + } + return SectionsBaseNames[K]; } /// The GCC ABI superclass message lookup function. Takes a pointer to a /// structure describing the receiver and the class, and a selector as @@ -937,15 +939,19 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { bool EmittedClass = false; /// Generate the name of a symbol for a reference to a class. Accesses to /// classes should be indirected via this. + + typedef std::pair<std::string, std::pair<llvm::Constant*, int>> EarlyInitPair; + std::vector<EarlyInitPair> EarlyInitList; + std::string SymbolForClassRef(StringRef Name, bool isWeak) { if (isWeak) - return (StringRef("._OBJC_WEAK_REF_CLASS_") + Name).str(); + return (ManglePublicSymbol("OBJC_WEAK_REF_CLASS_") + Name).str(); else - return (StringRef("._OBJC_REF_CLASS_") + Name).str(); + return (ManglePublicSymbol("OBJC_REF_CLASS_") + Name).str(); } /// Generate the name of a class symbol. std::string SymbolForClass(StringRef Name) { - return (StringRef("._OBJC_CLASS_") + Name).str(); + return (ManglePublicSymbol("OBJC_CLASS_") + Name).str(); } void CallRuntimeFunction(CGBuilderTy &B, StringRef FunctionName, ArrayRef<llvm::Value*> Args) { @@ -954,7 +960,7 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { Types.push_back(Arg->getType()); llvm::FunctionType *FT = llvm::FunctionType::get(B.getVoidTy(), Types, false); - llvm::Value *Fn = CGM.CreateRuntimeFunction(FT, FunctionName); + llvm::FunctionCallee Fn = CGM.CreateRuntimeFunction(FT, FunctionName); B.CreateCall(Fn, Args); } @@ -999,10 +1005,13 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { llvm::Constant *isa = TheModule.getNamedGlobal(Sym); - if (!isa) + if (!isa) { isa = new llvm::GlobalVariable(TheModule, IdTy, /* isConstant */false, llvm::GlobalValue::ExternalLinkage, nullptr, Sym); - else if (isa->getType() != PtrToIdTy) + if (CGM.getTriple().isOSBinFormatCOFF()) { + cast<llvm::GlobalValue>(isa)->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); + } + } else if (isa->getType() != PtrToIdTy) isa = llvm::ConstantExpr::getBitCast(isa, PtrToIdTy); // struct @@ -1017,7 +1026,11 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { ConstantInitBuilder Builder(CGM); auto Fields = Builder.beginStruct(); - Fields.add(isa); + if (!CGM.getTriple().isOSBinFormatCOFF()) { + Fields.add(isa); + } else { + Fields.addNullPointer(PtrTy); + } // For now, all non-ASCII strings are represented as UTF-16. As such, the // number of bytes is simply double the number of UTF-16 codepoints. In // ASCII strings, the number of bytes is equal to the number of non-ASCII @@ -1088,6 +1101,10 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { ObjCStrGV->setComdat(TheModule.getOrInsertComdat(StringName)); ObjCStrGV->setVisibility(llvm::GlobalValue::HiddenVisibility); } + if (CGM.getTriple().isOSBinFormatCOFF()) { + std::pair<llvm::Constant*, int> v{ObjCStrGV, 0}; + EarlyInitList.emplace_back(Sym, v); + } llvm::Constant *ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStrGV, IdTy); ObjCStrings[Str] = ObjCStr; ConstantStrings.push_back(ObjCStr); @@ -1201,6 +1218,33 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { ClassSymbol->setInitializer(new llvm::GlobalVariable(TheModule, Int8Ty, false, llvm::GlobalValue::ExternalWeakLinkage, nullptr, SymbolForClass(Name))); + else { + if (CGM.getTriple().isOSBinFormatCOFF()) { + IdentifierInfo &II = CGM.getContext().Idents.get(Name); + TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl(); + DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl); + + const ObjCInterfaceDecl *OID = nullptr; + for (const auto &Result : DC->lookup(&II)) + if ((OID = dyn_cast<ObjCInterfaceDecl>(Result))) + break; + + // The first Interface we find may be a @class, + // which should only be treated as the source of + // truth in the absence of a true declaration. + const ObjCInterfaceDecl *OIDDef = OID->getDefinition(); + if (OIDDef != nullptr) + OID = OIDDef; + + auto Storage = llvm::GlobalValue::DefaultStorageClass; + if (OID->hasAttr<DLLImportAttr>()) + Storage = llvm::GlobalValue::DLLImportStorageClass; + else if (OID->hasAttr<DLLExportAttr>()) + Storage = llvm::GlobalValue::DLLExportStorageClass; + + cast<llvm::GlobalValue>(ClassSymbol)->setDLLStorageClass(Storage); + } + } assert(ClassSymbol->getName() == SymbolName); return ClassSymbol; } @@ -1453,7 +1497,7 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { Sym->setSection((Section + SecSuffix).str()); Sym->setComdat(TheModule.getOrInsertComdat((Prefix + Section).str())); - Sym->setAlignment(1); + Sym->setAlignment(CGM.getPointerAlign().getQuantity()); return Sym; }; return { Sym("__start_", "$a"), Sym("__stop", "$z") }; @@ -1488,11 +1532,12 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { ConstantInitBuilder builder(CGM); auto InitStructBuilder = builder.beginStruct(); InitStructBuilder.addInt(Int64Ty, 0); - for (auto *s : SectionsBaseNames) { + auto §ionVec = CGM.getTriple().isOSBinFormatCOFF() ? PECOFFSectionsBaseNames : SectionsBaseNames; + for (auto *s : sectionVec) { auto bounds = GetSectionBounds(s); InitStructBuilder.add(bounds.first); InitStructBuilder.add(bounds.second); - }; + } auto *InitStruct = InitStructBuilder.finishAndCreateGlobal(".objc_init", CGM.getPointerAlign(), false, llvm::GlobalValue::LinkOnceODRLinkage); InitStruct->setVisibility(llvm::GlobalValue::HiddenVisibility); @@ -1519,7 +1564,12 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { if (CGM.getTriple().isOSBinFormatCOFF()) InitVar->setSection(".CRT$XCLz"); else - InitVar->setSection(".ctors"); + { + if (CGM.getCodeGenOpts().UseInitArray) + InitVar->setSection(".init_array"); + else + InitVar->setSection(".ctors"); + } InitVar->setVisibility(llvm::GlobalValue::HiddenVisibility); InitVar->setComdat(TheModule.getOrInsertComdat(".objc_ctor")); CGM.addUsedGlobal(InitVar); @@ -1582,6 +1632,29 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { ConstantStrings.clear(); Categories.clear(); Classes.clear(); + + if (EarlyInitList.size() > 0) { + auto *Init = llvm::Function::Create(llvm::FunctionType::get(CGM.VoidTy, + {}), llvm::GlobalValue::InternalLinkage, ".objc_early_init", + &CGM.getModule()); + llvm::IRBuilder<> b(llvm::BasicBlock::Create(CGM.getLLVMContext(), "entry", + Init)); + for (const auto &lateInit : EarlyInitList) { + auto *global = TheModule.getGlobalVariable(lateInit.first); + if (global) { + b.CreateAlignedStore(global, + b.CreateStructGEP(lateInit.second.first, lateInit.second.second), CGM.getPointerAlign().getQuantity()); + } + } + b.CreateRetVoid(); + // We can't use the normal LLVM global initialisation array, because we + // need to specify that this runs early in library initialisation. + auto *InitVar = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), + /*isConstant*/true, llvm::GlobalValue::InternalLinkage, + Init, ".objc_early_init_ptr"); + InitVar->setSection(".CRT$XCLb"); + CGM.addUsedGlobal(InitVar); + } return nullptr; } /// In the v2 ABI, ivar offset variables use the type encoding in their name @@ -1613,6 +1686,7 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { } void GenerateClass(const ObjCImplementationDecl *OID) override { ASTContext &Context = CGM.getContext(); + bool IsCOFF = CGM.getTriple().isOSBinFormatCOFF(); // Get the class name ObjCInterfaceDecl *classDecl = @@ -1671,8 +1745,9 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { // struct objc_property_list *properties metaclassFields.add(GeneratePropertyList(OID, classDecl, /*isClassProperty*/true)); - auto *metaclass = metaclassFields.finishAndCreateGlobal("._OBJC_METACLASS_" - + className, CGM.getPointerAlign()); + auto *metaclass = metaclassFields.finishAndCreateGlobal( + ManglePublicSymbol("OBJC_METACLASS_") + className, + CGM.getPointerAlign()); auto classFields = builder.beginStruct(); // struct objc_class *isa; @@ -1681,15 +1756,28 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { // Get the superclass name. const ObjCInterfaceDecl * SuperClassDecl = OID->getClassInterface()->getSuperClass(); + llvm::Constant *SuperClass = nullptr; if (SuperClassDecl) { auto SuperClassName = SymbolForClass(SuperClassDecl->getNameAsString()); - llvm::Constant *SuperClass = TheModule.getNamedGlobal(SuperClassName); + SuperClass = TheModule.getNamedGlobal(SuperClassName); if (!SuperClass) { SuperClass = new llvm::GlobalVariable(TheModule, PtrTy, false, llvm::GlobalValue::ExternalLinkage, nullptr, SuperClassName); + if (IsCOFF) { + auto Storage = llvm::GlobalValue::DefaultStorageClass; + if (SuperClassDecl->hasAttr<DLLImportAttr>()) + Storage = llvm::GlobalValue::DLLImportStorageClass; + else if (SuperClassDecl->hasAttr<DLLExportAttr>()) + Storage = llvm::GlobalValue::DLLExportStorageClass; + + cast<llvm::GlobalValue>(SuperClass)->setDLLStorageClass(Storage); + } } - classFields.add(llvm::ConstantExpr::getBitCast(SuperClass, PtrTy)); + if (!IsCOFF) + classFields.add(llvm::ConstantExpr::getBitCast(SuperClass, PtrTy)); + else + classFields.addNullPointer(PtrTy); } else classFields.addNullPointer(PtrTy); // const char *name; @@ -1731,7 +1819,6 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { CGM.getContext().getCharWidth()); // struct objc_ivar ivars[] auto ivarArrayBuilder = ivarListBuilder.beginArray(); - CodeGenTypes &Types = CGM.getTypes(); for (const ObjCIvarDecl *IVD = classDecl->all_declared_ivar_begin(); IVD; IVD = IVD->getNextIvar()) { auto ivarTy = IVD->getType(); @@ -1765,8 +1852,7 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { ivarBuilder.add(OffsetVar); // Ivar size ivarBuilder.addInt(Int32Ty, - td.getTypeSizeInBits(Types.ConvertType(ivarTy)) / - CGM.getContext().getCharWidth()); + CGM.getContext().getTypeSizeInChars(ivarTy).getQuantity()); // Alignment will be stored as a base-2 log of the alignment. int align = llvm::Log2_32(Context.getTypeAlignInChars(ivarTy).getQuantity()); // Objects that require more than 2^64-byte alignment should be impossible! @@ -1839,19 +1925,24 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { classFields.finishAndCreateGlobal(SymbolForClass(className), CGM.getPointerAlign(), false, llvm::GlobalValue::ExternalLinkage); - if (CGM.getTriple().isOSBinFormatCOFF()) { - auto Storage = llvm::GlobalValue::DefaultStorageClass; - if (OID->getClassInterface()->hasAttr<DLLImportAttr>()) - Storage = llvm::GlobalValue::DLLImportStorageClass; - else if (OID->getClassInterface()->hasAttr<DLLExportAttr>()) - Storage = llvm::GlobalValue::DLLExportStorageClass; - cast<llvm::GlobalValue>(classStruct)->setDLLStorageClass(Storage); - } - auto *classRefSymbol = GetClassVar(className); classRefSymbol->setSection(sectionName<ClassReferenceSection>()); classRefSymbol->setInitializer(llvm::ConstantExpr::getBitCast(classStruct, IdTy)); + if (IsCOFF) { + // we can't import a class struct. + if (OID->getClassInterface()->hasAttr<DLLExportAttr>()) { + cast<llvm::GlobalValue>(classStruct)->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); + cast<llvm::GlobalValue>(classRefSymbol)->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); + } + + if (SuperClass) { + std::pair<llvm::Constant*, int> v{classStruct, 1}; + EarlyInitList.emplace_back(SuperClass->getName(), std::move(v)); + } + + } + // Resolve the class aliases, if they exist. // FIXME: Class pointer aliases shouldn't exist! @@ -1879,7 +1970,7 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { auto classInitRef = new llvm::GlobalVariable(TheModule, classStruct->getType(), false, llvm::GlobalValue::ExternalLinkage, - classStruct, "._OBJC_INIT_CLASS_" + className); + classStruct, ManglePublicSymbol("OBJC_INIT_CLASS_") + className); classInitRef->setSection(sectionName<ClassSection>()); CGM.addUsedGlobal(classInitRef); @@ -1916,6 +2007,18 @@ const char *const CGObjCGNUstep2::SectionsBaseNames[8] = "__objc_constant_string" }; +const char *const CGObjCGNUstep2::PECOFFSectionsBaseNames[8] = +{ +".objcrt$SEL", +".objcrt$CLS", +".objcrt$CLR", +".objcrt$CAT", +".objcrt$PCL", +".objcrt$PCR", +".objcrt$CAL", +".objcrt$STR" +}; + /// Support for the ObjFW runtime. class CGObjCObjFW: public CGObjCGNU { protected: @@ -1938,14 +2041,14 @@ protected: EnforceType(Builder, Receiver, IdTy), EnforceType(Builder, cmd, SelectorTy) }; - llvm::CallSite imp; + llvm::CallBase *imp; if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) imp = CGF.EmitRuntimeCallOrInvoke(MsgLookupFnSRet, args); else imp = CGF.EmitRuntimeCallOrInvoke(MsgLookupFn, args); imp->setMetadata(msgSendMDKind, node); - return imp.getInstruction(); + return imp; } llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, Address ObjCSuper, @@ -2174,9 +2277,8 @@ llvm::Value *CGObjCGNU::GetClassNamed(CodeGenFunction &CGF, if (!isWeak) EmitClassRef(Name); - llvm::Constant *ClassLookupFn = - CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, PtrToInt8Ty, true), - "objc_lookup_class"); + llvm::FunctionCallee ClassLookupFn = CGM.CreateRuntimeFunction( + llvm::FunctionType::get(IdTy, PtrToInt8Ty, true), "objc_lookup_class"); return CGF.EmitNounwindRuntimeCall(ClassLookupFn, ClassName); } @@ -2432,7 +2534,7 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGenFunction &CGF, ReceiverClass = EnforceType(Builder, ReceiverClass, IdTy); } else { if (isCategoryImpl) { - llvm::Constant *classLookupFunction = nullptr; + llvm::FunctionCallee classLookupFunction = nullptr; if (IsClassMessage) { classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get( IdTy, PtrTy, true), "objc_get_meta_class"); @@ -2481,10 +2583,8 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGenFunction &CGF, Address ObjCSuper = CGF.CreateTempAlloca(ObjCSuperTy, CGF.getPointerAlign()); - Builder.CreateStore(Receiver, - Builder.CreateStructGEP(ObjCSuper, 0, CharUnits::Zero())); - Builder.CreateStore(ReceiverClass, - Builder.CreateStructGEP(ObjCSuper, 1, CGF.getPointerSize())); + Builder.CreateStore(Receiver, Builder.CreateStructGEP(ObjCSuper, 0)); + Builder.CreateStore(ReceiverClass, Builder.CreateStructGEP(ObjCSuper, 1)); ObjCSuper = EnforceType(Builder, ObjCSuper, PtrToObjCSuperTy); @@ -2501,7 +2601,7 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGenFunction &CGF, CGCallee callee(CGCalleeInfo(), imp); - llvm::Instruction *call; + llvm::CallBase *call; RValue msgRet = CGF.EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call); call->setMetadata(msgSendMDKind, node); return msgRet; @@ -2595,16 +2695,21 @@ CGObjCGNU::GenerateMessageSend(CodeGenFunction &CGF, case CodeGenOptions::Mixed: case CodeGenOptions::NonLegacy: if (CGM.ReturnTypeUsesFPRet(ResultType)) { - imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true), - "objc_msgSend_fpret"); + imp = + CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true), + "objc_msgSend_fpret") + .getCallee(); } else if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) { // The actual types here don't matter - we're going to bitcast the // function anyway - imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true), - "objc_msgSend_stret"); + imp = + CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true), + "objc_msgSend_stret") + .getCallee(); } else { - imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true), - "objc_msgSend"); + imp = CGM.CreateRuntimeFunction( + llvm::FunctionType::get(IdTy, IdTy, true), "objc_msgSend") + .getCallee(); } } @@ -2613,7 +2718,7 @@ CGObjCGNU::GenerateMessageSend(CodeGenFunction &CGF, imp = EnforceType(Builder, imp, MSI.MessengerType); - llvm::Instruction *call; + llvm::CallBase *call; CGCallee callee(CGCalleeInfo(), imp); RValue msgRet = CGF.EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call); call->setMetadata(msgSendMDKind, node); @@ -3697,7 +3802,8 @@ llvm::Function *CGObjCGNU::ModuleInitFunction() { llvm::FunctionType *FT = llvm::FunctionType::get(Builder.getVoidTy(), module->getType(), true); - llvm::Value *Register = CGM.CreateRuntimeFunction(FT, "__objc_exec_class"); + llvm::FunctionCallee Register = + CGM.CreateRuntimeFunction(FT, "__objc_exec_class"); Builder.CreateCall(Register, module); if (!ClassAliases.empty()) { @@ -3766,36 +3872,36 @@ llvm::Function *CGObjCGNU::GenerateMethod(const ObjCMethodDecl *OMD, return Method; } -llvm::Constant *CGObjCGNU::GetPropertyGetFunction() { +llvm::FunctionCallee CGObjCGNU::GetPropertyGetFunction() { return GetPropertyFn; } -llvm::Constant *CGObjCGNU::GetPropertySetFunction() { +llvm::FunctionCallee CGObjCGNU::GetPropertySetFunction() { return SetPropertyFn; } -llvm::Constant *CGObjCGNU::GetOptimizedPropertySetFunction(bool atomic, - bool copy) { +llvm::FunctionCallee CGObjCGNU::GetOptimizedPropertySetFunction(bool atomic, + bool copy) { return nullptr; } -llvm::Constant *CGObjCGNU::GetGetStructFunction() { +llvm::FunctionCallee CGObjCGNU::GetGetStructFunction() { return GetStructPropertyFn; } -llvm::Constant *CGObjCGNU::GetSetStructFunction() { +llvm::FunctionCallee CGObjCGNU::GetSetStructFunction() { return SetStructPropertyFn; } -llvm::Constant *CGObjCGNU::GetCppAtomicObjectGetFunction() { +llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectGetFunction() { return nullptr; } -llvm::Constant *CGObjCGNU::GetCppAtomicObjectSetFunction() { +llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectSetFunction() { return nullptr; } -llvm::Constant *CGObjCGNU::EnumerationMutationFunction() { +llvm::FunctionCallee CGObjCGNU::EnumerationMutationFunction() { return EnumerationMutationFn; } @@ -3844,13 +3950,14 @@ void CGObjCGNU::EmitThrowStmt(CodeGenFunction &CGF, // 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(); + llvm::CallBase *Throw = CGF.EmitRuntimeCallOrInvoke(ExceptionReThrowFn); + Throw->setDoesNotReturn(); } else { ExceptionAsObject = CGF.Builder.CreateBitCast(ExceptionAsObject, IdTy); - llvm::CallSite Throw = + llvm::CallBase *Throw = CGF.EmitRuntimeCallOrInvoke(ExceptionThrowFn, ExceptionAsObject); - Throw.setDoesNotReturn(); + Throw->setDoesNotReturn(); } CGF.Builder.CreateUnreachable(); if (ClearInsertionPoint) @@ -3861,8 +3968,7 @@ llvm::Value * CGObjCGNU::EmitObjCWeakRead(CodeGenFunction &CGF, Address AddrWeakObj) { CGBuilderTy &B = CGF.Builder; AddrWeakObj = EnforceType(B, AddrWeakObj, PtrToIdTy); - return B.CreateCall(WeakReadFn.getType(), WeakReadFn, - AddrWeakObj.getPointer()); + return B.CreateCall(WeakReadFn, AddrWeakObj.getPointer()); } void CGObjCGNU::EmitObjCWeakAssign(CodeGenFunction &CGF, @@ -3870,8 +3976,7 @@ void CGObjCGNU::EmitObjCWeakAssign(CodeGenFunction &CGF, CGBuilderTy &B = CGF.Builder; src = EnforceType(B, src, IdTy); dst = EnforceType(B, dst, PtrToIdTy); - B.CreateCall(WeakAssignFn.getType(), WeakAssignFn, - {src, dst.getPointer()}); + B.CreateCall(WeakAssignFn, {src, dst.getPointer()}); } void CGObjCGNU::EmitObjCGlobalAssign(CodeGenFunction &CGF, @@ -3882,8 +3987,7 @@ void CGObjCGNU::EmitObjCGlobalAssign(CodeGenFunction &CGF, dst = EnforceType(B, dst, PtrToIdTy); // FIXME. Add threadloca assign API assert(!threadlocal && "EmitObjCGlobalAssign - Threal Local API NYI"); - B.CreateCall(GlobalAssignFn.getType(), GlobalAssignFn, - {src, dst.getPointer()}); + B.CreateCall(GlobalAssignFn, {src, dst.getPointer()}); } void CGObjCGNU::EmitObjCIvarAssign(CodeGenFunction &CGF, @@ -3892,8 +3996,7 @@ void CGObjCGNU::EmitObjCIvarAssign(CodeGenFunction &CGF, CGBuilderTy &B = CGF.Builder; src = EnforceType(B, src, IdTy); dst = EnforceType(B, dst, IdTy); - B.CreateCall(IvarAssignFn.getType(), IvarAssignFn, - {src, dst.getPointer(), ivarOffset}); + B.CreateCall(IvarAssignFn, {src, dst.getPointer(), ivarOffset}); } void CGObjCGNU::EmitObjCStrongCastAssign(CodeGenFunction &CGF, @@ -3901,8 +4004,7 @@ void CGObjCGNU::EmitObjCStrongCastAssign(CodeGenFunction &CGF, CGBuilderTy &B = CGF.Builder; src = EnforceType(B, src, IdTy); dst = EnforceType(B, dst, PtrToIdTy); - B.CreateCall(StrongCastAssignFn.getType(), StrongCastAssignFn, - {src, dst.getPointer()}); + B.CreateCall(StrongCastAssignFn, {src, dst.getPointer()}); } void CGObjCGNU::EmitGCMemmoveCollectable(CodeGenFunction &CGF, @@ -3913,8 +4015,7 @@ void CGObjCGNU::EmitGCMemmoveCollectable(CodeGenFunction &CGF, DestPtr = EnforceType(B, DestPtr, PtrTy); SrcPtr = EnforceType(B, SrcPtr, PtrTy); - B.CreateCall(MemMoveFn.getType(), MemMoveFn, - {DestPtr.getPointer(), SrcPtr.getPointer(), Size}); + B.CreateCall(MemMoveFn, {DestPtr.getPointer(), SrcPtr.getPointer(), Size}); } llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable( |