summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/CGObjCGNU.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGObjCGNU.cpp')
-rw-r--r--lib/CodeGen/CGObjCGNU.cpp317
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 &sectionVec = 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(