30 #include "llvm/ADT/SmallVector.h"
31 #include "llvm/ADT/StringMap.h"
32 #include "llvm/IR/DataLayout.h"
33 #include "llvm/IR/Intrinsics.h"
34 #include "llvm/IR/LLVMContext.h"
35 #include "llvm/IR/Module.h"
36 #include "llvm/Support/Compiler.h"
37 #include "llvm/Support/ConvertUTF.h"
40 using namespace clang;
41 using namespace CodeGen;
48 class LazyRuntimeFunction {
50 llvm::FunctionType *FTy;
51 const char *FunctionName;
59 : CGM(nullptr), FunctionName(nullptr),
Function(nullptr) {}
63 template <
typename... Tys>
71 FTy = llvm::FunctionType::get(RetTy, ArgTys,
false);
74 FTy = llvm::FunctionType::get(RetTy, std::nullopt,
false);
78 llvm::FunctionType *getType() {
return FTy; }
82 operator llvm::FunctionCallee() {
99 llvm::Module &TheModule;
102 llvm::StructType *ObjCSuperTy;
105 llvm::PointerType *PtrToObjCSuperTy;
109 llvm::PointerType *SelectorTy;
111 llvm::Type *SelectorElemTy;
114 llvm::IntegerType *Int8Ty;
117 llvm::PointerType *PtrToInt8Ty;
119 llvm::StructType *ProtocolTy;
121 llvm::PointerType *ProtocolPtrTy;
127 llvm::PointerType *IMPTy;
132 llvm::PointerType *IdTy;
134 llvm::Type *IdElemTy;
137 llvm::PointerType *PtrToIdTy;
142 llvm::IntegerType *IntTy;
146 llvm::PointerType *PtrTy;
150 llvm::IntegerType *LongTy;
152 llvm::IntegerType *SizeTy;
154 llvm::IntegerType *IntPtrTy;
156 llvm::IntegerType *PtrDiffTy;
159 llvm::PointerType *PtrToIntTy;
163 llvm::IntegerType *Int32Ty;
165 llvm::IntegerType *Int64Ty;
167 llvm::StructType *PropertyMetadataTy;
171 unsigned msgSendMDKind;
174 bool usesSEHExceptions;
180 (R.
getVersion() >= VersionTuple(major, minor));
184 return (StringRef(CGM.
getTriple().isOSBinFormatCOFF() ?
"$_" :
"._") + Name).str();
188 return (ManglePublicSymbol(
"OBJC_PROTOCOL_") + Name).str();
192 return (ManglePublicSymbol(
"OBJC_REF_PROTOCOL_") + Name).str();
199 llvm::Constant *MakeConstantString(StringRef Str,
const char *Name =
"") {
202 return llvm::ConstantExpr::getGetElementPtr(Array.getElementType(),
203 Array.getPointer(), Zeros);
210 llvm::Constant *ExportUniqueString(
const std::string &Str,
212 bool Private=
false) {
214 auto *ConstStr = TheModule.getGlobalVariable(
name);
216 llvm::Constant *value = llvm::ConstantDataArray::getString(VMContext,Str);
217 auto *GV =
new llvm::GlobalVariable(TheModule, value->getType(),
true,
218 llvm::GlobalValue::LinkOnceODRLinkage, value,
name);
219 GV->setComdat(TheModule.getOrInsertComdat(
name));
224 return llvm::ConstantExpr::getGetElementPtr(ConstStr->getValueType(),
230 const Decl *Container) {
236 NameAndAttributes +=
'\0';
237 NameAndAttributes += TypeStr.length() + 3;
238 NameAndAttributes += TypeStr;
239 NameAndAttributes +=
'\0';
241 return MakeConstantString(NameAndAttributes);
250 int attrs =
property->getPropertyAttributes();
259 Fields.addInt(Int8Ty, attrs & 0xff);
265 attrs |= isSynthesized ? (1<<0) : 0;
266 attrs |= isDynamic ? (1<<1) : 0;
269 Fields.addInt(Int8Ty, attrs & 0xff);
271 Fields.addInt(Int8Ty, 0);
272 Fields.addInt(Int8Ty, 0);
275 virtual llvm::Constant *GenerateCategoryProtocolList(
const
280 Fields.addInt(IntTy, count);
283 llvm::DataLayout td(&TheModule);
284 Fields.addInt(IntTy, td.getTypeSizeInBits(PropertyMetadataTy) /
295 bool isSynthesized=
true,
bool
297 auto Fields = PropertiesArray.
beginStruct(PropertyMetadataTy);
299 Fields.add(MakePropertyEncodingString(property, OCD));
300 PushPropertyAttributes(Fields, property, isSynthesized, isDynamic);
304 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
305 Fields.add(MakeConstantString(accessor->getSelector().getAsString()));
306 Fields.add(TypeEncoding);
320 llvm::Value *EnforceType(
CGBuilderTy &B, llvm::Value *
V, llvm::Type *Ty) {
321 if (
V->getType() == Ty)
323 return B.CreateBitCast(
V, Ty);
327 llvm::Constant *Zeros[2];
329 llvm::Constant *NULLPtr;
331 llvm::LLVMContext &VMContext;
339 llvm::GlobalAlias *ClassPtrAlias;
344 llvm::GlobalAlias *MetaClassPtrAlias;
346 std::vector<llvm::Constant*> Classes;
348 std::vector<llvm::Constant*> Categories;
351 std::vector<llvm::Constant*> ConstantStrings;
355 llvm::StringMap<llvm::Constant*> ObjCStrings;
357 llvm::StringMap<llvm::Constant*> ExistingProtocols;
363 typedef std::pair<std::string, llvm::GlobalAlias*> TypedSelector;
367 typedef llvm::DenseMap<Selector, SmallVector<TypedSelector, 2> >
375 Selector RetainSel, ReleaseSel, AutoreleaseSel;
379 LazyRuntimeFunction IvarAssignFn, StrongCastAssignFn, MemMoveFn, WeakReadFn,
380 WeakAssignFn, GlobalAssignFn;
382 typedef std::pair<std::string, std::string> ClassAliasPair;
384 std::vector<ClassAliasPair> ClassAliases;
388 LazyRuntimeFunction ExceptionThrowFn;
391 LazyRuntimeFunction ExceptionReThrowFn;
394 LazyRuntimeFunction EnterCatchFn;
397 LazyRuntimeFunction ExitCatchFn;
399 LazyRuntimeFunction SyncEnterFn;
401 LazyRuntimeFunction SyncExitFn;
406 LazyRuntimeFunction EnumerationMutationFn;
409 LazyRuntimeFunction GetPropertyFn;
412 LazyRuntimeFunction SetPropertyFn;
414 LazyRuntimeFunction GetStructPropertyFn;
416 LazyRuntimeFunction SetStructPropertyFn;
428 const int ProtocolVersion;
431 const int ClassABIVersion;
447 llvm::Constant *GenerateMethodList(StringRef ClassName,
448 StringRef CategoryName,
450 bool isClassMethodList);
455 virtual llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName);
459 llvm::Constant *GeneratePropertyList(
const Decl *Container,
461 bool isClassProperty=
false,
462 bool protocolOptionalProperties=
false);
472 void GenerateProtocolHolderCategory();
475 llvm::Constant *GenerateClassStructure(
476 llvm::Constant *MetaClass,
477 llvm::Constant *SuperClass,
480 llvm::Constant *Version,
481 llvm::Constant *InstanceSize,
482 llvm::Constant *IVars,
483 llvm::Constant *Methods,
484 llvm::Constant *Protocols,
485 llvm::Constant *IvarOffsets,
486 llvm::Constant *Properties,
487 llvm::Constant *StrongIvarBitmap,
488 llvm::Constant *WeakIvarBitmap,
493 virtual llvm::Constant *GenerateProtocolMethodList(
497 void EmitProtocolMethodList(T &&Methods, llvm::Constant *&Required,
501 for (
const auto *I : Methods)
503 OptionalMethods.push_back(I);
505 RequiredMethods.push_back(I);
506 Required = GenerateProtocolMethodList(RequiredMethods);
507 Optional = GenerateProtocolMethodList(OptionalMethods);
520 const std::string Name =
"__objc_ivar_offset_" +
ID->getNameAsString()
539 llvm::Value *&Receiver,
542 MessageSendInfo &MSI) = 0;
550 MessageSendInfo &MSI) = 0;
567 unsigned protocolClassVersion,
unsigned classABI=1);
574 llvm::Value *Receiver,
const CallArgList &CallArgs,
581 bool isCategoryImpl, llvm::Value *Receiver,
590 virtual llvm::Constant *GetConstantSelector(
Selector Sel,
592 llvm_unreachable(
"Runtime unable to generate constant selector");
598 llvm::Constant *GetEHType(
QualType T)
override;
602 void GenerateDirectMethodPrologue(
CodeGenFunction &CGF, llvm::Function *Fn,
615 return GenerateProtocolRef(PD);
618 llvm::Function *ModuleInitFunction()
override;
619 llvm::FunctionCallee GetPropertyGetFunction()
override;
620 llvm::FunctionCallee GetPropertySetFunction()
override;
621 llvm::FunctionCallee GetOptimizedPropertySetFunction(
bool atomic,
623 llvm::FunctionCallee GetSetStructFunction()
override;
624 llvm::FunctionCallee GetGetStructFunction()
override;
625 llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override;
626 llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override;
627 llvm::FunctionCallee EnumerationMutationFunction()
override;
635 bool ClearInsertionPoint=
true)
override;
639 llvm::Value *src,
Address dst)
override;
641 llvm::Value *src,
Address dest,
642 bool threadlocal=
false)
override;
644 Address dest, llvm::Value *ivarOffset)
override;
646 llvm::Value *src,
Address dest)
override;
649 llvm::Value *Size)
override;
652 unsigned CVRQualifiers)
override;
656 llvm::Value *EmitNSAutoreleasePoolClassRef(
CodeGenFunction &CGF)
override;
679 class CGObjCGCC :
public CGObjCGNU {
682 LazyRuntimeFunction MsgLookupFn;
686 LazyRuntimeFunction MsgLookupSuperFn;
690 llvm::Value *cmd, llvm::MDNode *
node,
691 MessageSendInfo &MSI)
override {
693 llvm::Value *args[] = {
694 EnforceType(Builder, Receiver, IdTy),
695 EnforceType(Builder, cmd, SelectorTy) };
697 imp->setMetadata(msgSendMDKind,
node);
702 llvm::Value *cmd, MessageSendInfo &MSI)
override {
704 llvm::Value *lookupArgs[] = {
705 EnforceType(Builder, ObjCSuper.
getPointer(), PtrToObjCSuperTy), cmd};
712 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
714 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
715 PtrToObjCSuperTy, SelectorTy);
720 class CGObjCGNUstep :
public CGObjCGNU {
723 LazyRuntimeFunction SlotLookupFn;
728 LazyRuntimeFunction SlotLookupSuperFn;
730 LazyRuntimeFunction SetPropertyAtomic;
732 LazyRuntimeFunction SetPropertyAtomicCopy;
734 LazyRuntimeFunction SetPropertyNonAtomic;
736 LazyRuntimeFunction SetPropertyNonAtomicCopy;
739 LazyRuntimeFunction CxxAtomicObjectGetFn;
742 LazyRuntimeFunction CxxAtomicObjectSetFn;
747 llvm::Type *SlotStructTy;
750 llvm::Constant *GetEHType(
QualType T)
override;
754 llvm::Value *cmd, llvm::MDNode *
node,
755 MessageSendInfo &MSI)
override {
757 llvm::FunctionCallee LookupFn = SlotLookupFn;
762 Builder.CreateStore(Receiver, ReceiverPtr);
769 self = llvm::ConstantPointerNull::get(IdTy);
773 if (
auto *LookupFn2 = dyn_cast<llvm::Function>(LookupFn.getCallee()))
774 LookupFn2->addParamAttr(0, llvm::Attribute::NoCapture);
776 llvm::Value *args[] = {
777 EnforceType(Builder, ReceiverPtr.
getPointer(), PtrToIdTy),
778 EnforceType(Builder, cmd, SelectorTy),
779 EnforceType(Builder,
self, IdTy) };
781 slot->setOnlyReadsMemory();
782 slot->setMetadata(msgSendMDKind,
node);
785 llvm::Value *imp = Builder.CreateAlignedLoad(
786 IMPTy, Builder.CreateStructGEP(SlotStructTy, slot, 4),
791 Receiver = Builder.CreateLoad(ReceiverPtr,
true);
797 MessageSendInfo &MSI)
override {
799 llvm::Value *lookupArgs[] = {ObjCSuper.
getPointer(), cmd};
801 llvm::CallInst *slot =
803 slot->setOnlyReadsMemory();
805 return Builder.CreateAlignedLoad(
806 IMPTy, Builder.CreateStructGEP(SlotStructTy, slot, 4),
811 CGObjCGNUstep(
CodeGenModule &Mod) : CGObjCGNUstep(Mod, 9, 3, 1) {}
812 CGObjCGNUstep(
CodeGenModule &Mod,
unsigned ABI,
unsigned ProtocolABI,
814 CGObjCGNU(Mod, ABI, ProtocolABI, ClassABI) {
817 SlotStructTy = llvm::StructType::get(PtrTy, PtrTy, PtrTy, IntTy, IMPTy);
818 SlotTy = llvm::PointerType::getUnqual(SlotStructTy);
820 SlotLookupFn.init(&CGM,
"objc_msg_lookup_sender", SlotTy, PtrToIdTy,
823 SlotLookupSuperFn.init(&CGM,
"objc_slot_lookup_super", SlotTy,
824 PtrToObjCSuperTy, SelectorTy);
826 if (usesSEHExceptions) {
827 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
829 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy);
831 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
833 EnterCatchFn.init(&CGM,
"__cxa_begin_catch", PtrTy, PtrTy);
835 ExitCatchFn.init(&CGM,
"__cxa_end_catch", VoidTy);
837 ExceptionReThrowFn.init(&CGM,
"_Unwind_Resume_or_Rethrow", VoidTy,
839 }
else if (R.
getVersion() >= VersionTuple(1, 7)) {
840 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
842 EnterCatchFn.init(&CGM,
"objc_begin_catch", IdTy, PtrTy);
844 ExitCatchFn.init(&CGM,
"objc_end_catch", VoidTy);
846 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy, PtrTy);
848 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
849 SetPropertyAtomic.init(&CGM,
"objc_setProperty_atomic", VoidTy, IdTy,
850 SelectorTy, IdTy, PtrDiffTy);
851 SetPropertyAtomicCopy.init(&CGM,
"objc_setProperty_atomic_copy", VoidTy,
852 IdTy, SelectorTy, IdTy, PtrDiffTy);
853 SetPropertyNonAtomic.init(&CGM,
"objc_setProperty_nonatomic", VoidTy,
854 IdTy, SelectorTy, IdTy, PtrDiffTy);
855 SetPropertyNonAtomicCopy.init(&CGM,
"objc_setProperty_nonatomic_copy",
856 VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy);
859 CxxAtomicObjectSetFn.init(&CGM,
"objc_setCppObjectAtomic", VoidTy, PtrTy,
863 CxxAtomicObjectGetFn.init(&CGM,
"objc_getCppObjectAtomic", VoidTy, PtrTy,
867 llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override {
872 return CxxAtomicObjectGetFn;
875 llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override {
880 return CxxAtomicObjectSetFn;
883 llvm::FunctionCallee GetOptimizedPropertySetFunction(
bool atomic,
884 bool copy)
override {
895 if (copy)
return SetPropertyAtomicCopy;
896 return SetPropertyAtomic;
899 return copy ? SetPropertyNonAtomicCopy : SetPropertyNonAtomic;
906 class CGObjCGNUstep2 :
public CGObjCGNUstep {
911 ClassReferenceSection,
914 ProtocolReferenceSection,
916 ConstantStringSection
918 static const char *
const SectionsBaseNames[8];
919 static const char *
const PECOFFSectionsBaseNames[8];
920 template<SectionKind K>
922 if (CGM.
getTriple().isOSBinFormatCOFF()) {
927 return SectionsBaseNames[K];
932 LazyRuntimeFunction MsgLookupSuperFn;
936 bool EmittedProtocol =
false;
941 bool EmittedProtocolRef =
false;
945 bool EmittedClass =
false;
949 typedef std::pair<std::string, std::pair<llvm::GlobalVariable*, int>>
951 std::vector<EarlyInitPair> EarlyInitList;
953 std::string SymbolForClassRef(StringRef Name,
bool isWeak) {
955 return (ManglePublicSymbol(
"OBJC_WEAK_REF_CLASS_") + Name).str();
957 return (ManglePublicSymbol(
"OBJC_REF_CLASS_") + Name).str();
961 return (ManglePublicSymbol(
"OBJC_CLASS_") + Name).str();
963 void CallRuntimeFunction(
CGBuilderTy &B, StringRef FunctionName,
966 for (
auto *Arg : Args)
967 Types.push_back(Arg->getType());
968 llvm::FunctionType *FT = llvm::FunctionType::get(B.getVoidTy(), Types,
971 B.CreateCall(Fn, Args);
980 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
981 if (old != ObjCStrings.end())
989 (LiteralLength < 9) && !isNonASCII) {
995 for (
unsigned i=0 ; i<LiteralLength ; i++)
998 str |= LiteralLength << 3;
1001 auto *ObjCStr = llvm::ConstantExpr::getIntToPtr(
1002 llvm::ConstantInt::get(Int64Ty, str), IdTy);
1003 ObjCStrings[Str] = ObjCStr;
1009 if (StringClass.empty()) StringClass =
"NSConstantString";
1013 llvm::Constant *
isa = TheModule.getNamedGlobal(Sym);
1016 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
1018 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1019 cast<llvm::GlobalValue>(
isa)->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
1021 }
else if (
isa->getType() != PtrToIdTy)
1022 isa = llvm::ConstantExpr::getBitCast(
isa, PtrToIdTy);
1035 auto Fields = Builder.beginStruct();
1036 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
1039 Fields.addNullPointer(PtrTy);
1046 unsigned NumU8CodeUnits = Str.size();
1051 const llvm::UTF8 *FromPtr = (
const llvm::UTF8 *)Str.data();
1052 llvm::UTF16 *ToPtr = &ToBuf[0];
1053 (void)llvm::ConvertUTF8toUTF16(&FromPtr, FromPtr + NumU8CodeUnits,
1054 &ToPtr, ToPtr + NumU8CodeUnits, llvm::strictConversion);
1055 uint32_t StringLength = ToPtr - &ToBuf[0];
1059 Fields.addInt(Int32Ty, 2);
1061 Fields.addInt(Int32Ty, StringLength);
1063 Fields.addInt(Int32Ty, StringLength * 2);
1065 Fields.addInt(Int32Ty, 0);
1068 auto *
C = llvm::ConstantDataArray::get(VMContext, Arr);
1069 auto *Buffer =
new llvm::GlobalVariable(TheModule,
C->getType(),
1070 true, llvm::GlobalValue::PrivateLinkage, C,
".str");
1071 Buffer->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1075 Fields.addInt(Int32Ty, 0);
1077 Fields.addInt(Int32Ty, Str.size());
1079 Fields.addInt(Int32Ty, Str.size());
1081 Fields.addInt(Int32Ty, 0);
1083 Fields.add(MakeConstantString(Str));
1088 StringName =
".objc_str_";
1089 for (
int i=0,e=Str.size() ; i<e ; ++i) {
1090 unsigned char c = Str[i];
1101 llvm::GlobalVariable *ObjCStrGV =
1103 isNamed ? StringRef(StringName) :
".objc_string",
1104 Align,
false,
isNamed ? llvm::GlobalValue::LinkOnceODRLinkage
1105 : llvm::GlobalValue::PrivateLinkage);
1106 ObjCStrGV->setSection(sectionName<ConstantStringSection>());
1108 ObjCStrGV->setComdat(TheModule.getOrInsertComdat(StringName));
1111 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1112 std::pair<llvm::GlobalVariable*, int>
v{ObjCStrGV, 0};
1113 EarlyInitList.emplace_back(Sym,
v);
1115 llvm::Constant *ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStrGV, IdTy);
1116 ObjCStrings[Str] = ObjCStr;
1117 ConstantStrings.push_back(ObjCStr);
1124 bool isSynthesized=
true,
bool
1125 isDynamic=
true)
override {
1134 auto Fields = PropertiesArray.
beginStruct(PropertyMetadataTy);
1139 Fields.add(MakeConstantString(TypeStr));
1142 Fields.add(MakeConstantString(typeStr));
1146 Fields.add(GetConstantSelector(accessor->getSelector(), TypeStr));
1148 Fields.add(NULLPtr);
1163 llvm::StructType *ObjCMethodDescTy =
1165 { PtrToInt8Ty, PtrToInt8Ty });
1174 auto MethodList = Builder.beginStruct();
1176 MethodList.addInt(IntTy, Methods.size());
1178 llvm::DataLayout td(&TheModule);
1179 MethodList.addInt(IntTy, td.getTypeSizeInBits(ObjCMethodDescTy) /
1182 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
1183 for (
auto *M : Methods) {
1184 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
1185 Method.add(CGObjCGNU::GetConstantSelector(M));
1187 Method.finishAndAddTo(MethodArray);
1189 MethodArray.finishAndAddTo(MethodList);
1190 return MethodList.finishAndCreateGlobal(
".objc_protocol_method_list",
1196 auto RuntimeProtocols = GetRuntimeProtocolList(ReferencedProtocols.begin(),
1197 ReferencedProtocols.end());
1199 for (
const auto *PI : RuntimeProtocols)
1200 Protocols.push_back(
1201 llvm::ConstantExpr::getBitCast(GenerateProtocolRef(PI),
1203 return GenerateProtocolList(Protocols);
1207 llvm::Value *cmd, MessageSendInfo &MSI)
override {
1210 llvm::Value *lookupArgs[] = {CGObjCGNU::EnforceType(Builder,
1217 llvm::GlobalVariable *GetClassVar(StringRef Name,
bool isWeak=
false) {
1218 std::string SymbolName = SymbolForClassRef(Name, isWeak);
1219 auto *ClassSymbol = TheModule.getNamedGlobal(SymbolName);
1222 ClassSymbol =
new llvm::GlobalVariable(TheModule,
1224 nullptr, SymbolName);
1230 ClassSymbol->setInitializer(
new llvm::GlobalVariable(TheModule,
1231 Int8Ty,
false, llvm::GlobalValue::ExternalWeakLinkage,
1232 nullptr, SymbolForClass(Name)));
1234 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1240 for (
const auto *Result : DC->
lookup(&II))
1241 if ((OID = dyn_cast<ObjCInterfaceDecl>(Result)))
1247 assert(OID &&
"Failed to find ObjCInterfaceDecl");
1249 if (OIDDef !=
nullptr)
1252 auto Storage = llvm::GlobalValue::DefaultStorageClass;
1253 if (OID->
hasAttr<DLLImportAttr>())
1254 Storage = llvm::GlobalValue::DLLImportStorageClass;
1255 else if (OID->
hasAttr<DLLExportAttr>())
1256 Storage = llvm::GlobalValue::DLLExportStorageClass;
1258 cast<llvm::GlobalValue>(ClassSymbol)->setDLLStorageClass(Storage);
1261 assert(ClassSymbol->getName() == SymbolName);
1266 bool isWeak)
override {
1278 switch (Ownership) {
1300 llvm_unreachable(
"Method should not be called!");
1303 llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName)
override {
1304 std::string Name = SymbolForProtocol(ProtocolName);
1305 auto *GV = TheModule.getGlobalVariable(Name);
1308 GV =
new llvm::GlobalVariable(TheModule, ProtocolTy,
false,
1312 return llvm::ConstantExpr::getBitCast(GV, ProtocolPtrTy);
1316 llvm::StringMap<llvm::Constant*> ExistingProtocolRefs;
1321 auto *&Ref = ExistingProtocolRefs[Name];
1323 auto *&
Protocol = ExistingProtocols[Name];
1325 Protocol = GenerateProtocolRef(PD);
1327 assert(!TheModule.getGlobalVariable(RefName));
1329 auto GV =
new llvm::GlobalVariable(TheModule, ProtocolPtrTy,
1330 false, llvm::GlobalValue::LinkOnceODRLinkage,
1331 llvm::ConstantExpr::getBitCast(Protocol, ProtocolPtrTy), RefName);
1332 GV->setComdat(TheModule.getOrInsertComdat(RefName));
1333 GV->setSection(sectionName<ProtocolReferenceSection>());
1337 EmittedProtocolRef =
true;
1343 llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(ProtocolPtrTy,
1345 llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
1348 auto ProtocolBuilder = builder.beginStruct();
1349 ProtocolBuilder.addNullPointer(PtrTy);
1350 ProtocolBuilder.addInt(SizeTy, Protocols.size());
1351 ProtocolBuilder.add(ProtocolArray);
1352 return ProtocolBuilder.finishAndCreateGlobal(
".objc_protocol_list",
1361 auto *&
Protocol = ExistingProtocols[ProtocolName];
1365 EmittedProtocol =
true;
1367 auto SymName = SymbolForProtocol(ProtocolName);
1368 auto *OldGV = TheModule.getGlobalVariable(SymName);
1378 Protocol =
new llvm::GlobalVariable(TheModule, ProtocolTy,
1385 auto RuntimeProtocols =
1387 for (
const auto *PI : RuntimeProtocols)
1388 Protocols.push_back(
1389 llvm::ConstantExpr::getBitCast(GenerateProtocolRef(PI),
1391 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
1394 llvm::Constant *InstanceMethodList, *OptionalInstanceMethodList;
1395 llvm::Constant *ClassMethodList, *OptionalClassMethodList;
1397 OptionalInstanceMethodList);
1398 EmitProtocolMethodList(PD->
class_methods(), ClassMethodList,
1399 OptionalClassMethodList);
1404 auto ProtocolBuilder = builder.beginStruct();
1405 ProtocolBuilder.add(llvm::ConstantExpr::getIntToPtr(
1406 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
1407 ProtocolBuilder.add(MakeConstantString(ProtocolName));
1408 ProtocolBuilder.add(ProtocolList);
1409 ProtocolBuilder.add(InstanceMethodList);
1410 ProtocolBuilder.add(ClassMethodList);
1411 ProtocolBuilder.add(OptionalInstanceMethodList);
1412 ProtocolBuilder.add(OptionalClassMethodList);
1414 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
false,
false));
1416 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
false,
true));
1418 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
true,
false));
1420 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
true,
true));
1422 auto *GV = ProtocolBuilder.finishAndCreateGlobal(SymName,
1424 GV->setSection(sectionName<ProtocolSection>());
1425 GV->setComdat(TheModule.getOrInsertComdat(SymName));
1427 OldGV->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(GV,
1429 OldGV->removeFromParent();
1430 GV->setName(SymName);
1435 llvm::Constant *EnforceType(llvm::Constant *Val, llvm::Type *Ty) {
1436 if (Val->getType() == Ty)
1438 return llvm::ConstantExpr::getBitCast(Val, Ty);
1442 return GetConstantSelector(Sel, TypeEncoding);
1444 llvm::Constant *GetTypeString(llvm::StringRef TypeEncoding) {
1445 if (TypeEncoding.empty())
1448 std::replace(MangledTypes.begin(), MangledTypes.end(),
1450 std::string TypesVarName =
".objc_sel_types_" + MangledTypes;
1451 auto *TypesGlobal = TheModule.getGlobalVariable(TypesVarName);
1453 llvm::Constant *Init = llvm::ConstantDataArray::getString(VMContext,
1455 auto *GV =
new llvm::GlobalVariable(TheModule, Init->getType(),
1456 true, llvm::GlobalValue::LinkOnceODRLinkage, Init, TypesVarName);
1457 GV->setComdat(TheModule.getOrInsertComdat(TypesVarName));
1461 return llvm::ConstantExpr::getGetElementPtr(TypesGlobal->getValueType(),
1462 TypesGlobal, Zeros);
1464 llvm::Constant *GetConstantSelector(
Selector Sel,
1471 std::replace(MangledTypes.begin(), MangledTypes.end(),
1473 auto SelVarName = (StringRef(
".objc_selector_") + Sel.
getAsString() +
"_" +
1474 MangledTypes).str();
1475 if (
auto *GV = TheModule.getNamedGlobal(SelVarName))
1476 return EnforceType(GV, SelectorTy);
1478 auto SelBuilder = builder.beginStruct();
1479 SelBuilder.add(ExportUniqueString(Sel.
getAsString(),
".objc_sel_name_",
1481 SelBuilder.add(GetTypeString(TypeEncoding));
1482 auto *GV = SelBuilder.finishAndCreateGlobal(SelVarName,
1484 GV->setComdat(TheModule.getOrInsertComdat(SelVarName));
1486 GV->setSection(sectionName<SelectorSection>());
1487 auto *SelVal = EnforceType(GV, SelectorTy);
1490 llvm::StructType *emptyStruct =
nullptr;
1499 std::pair<llvm::Constant*,llvm::Constant*>
1500 GetSectionBounds(StringRef Section) {
1501 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1502 if (emptyStruct ==
nullptr) {
1504 emptyStruct->setBody({},
true);
1506 auto ZeroInit = llvm::Constant::getNullValue(emptyStruct);
1507 auto Sym = [&](StringRef Prefix, StringRef SecSuffix) {
1508 auto *Sym =
new llvm::GlobalVariable(TheModule, emptyStruct,
1510 llvm::GlobalValue::LinkOnceODRLinkage, ZeroInit, Prefix +
1513 Sym->setSection((Section + SecSuffix).str());
1514 Sym->setComdat(TheModule.getOrInsertComdat((Prefix +
1519 return { Sym(
"__start_",
"$a"), Sym(
"__stop",
"$z") };
1521 auto *Start =
new llvm::GlobalVariable(TheModule, PtrTy,
1526 auto *Stop =
new llvm::GlobalVariable(TheModule, PtrTy,
1531 return { Start, Stop };
1536 llvm::Function *ModuleInitFunction()
override {
1537 llvm::Function *LoadFunction = llvm::Function::Create(
1538 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
1539 llvm::GlobalValue::LinkOnceODRLinkage,
".objcv2_load_function",
1542 LoadFunction->setComdat(TheModule.getOrInsertComdat(
".objcv2_load_function"));
1544 llvm::BasicBlock *EntryBB =
1545 llvm::BasicBlock::Create(VMContext,
"entry", LoadFunction);
1547 B.SetInsertPoint(EntryBB);
1549 auto InitStructBuilder = builder.beginStruct();
1550 InitStructBuilder.addInt(Int64Ty, 0);
1551 auto §ionVec = CGM.
getTriple().isOSBinFormatCOFF() ? PECOFFSectionsBaseNames : SectionsBaseNames;
1552 for (
auto *
s : sectionVec) {
1553 auto bounds = GetSectionBounds(
s);
1554 InitStructBuilder.add(bounds.first);
1555 InitStructBuilder.add(bounds.second);
1557 auto *InitStruct = InitStructBuilder.finishAndCreateGlobal(
".objc_init",
1560 InitStruct->setComdat(TheModule.getOrInsertComdat(
".objc_init"));
1562 CallRuntimeFunction(B,
"__objc_load", {InitStruct});;
1569 auto *InitVar =
new llvm::GlobalVariable(TheModule, LoadFunction->getType(),
1570 false, llvm::GlobalValue::LinkOnceAnyLinkage,
1571 LoadFunction,
".objc_ctor");
1574 assert(InitVar->getName() ==
".objc_ctor");
1580 if (CGM.
getTriple().isOSBinFormatCOFF())
1581 InitVar->setSection(
".CRT$XCLz");
1585 InitVar->setSection(
".init_array");
1587 InitVar->setSection(
".ctors");
1590 InitVar->setComdat(TheModule.getOrInsertComdat(
".objc_ctor"));
1592 for (
auto *C : Categories) {
1593 auto *Cat = cast<llvm::GlobalVariable>(
C->stripPointerCasts());
1594 Cat->setSection(sectionName<CategorySection>());
1598 StringRef Section) {
1599 auto nullBuilder = builder.beginStruct();
1600 for (
auto *F : Init)
1602 auto GV = nullBuilder.finishAndCreateGlobal(Name, CGM.
getPointerAlign(),
1603 false, llvm::GlobalValue::LinkOnceODRLinkage);
1604 GV->setSection(Section);
1605 GV->setComdat(TheModule.getOrInsertComdat(Name));
1610 for (
auto clsAlias : ClassAliases)
1611 createNullGlobal(
std::string(
".objc_class_alias") +
1612 clsAlias.second, { MakeConstantString(clsAlias.second),
1613 GetClassVar(clsAlias.first) }, sectionName<ClassAliasSection>());
1618 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
1619 createNullGlobal(
".objc_null_selector", {NULLPtr, NULLPtr},
1620 sectionName<SelectorSection>());
1621 if (Categories.empty())
1622 createNullGlobal(
".objc_null_category", {NULLPtr, NULLPtr,
1623 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr},
1624 sectionName<CategorySection>());
1625 if (!EmittedClass) {
1626 createNullGlobal(
".objc_null_cls_init_ref", NULLPtr,
1627 sectionName<ClassSection>());
1628 createNullGlobal(
".objc_null_class_ref", { NULLPtr, NULLPtr },
1629 sectionName<ClassReferenceSection>());
1631 if (!EmittedProtocol)
1632 createNullGlobal(
".objc_null_protocol", {NULLPtr, NULLPtr, NULLPtr,
1633 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr,
1634 NULLPtr}, sectionName<ProtocolSection>());
1635 if (!EmittedProtocolRef)
1636 createNullGlobal(
".objc_null_protocol_ref", {NULLPtr},
1637 sectionName<ProtocolReferenceSection>());
1638 if (ClassAliases.empty())
1639 createNullGlobal(
".objc_null_class_alias", { NULLPtr, NULLPtr },
1640 sectionName<ClassAliasSection>());
1641 if (ConstantStrings.empty()) {
1642 auto i32Zero = llvm::ConstantInt::get(Int32Ty, 0);
1643 createNullGlobal(
".objc_null_constant_string", { NULLPtr, i32Zero,
1644 i32Zero, i32Zero, i32Zero, NULLPtr },
1645 sectionName<ConstantStringSection>());
1648 ConstantStrings.clear();
1652 if (EarlyInitList.size() > 0) {
1653 auto *Init = llvm::Function::Create(llvm::FunctionType::get(CGM.
VoidTy,
1656 llvm::IRBuilder<>
b(llvm::BasicBlock::Create(CGM.
getLLVMContext(),
"entry",
1658 for (
const auto &lateInit : EarlyInitList) {
1659 auto *global = TheModule.getGlobalVariable(lateInit.first);
1661 llvm::GlobalVariable *GV = lateInit.second.first;
1662 b.CreateAlignedStore(
1664 b.CreateStructGEP(GV->getValueType(), GV, lateInit.second.second),
1671 auto *InitVar =
new llvm::GlobalVariable(CGM.
getModule(), Init->getType(),
1673 Init,
".objc_early_init_ptr");
1674 InitVar->setSection(
".CRT$XCLb");
1686 std::replace(TypeEncoding.begin(), TypeEncoding.end(),
1688 const std::string Name =
"__objc_ivar_offset_" +
ID->getNameAsString()
1696 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
1697 if (!IvarOffsetPointer)
1698 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule, IntTy,
false,
1703 if (
Offset->getType() != PtrDiffTy)
1709 bool IsCOFF = CGM.
getTriple().isOSBinFormatCOFF();
1715 auto *classNameConstant = MakeConstantString(className);
1718 auto metaclassFields = builder.beginStruct();
1720 metaclassFields.addNullPointer(PtrTy);
1722 metaclassFields.addNullPointer(PtrTy);
1724 metaclassFields.add(classNameConstant);
1726 metaclassFields.addInt(LongTy, 0);
1729 metaclassFields.addInt(LongTy, 1);
1733 metaclassFields.addInt(LongTy, 0);
1735 metaclassFields.addNullPointer(PtrTy);
1740 metaclassFields.addNullPointer(PtrTy);
1745 metaclassFields.addBitCast(
1746 GenerateMethodList(className,
"", ClassMethods,
true),
1750 metaclassFields.addNullPointer(PtrTy);
1752 metaclassFields.addNullPointer(PtrTy);
1754 metaclassFields.addNullPointer(PtrTy);
1756 metaclassFields.addNullPointer(PtrTy);
1758 metaclassFields.addNullPointer(PtrTy);
1760 metaclassFields.addNullPointer(PtrTy);
1762 metaclassFields.addNullPointer(PtrTy);
1764 metaclassFields.addInt(LongTy, 0);
1766 metaclassFields.add(GeneratePropertyList(OID, classDecl,
true));
1768 auto *metaclass = metaclassFields.finishAndCreateGlobal(
1769 ManglePublicSymbol(
"OBJC_METACLASS_") + className,
1772 auto classFields = builder.beginStruct();
1774 classFields.add(metaclass);
1779 llvm::Constant *SuperClass =
nullptr;
1780 if (SuperClassDecl) {
1781 auto SuperClassName = SymbolForClass(SuperClassDecl->
getNameAsString());
1782 SuperClass = TheModule.getNamedGlobal(SuperClassName);
1785 SuperClass =
new llvm::GlobalVariable(TheModule, PtrTy,
false,
1788 auto Storage = llvm::GlobalValue::DefaultStorageClass;
1789 if (SuperClassDecl->
hasAttr<DLLImportAttr>())
1790 Storage = llvm::GlobalValue::DLLImportStorageClass;
1791 else if (SuperClassDecl->
hasAttr<DLLExportAttr>())
1792 Storage = llvm::GlobalValue::DLLExportStorageClass;
1794 cast<llvm::GlobalValue>(SuperClass)->setDLLStorageClass(Storage);
1798 classFields.add(llvm::ConstantExpr::getBitCast(SuperClass, PtrTy));
1800 classFields.addNullPointer(PtrTy);
1802 classFields.addNullPointer(PtrTy);
1804 classFields.add(classNameConstant);
1806 classFields.addInt(LongTy, 0);
1809 classFields.addInt(LongTy, 0);
1811 int superInstanceSize = !SuperClassDecl ? 0 :
1815 classFields.addInt(LongTy,
1817 superInstanceSize));
1820 classFields.addNullPointer(PtrTy);
1825 llvm::DataLayout td(&TheModule);
1828 auto ivarListBuilder =
b.beginStruct();
1830 ivarListBuilder.addInt(IntTy, ivar_count);
1832 llvm::StructType *ObjCIvarTy = llvm::StructType::get(
1838 ivarListBuilder.addInt(SizeTy, td.getTypeSizeInBits(ObjCIvarTy) /
1841 auto ivarArrayBuilder = ivarListBuilder.beginArray();
1844 auto ivarTy = IVD->getType();
1845 auto ivarBuilder = ivarArrayBuilder.beginStruct();
1847 ivarBuilder.add(MakeConstantString(IVD->getNameAsString()));
1852 ivarBuilder.add(MakeConstantString(TypeStr));
1854 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
1856 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy,
Offset);
1857 std::string OffsetName = GetIVarOffsetVariableName(classDecl, IVD);
1858 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
1860 OffsetVar->setInitializer(OffsetValue);
1862 OffsetVar =
new llvm::GlobalVariable(TheModule, IntTy,
1864 OffsetValue, OffsetName);
1865 auto ivarVisibility =
1871 OffsetVar->setVisibility(ivarVisibility);
1872 ivarBuilder.add(OffsetVar);
1874 ivarBuilder.addInt(Int32Ty,
1885 ivarBuilder.addInt(Int32Ty,
1886 (
align << 3) | (1<<2) |
1887 FlagsForOwnership(ivarTy.getQualifiers().getObjCLifetime()));
1888 ivarBuilder.finishAndAddTo(ivarArrayBuilder);
1890 ivarArrayBuilder.finishAndAddTo(ivarListBuilder);
1891 auto ivarList = ivarListBuilder.finishAndCreateGlobal(
".objc_ivar_list",
1893 llvm::GlobalValue::PrivateLinkage);
1894 classFields.add(ivarList);
1898 InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
1901 if (propImpl->getPropertyImplementation() ==
1904 if (OMD && OMD->hasBody())
1905 InstanceMethods.push_back(OMD);
1907 addIfExists(propImpl->getGetterMethodDecl());
1908 addIfExists(propImpl->getSetterMethodDecl());
1911 if (InstanceMethods.size() == 0)
1912 classFields.addNullPointer(PtrTy);
1914 classFields.addBitCast(
1915 GenerateMethodList(className,
"", InstanceMethods,
false),
1918 classFields.addNullPointer(PtrTy);
1920 classFields.addNullPointer(PtrTy);
1922 classFields.addNullPointer(PtrTy);
1924 classFields.addNullPointer(PtrTy);
1926 classFields.addNullPointer(PtrTy);
1928 auto RuntimeProtocols = GetRuntimeProtocolList(classDecl->
protocol_begin(),
1931 for (
const auto *I : RuntimeProtocols)
1932 Protocols.push_back(
1933 llvm::ConstantExpr::getBitCast(GenerateProtocolRef(I),
1935 if (Protocols.empty())
1936 classFields.addNullPointer(PtrTy);
1938 classFields.add(GenerateProtocolList(Protocols));
1940 classFields.addNullPointer(PtrTy);
1942 classFields.addInt(LongTy, 0);
1944 classFields.add(GeneratePropertyList(OID, classDecl));
1946 llvm::GlobalVariable *classStruct =
1947 classFields.finishAndCreateGlobal(SymbolForClass(className),
1950 auto *classRefSymbol = GetClassVar(className);
1951 classRefSymbol->setSection(sectionName<ClassReferenceSection>());
1952 classRefSymbol->setInitializer(llvm::ConstantExpr::getBitCast(classStruct, IdTy));
1957 classStruct->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1958 cast<llvm::GlobalValue>(classRefSymbol)->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1962 std::pair<llvm::GlobalVariable*, int>
v{classStruct, 1};
1963 EarlyInitList.emplace_back(
std::string(SuperClass->getName()),
1972 if (ClassPtrAlias) {
1973 ClassPtrAlias->replaceAllUsesWith(
1974 llvm::ConstantExpr::getBitCast(classStruct, IdTy));
1975 ClassPtrAlias->eraseFromParent();
1976 ClassPtrAlias =
nullptr;
1978 if (
auto Placeholder =
1979 TheModule.getNamedGlobal(SymbolForClass(className)))
1980 if (Placeholder != classStruct) {
1981 Placeholder->replaceAllUsesWith(
1982 llvm::ConstantExpr::getBitCast(classStruct, Placeholder->getType()));
1983 Placeholder->eraseFromParent();
1984 classStruct->setName(SymbolForClass(className));
1986 if (MetaClassPtrAlias) {
1987 MetaClassPtrAlias->replaceAllUsesWith(
1988 llvm::ConstantExpr::getBitCast(metaclass, IdTy));
1989 MetaClassPtrAlias->eraseFromParent();
1990 MetaClassPtrAlias =
nullptr;
1992 assert(classStruct->getName() == SymbolForClass(className));
1994 auto classInitRef =
new llvm::GlobalVariable(TheModule,
1996 classStruct, ManglePublicSymbol(
"OBJC_INIT_CLASS_") + className);
1997 classInitRef->setSection(sectionName<ClassSection>());
2000 EmittedClass =
true;
2003 CGObjCGNUstep2(
CodeGenModule &Mod) : CGObjCGNUstep(Mod, 10, 4, 2) {
2004 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
2005 PtrToObjCSuperTy, SelectorTy);
2014 PropertyMetadataTy =
2016 { PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty });
2021 const char *
const CGObjCGNUstep2::SectionsBaseNames[8] =
2025 "__objc_class_refs",
2028 "__objc_protocol_refs",
2029 "__objc_class_aliases",
2030 "__objc_constant_string"
2033 const char *
const CGObjCGNUstep2::PECOFFSectionsBaseNames[8] =
2046 class CGObjCObjFW:
public CGObjCGNU {
2050 LazyRuntimeFunction MsgLookupFn;
2053 LazyRuntimeFunction MsgLookupFnSRet;
2057 LazyRuntimeFunction MsgLookupSuperFn, MsgLookupSuperFnSRet;
2060 llvm::Value *cmd, llvm::MDNode *
node,
2061 MessageSendInfo &MSI)
override {
2063 llvm::Value *args[] = {
2064 EnforceType(Builder, Receiver, IdTy),
2065 EnforceType(Builder, cmd, SelectorTy) };
2067 llvm::CallBase *imp;
2073 imp->setMetadata(msgSendMDKind,
node);
2078 llvm::Value *cmd, MessageSendInfo &MSI)
override {
2080 llvm::Value *lookupArgs[] = {
2081 EnforceType(Builder, ObjCSuper.
getPointer(), PtrToObjCSuperTy), cmd,
2091 bool isWeak)
override {
2093 return CGObjCGNU::GetClassNamed(CGF, Name, isWeak);
2097 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(SymbolName);
2099 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
2101 nullptr, SymbolName);
2108 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
2109 MsgLookupFnSRet.init(&CGM,
"objc_msg_lookup_stret", IMPTy, IdTy,
2112 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
2113 PtrToObjCSuperTy, SelectorTy);
2114 MsgLookupSuperFnSRet.init(&CGM,
"objc_msg_lookup_super_stret", IMPTy,
2115 PtrToObjCSuperTy, SelectorTy);
2123 void CGObjCGNU::EmitClassRef(
const std::string &className) {
2124 std::string symbolRef =
"__objc_class_ref_" + className;
2126 if (TheModule.getGlobalVariable(symbolRef))
2128 std::string symbolName =
"__objc_class_name_" + className;
2129 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
2131 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
2133 nullptr, symbolName);
2135 new llvm::GlobalVariable(TheModule, ClassSymbol->getType(),
true,
2136 llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef);
2139 CGObjCGNU::CGObjCGNU(
CodeGenModule &cgm,
unsigned runtimeABIVersion,
2140 unsigned protocolClassVersion,
unsigned classABI)
2142 VMContext(cgm.getLLVMContext()), ClassPtrAlias(nullptr),
2143 MetaClassPtrAlias(nullptr), RuntimeVersion(runtimeABIVersion),
2144 ProtocolVersion(protocolClassVersion), ClassABIVersion(classABI) {
2146 msgSendMDKind = VMContext.getMDKindID(
"GNUObjCMessageSend");
2151 IntTy = cast<llvm::IntegerType>(
2153 LongTy = cast<llvm::IntegerType>(
2155 SizeTy = cast<llvm::IntegerType>(
2157 PtrDiffTy = cast<llvm::IntegerType>(
2161 Int8Ty = llvm::Type::getInt8Ty(VMContext);
2163 PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
2164 ProtocolPtrTy = llvm::PointerType::getUnqual(
2167 Zeros[0] = llvm::ConstantInt::get(LongTy, 0);
2168 Zeros[1] = Zeros[0];
2169 NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty);
2173 SelectorTy = PtrToInt8Ty;
2174 SelectorElemTy = Int8Ty;
2180 PtrToIntTy = llvm::PointerType::getUnqual(IntTy);
2181 PtrTy = PtrToInt8Ty;
2183 Int32Ty = llvm::Type::getInt32Ty(VMContext);
2184 Int64Ty = llvm::Type::getInt64Ty(VMContext);
2201 PtrToIdTy = llvm::PointerType::getUnqual(IdTy);
2202 ProtocolTy = llvm::StructType::get(IdTy,
2225 PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty,
2226 PtrToInt8Ty, PtrToInt8Ty });
2228 ObjCSuperTy = llvm::StructType::get(IdTy, IdTy);
2229 PtrToObjCSuperTy = llvm::PointerType::getUnqual(ObjCSuperTy);
2231 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
2234 ExceptionThrowFn.init(&
CGM,
"objc_exception_throw", VoidTy, IdTy);
2235 ExceptionReThrowFn.init(&
CGM,
"objc_exception_throw", VoidTy, IdTy);
2237 SyncEnterFn.init(&
CGM,
"objc_sync_enter", IntTy, IdTy);
2239 SyncExitFn.init(&
CGM,
"objc_sync_exit", IntTy, IdTy);
2242 EnumerationMutationFn.init(&
CGM,
"objc_enumerationMutation", VoidTy, IdTy);
2245 GetPropertyFn.init(&
CGM,
"objc_getProperty", IdTy, IdTy, SelectorTy,
2248 SetPropertyFn.init(&
CGM,
"objc_setProperty", VoidTy, IdTy, SelectorTy,
2249 PtrDiffTy, IdTy, BoolTy, BoolTy);
2251 GetStructPropertyFn.init(&
CGM,
"objc_getPropertyStruct", VoidTy, PtrTy, PtrTy,
2252 PtrDiffTy, BoolTy, BoolTy);
2254 SetStructPropertyFn.init(&
CGM,
"objc_setPropertyStruct", VoidTy, PtrTy, PtrTy,
2255 PtrDiffTy, BoolTy, BoolTy);
2258 llvm::Type *IMPArgs[] = { IdTy, SelectorTy };
2259 IMPTy = llvm::PointerType::getUnqual(llvm::FunctionType::get(IdTy, IMPArgs,
2264 RuntimeVersion = 10;
2279 IvarAssignFn.init(&
CGM,
"objc_assign_ivar", IdTy, IdTy, IdTy, PtrDiffTy);
2281 StrongCastAssignFn.init(&
CGM,
"objc_assign_strongCast", IdTy, IdTy,
2284 GlobalAssignFn.init(&
CGM,
"objc_assign_global", IdTy, IdTy, PtrToIdTy);
2286 WeakAssignFn.init(&
CGM,
"objc_assign_weak", IdTy, IdTy, PtrToIdTy);
2288 WeakReadFn.init(&
CGM,
"objc_read_weak", IdTy, PtrToIdTy);
2290 MemMoveFn.init(&
CGM,
"objc_memmove_collectable", PtrTy, PtrTy, PtrTy,
2297 llvm::Constant *ClassName = MakeConstantString(Name);
2309 llvm::FunctionType::get(IdTy, PtrToInt8Ty,
true),
"objc_lookup_class");
2319 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value))
2324 llvm::Value *CGObjCGNU::EmitNSAutoreleasePoolClassRef(
CodeGenFunction &CGF) {
2325 auto *
Value = GetClassNamed(CGF,
"NSAutoreleasePool",
false);
2326 if (CGM.
getTriple().isOSBinFormatCOFF()) {
2327 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value)) {
2333 for (
const auto *Result : DC->
lookup(&II))
2334 if ((VD = dyn_cast<VarDecl>(Result)))
2346 llvm::GlobalAlias *SelValue =
nullptr;
2349 e = Types.end() ; i!=e ; i++) {
2350 if (i->first == TypeEncoding) {
2351 SelValue = i->second;
2357 llvm::GlobalValue::PrivateLinkage,
2360 Types.emplace_back(TypeEncoding, SelValue);
2367 llvm::Value *SelValue = GetSelector(CGF, Sel);
2384 return GetTypedSelector(CGF, Method->
getSelector(), SelTypes);
2387 llvm::Constant *CGObjCGNU::GetEHType(
QualType T) {
2394 return MakeConstantString(
"@id");
2402 assert(OPT &&
"Invalid @catch type.");
2404 assert(IDecl &&
"Invalid @catch type.");
2408 llvm::Constant *CGObjCGNUstep::GetEHType(
QualType T) {
2409 if (usesSEHExceptions)
2413 return CGObjCGNU::GetEHType(T);
2421 llvm::Constant *IDEHType =
2422 CGM.
getModule().getGlobalVariable(
"__objc_id_type_info");
2425 new llvm::GlobalVariable(CGM.
getModule(), PtrToInt8Ty,
2428 nullptr,
"__objc_id_type_info");
2429 return llvm::ConstantExpr::getBitCast(IDEHType, PtrToInt8Ty);
2434 assert(PT &&
"Invalid @catch type.");
2436 assert(IT &&
"Invalid @catch type.");
2440 std::string typeinfoName =
"__objc_eh_typeinfo_" + className;
2443 llvm::Constant *typeinfo = TheModule.getGlobalVariable(typeinfoName);
2445 return llvm::ConstantExpr::getBitCast(typeinfo, PtrToInt8Ty);
2452 const char *vtableName =
"_ZTVN7gnustep7libobjc22__objc_class_type_infoE";
2453 auto *Vtable = TheModule.getGlobalVariable(vtableName);
2455 Vtable =
new llvm::GlobalVariable(TheModule, PtrToInt8Ty,
true,
2457 nullptr, vtableName);
2459 llvm::Constant *Two = llvm::ConstantInt::get(IntTy, 2);
2460 auto *BVtable = llvm::ConstantExpr::getBitCast(
2461 llvm::ConstantExpr::getGetElementPtr(Vtable->getValueType(), Vtable, Two),
2464 llvm::Constant *typeName =
2465 ExportUniqueString(className,
"__objc_eh_typename_");
2468 auto fields = builder.beginStruct();
2469 fields.add(BVtable);
2470 fields.add(typeName);
2471 llvm::Constant *TI =
2472 fields.finishAndCreateGlobal(
"__objc_eh_typeinfo_" + className,
2475 llvm::GlobalValue::LinkOnceODRLinkage);
2476 return llvm::ConstantExpr::getBitCast(TI, PtrToInt8Ty);
2486 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
2487 if (old != ObjCStrings.end())
2492 if (StringClass.empty()) StringClass =
"NSConstantString";
2497 llvm::Constant *
isa = TheModule.getNamedGlobal(Sym);
2500 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
2501 llvm::GlobalValue::ExternalWeakLinkage,
nullptr, Sym);
2502 else if (
isa->getType() != PtrToIdTy)
2503 isa = llvm::ConstantExpr::getBitCast(
isa, PtrToIdTy);
2506 auto Fields = Builder.beginStruct();
2508 Fields.add(MakeConstantString(Str));
2509 Fields.addInt(IntTy, Str.size());
2510 llvm::Constant *ObjCStr =
2512 ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStr, PtrToInt8Ty);
2513 ObjCStrings[Str] = ObjCStr;
2514 ConstantStrings.push_back(ObjCStr);
2527 bool isCategoryImpl,
2528 llvm::Value *Receiver,
2529 bool IsClassMessage,
2534 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2538 if (Sel == ReleaseSel) {
2543 llvm::Value *cmd = GetSelector(CGF, Sel);
2546 ActualArgs.
add(
RValue::get(EnforceType(Builder, Receiver, IdTy)), ASTIdTy);
2550 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2552 llvm::Value *ReceiverClass =
nullptr;
2555 ReceiverClass = GetClassNamed(CGF,
2556 Class->getSuperClass()->getNameAsString(),
false);
2557 if (IsClassMessage) {
2559 ReceiverClass = Builder.CreateBitCast(ReceiverClass,
2560 llvm::PointerType::getUnqual(IdTy));
2562 Builder.CreateAlignedLoad(IdTy, ReceiverClass, CGF.
getPointerAlign());
2564 ReceiverClass = EnforceType(Builder, ReceiverClass, IdTy);
2566 if (isCategoryImpl) {
2567 llvm::FunctionCallee classLookupFunction =
nullptr;
2568 if (IsClassMessage) {
2570 IdTy, PtrTy,
true),
"objc_get_meta_class");
2573 IdTy, PtrTy,
true),
"objc_get_class");
2575 ReceiverClass = Builder.CreateCall(classLookupFunction,
2576 MakeConstantString(
Class->getNameAsString()));
2583 if (IsClassMessage) {
2584 if (!MetaClassPtrAlias) {
2587 ".objc_metaclass_ref" +
Class->getNameAsString(), &TheModule);
2589 ReceiverClass = MetaClassPtrAlias;
2591 if (!ClassPtrAlias) {
2594 ".objc_class_ref" +
Class->getNameAsString(), &TheModule);
2596 ReceiverClass = ClassPtrAlias;
2600 llvm::Type *CastTy = llvm::StructType::get(IdTy, IdTy);
2601 ReceiverClass = Builder.CreateBitCast(ReceiverClass,
2602 llvm::PointerType::getUnqual(CastTy));
2604 ReceiverClass = Builder.CreateStructGEP(CastTy, ReceiverClass, 1);
2607 Builder.CreateAlignedLoad(IdTy, ReceiverClass, CGF.
getPointerAlign());
2610 llvm::StructType *ObjCSuperTy =
2611 llvm::StructType::get(Receiver->getType(), IdTy);
2616 Builder.CreateStore(Receiver, Builder.CreateStructGEP(ObjCSuper, 0));
2617 Builder.CreateStore(ReceiverClass, Builder.CreateStructGEP(ObjCSuper, 1));
2620 llvm::Value *imp = LookupIMPSuper(CGF, ObjCSuper, cmd, MSI);
2621 imp = EnforceType(Builder, imp, MSI.MessengerType);
2623 llvm::Metadata *impMD[] = {
2624 llvm::MDString::get(VMContext, Sel.
getAsString()),
2625 llvm::MDString::get(VMContext,
Class->getSuperClass()->getNameAsString()),
2626 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2627 llvm::Type::getInt1Ty(VMContext), IsClassMessage))};
2628 llvm::MDNode *
node = llvm::MDNode::get(VMContext, impMD);
2632 llvm::CallBase *call;
2633 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2634 call->setMetadata(msgSendMDKind,
node);
2644 llvm::Value *Receiver,
2652 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2656 if (Sel == ReleaseSel) {
2664 cmd = GetSelector(CGF, Method);
2666 cmd = GetSelector(CGF, Sel);
2667 cmd = EnforceType(Builder, cmd, SelectorTy);
2668 Receiver = EnforceType(Builder, Receiver, IdTy);
2670 llvm::Metadata *impMD[] = {
2671 llvm::MDString::get(VMContext, Sel.
getAsString()),
2672 llvm::MDString::get(VMContext, Class ?
Class->getNameAsString() :
""),
2673 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2674 llvm::Type::getInt1Ty(VMContext), Class !=
nullptr))};
2675 llvm::MDNode *
node = llvm::MDNode::get(VMContext, impMD);
2682 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2703 bool hasParamDestroyedInCallee =
false;
2704 bool requiresExplicitZeroResult =
false;
2705 bool requiresNilReceiverCheck = [&] {
2707 if (!canMessageReceiverBeNull(CGF, Method,
false,
2713 hasParamDestroyedInCallee =
true;
2733 requiresExplicitZeroResult =
true;
2737 return hasParamDestroyedInCallee || requiresExplicitZeroResult;
2743 bool requiresExplicitAggZeroing =
2747 llvm::BasicBlock *continueBB =
nullptr;
2749 llvm::BasicBlock *nilPathBB =
nullptr;
2751 llvm::BasicBlock *nilCleanupBB =
nullptr;
2754 if (requiresNilReceiverCheck) {
2761 if (requiresExplicitAggZeroing || hasParamDestroyedInCallee) {
2764 nilPathBB = Builder.GetInsertBlock();
2767 llvm::Value *isNil = Builder.CreateICmpEQ(Receiver,
2768 llvm::Constant::getNullValue(Receiver->getType()));
2769 Builder.CreateCondBr(isNil, nilCleanupBB ? nilCleanupBB : continueBB,
2782 imp = LookupIMP(CGF, Receiver, cmd,
node, MSI);
2789 "objc_msgSend_fpret")
2796 "objc_msgSend_stret")
2800 llvm::FunctionType::get(IdTy, IdTy,
true),
"objc_msgSend")
2808 imp = EnforceType(Builder, imp, MSI.MessengerType);
2810 llvm::CallBase *call;
2812 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2813 call->setMetadata(msgSendMDKind,
node);
2815 if (requiresNilReceiverCheck) {
2816 llvm::BasicBlock *nonNilPathBB = CGF.
Builder.GetInsertBlock();
2817 CGF.
Builder.CreateBr(continueBB);
2823 if (hasParamDestroyedInCallee) {
2824 destroyCalleeDestroyedArguments(CGF, Method, CallArgs);
2827 if (requiresExplicitAggZeroing) {
2833 nilPathBB = CGF.
Builder.GetInsertBlock();
2834 CGF.
Builder.CreateBr(continueBB);
2842 llvm::PHINode *phi = Builder.CreatePHI(
v->getType(), 2);
2843 phi->addIncoming(
v, nonNilPathBB);
2851 llvm::PHINode *phi = Builder.CreatePHI(
v.first->getType(), 2);
2852 phi->addIncoming(
v.first, nonNilPathBB);
2853 phi->addIncoming(llvm::Constant::getNullValue(
v.first->getType()),
2855 llvm::PHINode *phi2 = Builder.CreatePHI(
v.second->getType(), 2);
2856 phi2->addIncoming(
v.second, nonNilPathBB);
2857 phi2->addIncoming(llvm::Constant::getNullValue(
v.second->getType()),
2867 llvm::Constant *CGObjCGNU::
2868 GenerateMethodList(StringRef ClassName,
2869 StringRef CategoryName,
2871 bool isClassMethodList) {
2872 if (Methods.empty())
2877 auto MethodList = Builder.beginStruct();
2878 MethodList.addNullPointer(CGM.
Int8PtrTy);
2879 MethodList.addInt(Int32Ty, Methods.size());
2882 llvm::StructType *ObjCMethodTy =
2891 llvm::DataLayout td(&TheModule);
2892 MethodList.addInt(SizeTy, td.getTypeSizeInBits(ObjCMethodTy) /
2908 auto MethodArray = MethodList.beginArray();
2910 for (
const auto *OMD : Methods) {
2911 llvm::Constant *FnPtr =
2912 TheModule.getFunction(getSymbolNameForMethod(OMD));
2913 assert(FnPtr &&
"Can't generate metadata for method that doesn't exist");
2914 auto Method = MethodArray.beginStruct(ObjCMethodTy);
2916 Method.addBitCast(FnPtr, IMPTy);
2917 Method.
add(GetConstantSelector(OMD->getSelector(),
2921 Method.
add(MakeConstantString(OMD->getSelector().getAsString()));
2923 Method.addBitCast(FnPtr, IMPTy);
2925 Method.finishAndAddTo(MethodArray);
2927 MethodArray.finishAndAddTo(MethodList);
2930 return MethodList.finishAndCreateGlobal(
".objc_method_list",
2935 llvm::Constant *CGObjCGNU::
2941 if (IvarNames.empty())
2947 auto IvarList = Builder.beginStruct();
2948 IvarList.addInt(IntTy, (
int)IvarNames.size());
2951 llvm::StructType *ObjCIvarTy =
2952 llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, IntTy);
2955 auto Ivars = IvarList.beginArray(ObjCIvarTy);
2956 for (
unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {
2957 auto Ivar = Ivars.beginStruct(ObjCIvarTy);
2958 Ivar.
add(IvarNames[i]);
2959 Ivar.
add(IvarTypes[i]);
2960 Ivar.
add(IvarOffsets[i]);
2961 Ivar.finishAndAddTo(Ivars);
2963 Ivars.finishAndAddTo(IvarList);
2966 return IvarList.finishAndCreateGlobal(
".objc_ivar_list",
2971 llvm::Constant *CGObjCGNU::GenerateClassStructure(
2972 llvm::Constant *MetaClass,
2973 llvm::Constant *SuperClass,
2976 llvm::Constant *Version,
2977 llvm::Constant *InstanceSize,
2978 llvm::Constant *IVars,
2979 llvm::Constant *Methods,
2980 llvm::Constant *Protocols,
2981 llvm::Constant *IvarOffsets,
2982 llvm::Constant *Properties,
2983 llvm::Constant *StrongIvarBitmap,
2984 llvm::Constant *WeakIvarBitmap,
2993 llvm::StructType *ClassTy = llvm::StructType::get(
3010 IvarOffsets->getType(),
3011 Properties->getType(),
3017 auto Elements = Builder.beginStruct(ClassTy);
3022 Elements.addBitCast(MetaClass, PtrToInt8Ty);
3024 Elements.add(SuperClass);
3026 Elements.add(MakeConstantString(Name,
".class_name"));
3028 Elements.addInt(LongTy, 0);
3030 Elements.addInt(LongTy, info);
3033 llvm::DataLayout td(&TheModule);
3034 Elements.addInt(LongTy,
3035 td.getTypeSizeInBits(ClassTy) /
3038 Elements.add(InstanceSize);
3040 Elements.add(IVars);
3042 Elements.add(Methods);
3045 Elements.add(NULLPtr);
3047 Elements.add(NULLPtr);
3049 Elements.add(NULLPtr);
3051 Elements.addBitCast(Protocols, PtrTy);
3053 Elements.add(NULLPtr);
3055 Elements.addInt(LongTy, ClassABIVersion);
3057 Elements.add(IvarOffsets);
3059 Elements.add(Properties);
3061 Elements.add(StrongIvarBitmap);
3063 Elements.add(WeakIvarBitmap);
3068 std::string ClassSym((isMeta ?
"_OBJC_METACLASS_":
"_OBJC_CLASS_") +
3070 llvm::GlobalVariable *ClassRef = TheModule.getNamedGlobal(ClassSym);
3071 llvm::Constant *
Class =
3072 Elements.finishAndCreateGlobal(ClassSym, CGM.
getPointerAlign(),
false,
3075 ClassRef->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(Class,
3076 ClassRef->getType()));
3077 ClassRef->removeFromParent();
3078 Class->setName(ClassSym);
3083 llvm::Constant *CGObjCGNU::
3086 llvm::StructType *ObjCMethodDescTy =
3087 llvm::StructType::get(CGM.
getLLVMContext(), { PtrToInt8Ty, PtrToInt8Ty });
3090 auto MethodList = Builder.beginStruct();
3091 MethodList.addInt(IntTy, Methods.size());
3092 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
3093 for (
auto *M : Methods) {
3094 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
3095 Method.
add(MakeConstantString(M->getSelector().getAsString()));
3097 Method.finishAndAddTo(MethodArray);
3099 MethodArray.finishAndAddTo(MethodList);
3100 return MethodList.finishAndCreateGlobal(
".objc_method_list",
3109 auto ProtocolList = Builder.beginStruct();
3110 ProtocolList.add(NULLPtr);
3111 ProtocolList.addInt(LongTy, Protocols.size());
3113 auto Elements = ProtocolList.beginArray(PtrToInt8Ty);
3114 for (
const std::string *iter = Protocols.begin(), *endIter = Protocols.end();
3115 iter != endIter ; iter++) {
3116 llvm::Constant *protocol =
nullptr;
3117 llvm::StringMap<llvm::Constant*>::iterator value =
3118 ExistingProtocols.find(*iter);
3119 if (value == ExistingProtocols.end()) {
3120 protocol = GenerateEmptyProtocol(*iter);
3122 protocol = value->getValue();
3124 Elements.addBitCast(protocol, PtrToInt8Ty);
3126 Elements.finishAndAddTo(ProtocolList);
3127 return ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
3133 auto protocol = GenerateProtocolRef(PD);
3136 return CGF.
Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(T));
3139 llvm::Constant *CGObjCGNU::GenerateProtocolRef(
const ObjCProtocolDecl *PD) {
3142 GenerateProtocol(PD);
3143 assert(protocol &&
"Unknown protocol");
3148 CGObjCGNU::GenerateEmptyProtocol(StringRef ProtocolName) {
3149 llvm::Constant *ProtocolList = GenerateProtocolList({});
3150 llvm::Constant *MethodList = GenerateProtocolMethodList({});
3151 MethodList = llvm::ConstantExpr::getBitCast(MethodList, PtrToInt8Ty);
3155 auto Elements = Builder.beginStruct();
3159 Elements.add(llvm::ConstantExpr::getIntToPtr(
3160 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3162 Elements.add(MakeConstantString(ProtocolName,
".objc_protocol_name"));
3163 Elements.add(ProtocolList);
3164 Elements.add(MethodList);
3165 Elements.add(MethodList);
3166 Elements.add(MethodList);
3167 Elements.add(MethodList);
3168 Elements.add(NULLPtr);
3169 Elements.add(NULLPtr);
3170 return Elements.finishAndCreateGlobal(SymbolForProtocol(ProtocolName),
3186 Protocols.push_back(PI->getNameAsString());
3190 if (I->isOptional())
3191 OptionalInstanceMethods.push_back(I);
3193 InstanceMethods.push_back(I);
3198 if (I->isOptional())
3199 OptionalClassMethods.push_back(I);
3201 ClassMethods.push_back(I);
3203 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
3204 llvm::Constant *InstanceMethodList =
3205 GenerateProtocolMethodList(InstanceMethods);
3206 llvm::Constant *ClassMethodList =
3207 GenerateProtocolMethodList(ClassMethods);
3208 llvm::Constant *OptionalInstanceMethodList =
3209 GenerateProtocolMethodList(OptionalInstanceMethods);
3210 llvm::Constant *OptionalClassMethodList =
3211 GenerateProtocolMethodList(OptionalClassMethods);
3219 llvm::Constant *PropertyList =
3220 GeneratePropertyList(
nullptr, PD,
false,
false);
3221 llvm::Constant *OptionalPropertyList =
3222 GeneratePropertyList(
nullptr, PD,
false,
true);
3229 auto Elements = Builder.beginStruct();
3231 llvm::ConstantExpr::getIntToPtr(
3232 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3233 Elements.add(MakeConstantString(ProtocolName));
3234 Elements.add(ProtocolList);
3235 Elements.add(InstanceMethodList);
3236 Elements.add(ClassMethodList);
3237 Elements.add(OptionalInstanceMethodList);
3238 Elements.add(OptionalClassMethodList);
3239 Elements.add(PropertyList);
3240 Elements.add(OptionalPropertyList);
3241 ExistingProtocols[ProtocolName] =
3242 llvm::ConstantExpr::getBitCast(
3243 Elements.finishAndCreateGlobal(
".objc_protocol", CGM.
getPointerAlign()),
3246 void CGObjCGNU::GenerateProtocolHolderCategory() {
3250 auto Elements = Builder.beginStruct();
3252 const std::string ClassName =
"__ObjC_Protocol_Holder_Ugly_Hack";
3254 Elements.add(MakeConstantString(CategoryName));
3255 Elements.add(MakeConstantString(ClassName));
3257 Elements.addBitCast(GenerateMethodList(
3258 ClassName, CategoryName, {},
false), PtrTy);
3260 Elements.addBitCast(GenerateMethodList(
3261 ClassName, CategoryName, {},
true), PtrTy);
3265 auto ProtocolList = ProtocolListBuilder.beginStruct();
3266 ProtocolList.add(NULLPtr);
3267 ProtocolList.addInt(LongTy, ExistingProtocols.size());
3268 auto ProtocolElements = ProtocolList.beginArray(PtrTy);
3269 for (
auto iter = ExistingProtocols.begin(), endIter = ExistingProtocols.end();
3270 iter != endIter ; iter++) {
3271 ProtocolElements.addBitCast(iter->getValue(), PtrTy);
3273 ProtocolElements.finishAndAddTo(ProtocolList);
3274 Elements.addBitCast(
3275 ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
3278 Categories.push_back(llvm::ConstantExpr::getBitCast(
3295 int bitCount = bits.size();
3297 if (bitCount < ptrBits) {
3299 for (
int i=0 ; i<bitCount ; ++i) {
3300 if (bits[i]) val |= 1ULL<<(i+1);
3302 return llvm::ConstantInt::get(IntPtrTy, val);
3306 while (
v < bitCount) {
3308 for (
int i=0 ; (i<32) && (
v<bitCount) ; ++i) {
3309 if (bits[
v]) word |= 1<<i;
3312 values.push_back(llvm::ConstantInt::get(Int32Ty, word));
3316 auto fields = builder.beginStruct();
3317 fields.addInt(Int32Ty, values.size());
3318 auto array = fields.beginArray();
3319 for (
auto *
v : values) array.add(
v);
3320 array.finishAndAddTo(fields);
3322 llvm::Constant *GS =
3324 llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy);
3328 llvm::Constant *CGObjCGNU::GenerateCategoryProtocolList(
const
3331 const auto RuntimeProtos =
3332 GetRuntimeProtocolList(RefPro.begin(), RefPro.end());
3334 for (
const auto *PD : RuntimeProtos)
3336 return GenerateProtocolList(Protocols);
3348 auto Elements = Builder.beginStruct();
3349 Elements.add(MakeConstantString(CategoryName));
3350 Elements.add(MakeConstantString(ClassName));
3353 InstanceMethods.insert(InstanceMethods.begin(), OCD->
instmeth_begin(),
3355 Elements.addBitCast(
3356 GenerateMethodList(ClassName, CategoryName, InstanceMethods,
false),
3363 Elements.addBitCast(
3364 GenerateMethodList(ClassName, CategoryName, ClassMethods,
true),
3367 Elements.addBitCast(GenerateCategoryProtocolList(CatDecl), PtrTy);
3373 Elements.addBitCast(GeneratePropertyList(OCD, Category,
false), PtrTy);
3375 Elements.addBitCast(GeneratePropertyList(OCD, Category,
true), PtrTy);
3377 Elements.addNullPointer(PtrTy);
3378 Elements.addNullPointer(PtrTy);
3382 Categories.push_back(llvm::ConstantExpr::getBitCast(
3383 Elements.finishAndCreateGlobal(
3384 std::string(
".objc_category_")+ClassName+CategoryName,
3389 llvm::Constant *CGObjCGNU::GeneratePropertyList(
const Decl *Container,
3391 bool isClassProperty,
3392 bool protocolOptionalProperties) {
3396 bool isProtocol = isa<ObjCProtocolDecl>(OCD);
3399 std::function<void(
const ObjCProtocolDecl *Proto)> collectProtocolProperties
3401 for (
const auto *
P : Proto->protocols())
3402 collectProtocolProperties(
P);
3403 for (
const auto *PD : Proto->properties()) {
3404 if (isClassProperty != PD->isClassProperty())
3412 Properties.push_back(PD);
3418 for (
auto *PD : ClassExt->properties()) {
3419 if (isClassProperty != PD->isClassProperty())
3422 Properties.push_back(PD);
3426 if (isClassProperty != PD->isClassProperty())
3430 if (isProtocol && (protocolOptionalProperties != PD->isOptional()))
3437 Properties.push_back(PD);
3442 collectProtocolProperties(
P);
3444 for (
const auto *
P : CD->protocols())
3445 collectProtocolProperties(
P);
3447 auto numProperties = Properties.size();
3449 if (numProperties == 0)
3453 auto propertyList = builder.beginStruct();
3454 auto properties = PushPropertyListHeader(propertyList, numProperties);
3458 for (
auto *property : Properties) {
3459 bool isSynthesized =
false;
3460 bool isDynamic =
false;
3464 isSynthesized = (propertyImpl->getPropertyImplementation() ==
3466 isDynamic = (propertyImpl->getPropertyImplementation() ==
3470 PushProperty(properties, property, Container, isSynthesized, isDynamic);
3472 properties.finishAndAddTo(propertyList);
3474 return propertyList.finishAndCreateGlobal(
".objc_property_list",
3493 if (SuperClassDecl) {
3495 EmitClassRef(SuperClassName);
3505 std::string classSymbolName =
"__objc_class_name_" + ClassName;
3506 if (
auto *symbol = TheModule.getGlobalVariable(classSymbolName)) {
3507 symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0));
3509 new llvm::GlobalVariable(TheModule, LongTy,
false,
3511 llvm::ConstantInt::get(LongTy, 0),
3527 auto IvarOffsetValues = IvarOffsetBuilder.beginArray(PtrToIntTy);
3531 int superInstanceSize = !SuperClassDecl ? 0 :
3536 instanceSize = 0 - (instanceSize - superInstanceSize);
3542 IvarNames.push_back(MakeConstantString(IVD->getNameAsString()));
3546 IvarTypes.push_back(MakeConstantString(TypeStr));
3547 IvarAligns.push_back(llvm::ConstantInt::get(IntTy,
3550 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
3553 Offset = BaseOffset - superInstanceSize;
3555 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy,
Offset);
3557 std::string OffsetName =
"__objc_ivar_offset_value_" + ClassName +
"." +
3558 IVD->getNameAsString();
3560 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
3562 OffsetVar->setInitializer(OffsetValue);
3568 OffsetVar =
new llvm::GlobalVariable(TheModule, Int32Ty,
3570 OffsetValue, OffsetName);
3571 IvarOffsets.push_back(OffsetValue);
3572 IvarOffsetValues.add(OffsetVar);
3574 IvarOwnership.push_back(lt);
3577 StrongIvars.push_back(
true);
3578 WeakIvars.push_back(
false);
3581 StrongIvars.push_back(
false);
3582 WeakIvars.push_back(
true);
3585 StrongIvars.push_back(
false);
3586 WeakIvars.push_back(
false);
3589 llvm::Constant *StrongIvarBitmap = MakeBitField(StrongIvars);
3590 llvm::Constant *WeakIvarBitmap = MakeBitField(WeakIvars);
3591 llvm::GlobalVariable *IvarOffsetArray =
3592 IvarOffsetValues.finishAndCreateGlobal(
".ivar.offsets",
3597 InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
3604 llvm::Constant *Properties = GeneratePropertyList(OID, ClassDecl);
3607 auto RefProtocols = ClassDecl->
protocols();
3608 auto RuntimeProtocols =
3609 GetRuntimeProtocolList(RefProtocols.begin(), RefProtocols.end());
3611 for (
const auto *I : RuntimeProtocols)
3612 Protocols.push_back(I->getNameAsString());
3615 llvm::Constant *SuperClass;
3616 if (!SuperClassName.empty()) {
3617 SuperClass = MakeConstantString(SuperClassName,
".super_class_name");
3619 SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty);
3624 llvm::Constant *MethodList = GenerateMethodList(ClassName,
"",
3625 InstanceMethods,
false);
3626 llvm::Constant *ClassMethodList = GenerateMethodList(ClassName,
"",
3627 ClassMethods,
true);
3628 llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
3629 IvarOffsets, IvarAligns, IvarOwnership);
3640 llvm::Type *IndexTy = Int32Ty;
3641 llvm::Constant *offsetPointerIndexes[] = {Zeros[0],
3642 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 2 : 1),
nullptr,
3643 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 3 : 2) };
3645 unsigned ivarIndex = 0;
3648 const std::string Name = GetIVarOffsetVariableName(ClassDecl, IVD);
3649 offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, ivarIndex);
3651 llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr(
3652 cast<llvm::GlobalVariable>(IvarList)->getValueType(), IvarList,
3653 offsetPointerIndexes);
3655 llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name);
3657 offset->setInitializer(offsetValue);
3664 new llvm::GlobalVariable(TheModule, offsetValue->getType(),
3668 llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0);
3671 llvm::Constant *MetaClassStruct = GenerateClassStructure(
3672 NULLPtr, NULLPtr, 0x12L, ClassName.c_str(),
nullptr, Zeros[0],
3673 NULLPtr, ClassMethodList, NULLPtr, NULLPtr,
3674 GeneratePropertyList(OID, ClassDecl,
true), ZeroPtr, ZeroPtr,
true);
3679 llvm::Constant *ClassStruct = GenerateClassStructure(
3680 MetaClassStruct, SuperClass, 0x11L, ClassName.c_str(),
nullptr,
3681 llvm::ConstantInt::get(LongTy, instanceSize), IvarList, MethodList,
3682 GenerateProtocolList(Protocols), IvarOffsetArray, Properties,
3683 StrongIvarBitmap, WeakIvarBitmap);
3688 if (ClassPtrAlias) {
3689 ClassPtrAlias->replaceAllUsesWith(
3690 llvm::ConstantExpr::getBitCast(ClassStruct, IdTy));
3691 ClassPtrAlias->eraseFromParent();
3692 ClassPtrAlias =
nullptr;
3694 if (MetaClassPtrAlias) {
3695 MetaClassPtrAlias->replaceAllUsesWith(
3696 llvm::ConstantExpr::getBitCast(MetaClassStruct, IdTy));
3697 MetaClassPtrAlias->eraseFromParent();
3698 MetaClassPtrAlias =
nullptr;
3702 ClassStruct = llvm::ConstantExpr::getBitCast(ClassStruct, PtrToInt8Ty);
3703 Classes.push_back(ClassStruct);
3706 llvm::Function *CGObjCGNU::ModuleInitFunction() {
3708 if (Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
3713 GenerateProtocolHolderCategory();
3715 llvm::StructType *selStructTy = dyn_cast<llvm::StructType>(SelectorElemTy);
3716 llvm::Type *selStructPtrTy = SelectorTy;
3719 { PtrToInt8Ty, PtrToInt8Ty });
3720 selStructPtrTy = llvm::PointerType::getUnqual(selStructTy);
3724 llvm::Constant *statics = NULLPtr;
3725 if (!ConstantStrings.empty()) {
3726 llvm::GlobalVariable *fileStatics = [&] {
3728 auto staticsStruct = builder.beginStruct();
3731 if (stringClass.empty()) stringClass =
"NXConstantString";
3732 staticsStruct.add(MakeConstantString(stringClass,
3733 ".objc_static_class_name"));
3735 auto array = staticsStruct.beginArray();
3736 array.addAll(ConstantStrings);
3738 array.finishAndAddTo(staticsStruct);
3740 return staticsStruct.finishAndCreateGlobal(
".objc_statics",
3745 auto allStaticsArray = builder.beginArray(fileStatics->getType());
3746 allStaticsArray.add(fileStatics);
3747 allStaticsArray.addNullPointer(fileStatics->getType());
3749 statics = allStaticsArray.finishAndCreateGlobal(
".objc_statics_ptr",
3751 statics = llvm::ConstantExpr::getBitCast(statics, PtrTy);
3757 unsigned selectorCount;
3760 llvm::GlobalVariable *selectorList = [&] {
3762 auto selectors = builder.beginArray(selStructTy);
3764 std::vector<Selector> allSelectors;
3765 for (
auto &entry : table)
3766 allSelectors.push_back(entry.first);
3767 llvm::sort(allSelectors);
3769 for (
auto &untypedSel : allSelectors) {
3770 std::string selNameStr = untypedSel.getAsString();
3771 llvm::Constant *selName = ExportUniqueString(selNameStr,
".objc_sel_name");
3773 for (TypedSelector &sel : table[untypedSel]) {
3774 llvm::Constant *selectorTypeEncoding = NULLPtr;
3775 if (!sel.first.empty())
3776 selectorTypeEncoding =
3777 MakeConstantString(sel.first,
".objc_sel_types");
3779 auto selStruct = selectors.beginStruct(selStructTy);
3780 selStruct.add(selName);
3781 selStruct.add(selectorTypeEncoding);
3782 selStruct.finishAndAddTo(selectors);
3785 selectorAliases.push_back(sel.second);
3790 selectorCount = selectors.size();
3796 auto selStruct = selectors.beginStruct(selStructTy);
3797 selStruct.add(NULLPtr);
3798 selStruct.add(NULLPtr);
3799 selStruct.finishAndAddTo(selectors);
3801 return selectors.finishAndCreateGlobal(
".objc_selector_list",
3806 for (
unsigned i = 0; i < selectorCount; ++i) {
3807 llvm::Constant *idxs[] = {
3809 llvm::ConstantInt::get(Int32Ty, i)
3812 llvm::Constant *selPtr = llvm::ConstantExpr::getGetElementPtr(
3813 selectorList->getValueType(), selectorList, idxs);
3816 selPtr = llvm::ConstantExpr::getBitCast(selPtr, SelectorTy);
3817 selectorAliases[i]->replaceAllUsesWith(selPtr);
3818 selectorAliases[i]->eraseFromParent();
3821 llvm::GlobalVariable *symtab = [&] {
3823 auto symtab = builder.beginStruct();
3826 symtab.addInt(LongTy, selectorCount);
3828 symtab.addBitCast(selectorList, selStructPtrTy);
3831 symtab.addInt(CGM.
Int16Ty, Classes.size());
3833 symtab.addInt(CGM.
Int16Ty, Categories.size());
3836 auto classList = symtab.beginArray(PtrToInt8Ty);
3837 classList.addAll(Classes);
3838 classList.addAll(Categories);
3840 classList.add(statics);
3841 classList.add(NULLPtr);
3842 classList.finishAndAddTo(symtab);
3850 llvm::Constant *module = [&] {
3851 llvm::Type *moduleEltTys[] = {
3852 LongTy, LongTy, PtrToInt8Ty, symtab->getType(), IntTy
3854 llvm::StructType *moduleTy = llvm::StructType::get(
3856 ArrayRef(moduleEltTys).drop_back(
unsigned(RuntimeVersion < 10)));
3859 auto module = builder.beginStruct(moduleTy);
3861 module.addInt(LongTy, RuntimeVersion);
3863 module.addInt(LongTy, CGM.
getDataLayout().getTypeStoreSize(moduleTy));
3870 module.add(MakeConstantString(path,
".objc_source_file_name"));
3873 if (RuntimeVersion >= 10) {
3876 module.addInt(IntTy, 2);
3880 module.addInt(IntTy, 1);
3882 module.addInt(IntTy, 0);
3885 module.addInt(IntTy, 1);
3895 llvm::Function * LoadFunction = llvm::Function::Create(
3896 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
3899 llvm::BasicBlock *EntryBB =
3900 llvm::BasicBlock::Create(VMContext,
"entry", LoadFunction);
3902 Builder.SetInsertPoint(EntryBB);
3904 llvm::FunctionType *FT =
3905 llvm::FunctionType::get(Builder.getVoidTy(), module->getType(),
true);
3906 llvm::FunctionCallee Register =
3908 Builder.CreateCall(Register, module);
3910 if (!ClassAliases.empty()) {
3911 llvm::Type *ArgTypes[2] = {PtrTy, PtrToInt8Ty};
3912 llvm::FunctionType *RegisterAliasTy =
3913 llvm::FunctionType::get(Builder.getVoidTy(),
3915 llvm::Function *RegisterAlias = llvm::Function::Create(
3917 llvm::GlobalValue::ExternalWeakLinkage,
"class_registerAlias_np",
3919 llvm::BasicBlock *AliasBB =
3920 llvm::BasicBlock::Create(VMContext,
"alias", LoadFunction);
3921 llvm::BasicBlock *NoAliasBB =
3922 llvm::BasicBlock::Create(VMContext,
"no_alias", LoadFunction);
3925 llvm::Value *HasRegisterAlias = Builder.CreateICmpNE(RegisterAlias,
3926 llvm::Constant::getNullValue(RegisterAlias->getType()));
3927 Builder.CreateCondBr(HasRegisterAlias, AliasBB, NoAliasBB);
3930 Builder.SetInsertPoint(AliasBB);
3932 for (std::vector<ClassAliasPair>::iterator iter = ClassAliases.begin();
3933 iter != ClassAliases.end(); ++iter) {
3934 llvm::Constant *TheClass =
3935 TheModule.getGlobalVariable(
"_OBJC_CLASS_" + iter->first,
true);
3937 TheClass = llvm::ConstantExpr::getBitCast(TheClass, PtrTy);
3938 Builder.CreateCall(RegisterAlias,
3939 {TheClass, MakeConstantString(iter->second)});
3943 Builder.CreateBr(NoAliasBB);
3946 Builder.SetInsertPoint(NoAliasBB);
3948 Builder.CreateRetVoid();
3950 return LoadFunction;
3953 llvm::Function *CGObjCGNU::GenerateMethod(
const ObjCMethodDecl *OMD,
3956 llvm::FunctionType *MethodTy =
3957 Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
3958 std::string FunctionName = getSymbolNameForMethod(OMD);
3960 llvm::Function *Method
3961 = llvm::Function::Create(MethodTy,
3975 llvm::FunctionCallee CGObjCGNU::GetPropertyGetFunction() {
3976 return GetPropertyFn;
3979 llvm::FunctionCallee CGObjCGNU::GetPropertySetFunction() {
3980 return SetPropertyFn;
3983 llvm::FunctionCallee CGObjCGNU::GetOptimizedPropertySetFunction(
bool atomic,
3988 llvm::FunctionCallee CGObjCGNU::GetGetStructFunction() {
3989 return GetStructPropertyFn;
3992 llvm::FunctionCallee CGObjCGNU::GetSetStructFunction() {
3993 return SetStructPropertyFn;
3996 llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectGetFunction() {
4000 llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectSetFunction() {
4004 llvm::FunctionCallee CGObjCGNU::EnumerationMutationFunction() {
4005 return EnumerationMutationFn;
4010 EmitAtSynchronizedStmt(CGF, S, SyncEnterFn, SyncExitFn);
4027 EmitTryCatchStmt(CGF, S, EnterCatchFn, ExitCatchFn, ExceptionReThrowFn);
4032 bool ClearInsertionPoint) {
4033 llvm::Value *ExceptionAsObject;
4034 bool isRethrow =
false;
4036 if (
const Expr *ThrowExpr = S.getThrowExpr()) {
4038 ExceptionAsObject = Exception;
4041 "Unexpected rethrow outside @catch block.");
4045 if (isRethrow && usesSEHExceptions) {
4054 Throw->setDoesNotReturn();
4057 ExceptionAsObject = CGF.
Builder.CreateBitCast(ExceptionAsObject, IdTy);
4058 llvm::CallBase *Throw =
4060 Throw->setDoesNotReturn();
4062 CGF.
Builder.CreateUnreachable();
4063 if (ClearInsertionPoint)
4064 CGF.
Builder.ClearInsertionPoint();
4070 return B.CreateCall(WeakReadFn,
4071 EnforceType(B, AddrWeakObj.
getPointer(), PtrToIdTy));
4075 llvm::Value *src,
Address dst) {
4077 src = EnforceType(B, src, IdTy);
4078 llvm::Value *dstVal = EnforceType(B, dst.
getPointer(), PtrToIdTy);
4079 B.CreateCall(WeakAssignFn, {src, dstVal});
4083 llvm::Value *src,
Address dst,
4086 src = EnforceType(B, src, IdTy);
4087 llvm::Value *dstVal = EnforceType(B, dst.
getPointer(), PtrToIdTy);
4089 assert(!threadlocal &&
"EmitObjCGlobalAssign - Threal Local API NYI");
4090 B.CreateCall(GlobalAssignFn, {src, dstVal});
4094 llvm::Value *src,
Address dst,
4095 llvm::Value *ivarOffset) {
4097 src = EnforceType(B, src, IdTy);
4098 llvm::Value *dstVal = EnforceType(B, dst.
getPointer(), IdTy);
4099 B.CreateCall(IvarAssignFn, {src, dstVal, ivarOffset});
4103 llvm::Value *src,
Address dst) {
4105 src = EnforceType(B, src, IdTy);
4106 llvm::Value *dstVal = EnforceType(B, dst.
getPointer(), PtrToIdTy);
4107 B.CreateCall(StrongCastAssignFn, {src, dstVal});
4113 llvm::Value *Size) {
4115 llvm::Value *DestPtrVal = EnforceType(B, DestPtr.
getPointer(), PtrTy);
4116 llvm::Value *SrcPtrVal = EnforceType(B, SrcPtr.
getPointer(), PtrTy);
4118 B.CreateCall(MemMoveFn, {DestPtrVal, SrcPtrVal,
Size});
4121 llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
4124 const std::string Name = GetIVarOffsetVariableName(
ID, Ivar);
4128 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
4129 if (!IvarOffsetPointer)
4130 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule,
4131 llvm::Type::getInt32PtrTy(VMContext),
false,
4133 return IvarOffsetPointer;
4138 llvm::Value *BaseValue,
4140 unsigned CVRQualifiers) {
4143 return EmitValueForIvarAtOffset(CGF,
ID, BaseValue, Ivar, CVRQualifiers,
4144 EmitIvarOffset(CGF,
ID, Ivar));
4172 if (RuntimeVersion < 10 ||
4174 return CGF.
Builder.CreateZExtOrBitCast(
4177 llvm::Type::getInt32PtrTy(VMContext),
4178 ObjCIvarOffsetVariable(Interface, Ivar),
4185 llvm::Value *
Offset = TheModule.getGlobalVariable(
name);
4187 auto GV =
new llvm::GlobalVariable(TheModule, IntTy,
4188 false, llvm::GlobalValue::LinkOnceAnyLinkage,
4189 llvm::Constant::getNullValue(IntTy),
name);
4194 if (
Offset->getType() != PtrDiffTy)
4199 return llvm::ConstantInt::get(PtrDiffTy,
Offset,
true);
4205 switch (Runtime.getKind()) {
4207 if (Runtime.getVersion() >= VersionTuple(2, 0))
4208 return new CGObjCGNUstep2(CGM);
4209 return new CGObjCGNUstep(CGM);
4212 return new CGObjCGCC(CGM);
4215 return new CGObjCObjFW(CGM);
4221 llvm_unreachable(
"these runtimes are not GNU runtimes");
4223 llvm_unreachable(
"bad runtime");