29 #include "llvm/ADT/SmallVector.h" 30 #include "llvm/ADT/StringMap.h" 31 #include "llvm/IR/DataLayout.h" 32 #include "llvm/IR/Intrinsics.h" 33 #include "llvm/IR/LLVMContext.h" 34 #include "llvm/IR/Module.h" 35 #include "llvm/Support/Compiler.h" 36 #include "llvm/Support/ConvertUTF.h" 39 using namespace clang;
40 using namespace CodeGen;
44 std::string SymbolNameForMethod( StringRef ClassName,
45 StringRef CategoryName,
const Selector MethodName,
47 std::string MethodNameColonStripped = MethodName.
getAsString();
48 std::replace(MethodNameColonStripped.begin(), MethodNameColonStripped.end(),
50 return (Twine(isClassMethod ?
"_c_" :
"_i_") + ClassName +
"_" +
51 CategoryName +
"_" + MethodNameColonStripped).str();
57 class LazyRuntimeFunction {
59 llvm::FunctionType *FTy;
60 const char *FunctionName;
68 : CGM(nullptr), FunctionName(nullptr), Function(nullptr) {}
72 template <
typename... Tys>
80 FTy = llvm::FunctionType::get(RetTy, ArgTys,
false);
83 FTy = llvm::FunctionType::get(RetTy, None,
false);
87 llvm::FunctionType *getType() {
return FTy; }
91 operator llvm::FunctionCallee() {
108 llvm::Module &TheModule;
111 llvm::StructType *ObjCSuperTy;
114 llvm::PointerType *PtrToObjCSuperTy;
118 llvm::PointerType *SelectorTy;
121 llvm::IntegerType *Int8Ty;
124 llvm::PointerType *PtrToInt8Ty;
126 llvm::StructType *ProtocolTy;
128 llvm::PointerType *ProtocolPtrTy;
134 llvm::PointerType *IMPTy;
139 llvm::PointerType *IdTy;
142 llvm::PointerType *PtrToIdTy;
147 llvm::IntegerType *IntTy;
151 llvm::PointerType *PtrTy;
155 llvm::IntegerType *LongTy;
157 llvm::IntegerType *SizeTy;
159 llvm::IntegerType *IntPtrTy;
161 llvm::IntegerType *PtrDiffTy;
164 llvm::PointerType *PtrToIntTy;
168 llvm::IntegerType *Int32Ty;
170 llvm::IntegerType *Int64Ty;
172 llvm::StructType *PropertyMetadataTy;
176 unsigned msgSendMDKind;
179 bool usesSEHExceptions;
185 (R.
getVersion() >= VersionTuple(major, minor));
188 std::string ManglePublicSymbol(StringRef Name) {
189 return (StringRef(CGM.
getTriple().isOSBinFormatCOFF() ?
"$_" :
"._") + Name).str();
192 std::string SymbolForProtocol(Twine Name) {
193 return (ManglePublicSymbol(
"OBJC_PROTOCOL_") + Name).str();
196 std::string SymbolForProtocolRef(StringRef Name) {
197 return (ManglePublicSymbol(
"OBJC_REF_PROTOCOL_") + Name).str();
204 llvm::Constant *MakeConstantString(StringRef Str,
const char *Name =
"") {
206 return llvm::ConstantExpr::getGetElementPtr(Array.
getElementType(),
214 llvm::Constant *ExportUniqueString(
const std::string &Str,
215 const std::string &prefix,
216 bool Private=
false) {
217 std::string name = prefix + Str;
218 auto *ConstStr = TheModule.getGlobalVariable(name);
220 llvm::Constant *value = llvm::ConstantDataArray::getString(VMContext,Str);
221 auto *GV =
new llvm::GlobalVariable(TheModule, value->getType(),
true,
222 llvm::GlobalValue::LinkOnceODRLinkage, value,
name);
223 GV->setComdat(TheModule.getOrInsertComdat(name));
228 return llvm::ConstantExpr::getGetElementPtr(ConstStr->getValueType(),
234 const Decl *Container) {
237 std::string NameAndAttributes;
238 std::string TypeStr =
240 NameAndAttributes +=
'\0';
241 NameAndAttributes += TypeStr.length() + 3;
242 NameAndAttributes += TypeStr;
243 NameAndAttributes +=
'\0';
245 return MakeConstantString(NameAndAttributes);
254 int attrs =
property->getPropertyAttributes();
263 Fields.addInt(Int8Ty, attrs & 0xff);
269 attrs |= isSynthesized ? (1<<0) : 0;
273 Fields.addInt(Int8Ty, attrs & 0xff);
275 Fields.addInt(Int8Ty, 0);
276 Fields.addInt(Int8Ty, 0);
279 virtual llvm::Constant *GenerateCategoryProtocolList(
const 284 Fields.addInt(IntTy, count);
287 llvm::DataLayout td(&TheModule);
288 Fields.addInt(IntTy, td.getTypeSizeInBits(PropertyMetadataTy) /
299 bool isSynthesized=
true,
bool 301 auto Fields = PropertiesArray.
beginStruct(PropertyMetadataTy);
303 Fields.add(MakePropertyEncodingString(property, OCD));
304 PushPropertyAttributes(Fields, property, isSynthesized,
isDynamic);
308 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
309 Fields.add(MakeConstantString(accessor->getSelector().getAsString()));
310 Fields.add(TypeEncoding);
325 if (V->getType() == Ty)
return V;
329 if (V.
getType() == Ty)
return V;
334 llvm::Constant *Zeros[2];
336 llvm::Constant *NULLPtr;
338 llvm::LLVMContext &VMContext;
346 llvm::GlobalAlias *ClassPtrAlias;
351 llvm::GlobalAlias *MetaClassPtrAlias;
353 std::vector<llvm::Constant*> Classes;
355 std::vector<llvm::Constant*> Categories;
358 std::vector<llvm::Constant*> ConstantStrings;
362 llvm::StringMap<llvm::Constant*> ObjCStrings;
364 llvm::StringMap<llvm::Constant*> ExistingProtocols;
370 typedef std::pair<std::string, llvm::GlobalAlias*> TypedSelector;
374 typedef llvm::DenseMap<Selector, SmallVector<TypedSelector, 2> >
382 Selector RetainSel, ReleaseSel, AutoreleaseSel;
386 LazyRuntimeFunction IvarAssignFn, StrongCastAssignFn, MemMoveFn, WeakReadFn,
387 WeakAssignFn, GlobalAssignFn;
389 typedef std::pair<std::string, std::string> ClassAliasPair;
391 std::vector<ClassAliasPair> ClassAliases;
395 LazyRuntimeFunction ExceptionThrowFn;
398 LazyRuntimeFunction ExceptionReThrowFn;
401 LazyRuntimeFunction EnterCatchFn;
404 LazyRuntimeFunction ExitCatchFn;
406 LazyRuntimeFunction SyncEnterFn;
408 LazyRuntimeFunction SyncExitFn;
413 LazyRuntimeFunction EnumerationMutationFn;
416 LazyRuntimeFunction GetPropertyFn;
419 LazyRuntimeFunction SetPropertyFn;
421 LazyRuntimeFunction GetStructPropertyFn;
423 LazyRuntimeFunction SetStructPropertyFn;
435 const int ProtocolVersion;
438 const int ClassABIVersion;
454 llvm::Constant *GenerateMethodList(StringRef ClassName,
455 StringRef CategoryName,
457 bool isClassMethodList);
462 virtual llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName);
466 llvm::Constant *GeneratePropertyList(
const Decl *Container,
468 bool isClassProperty=
false,
469 bool protocolOptionalProperties=
false);
479 void GenerateProtocolHolderCategory();
482 llvm::Constant *GenerateClassStructure(
483 llvm::Constant *MetaClass,
484 llvm::Constant *SuperClass,
487 llvm::Constant *Version,
488 llvm::Constant *InstanceSize,
489 llvm::Constant *IVars,
490 llvm::Constant *Methods,
491 llvm::Constant *Protocols,
492 llvm::Constant *IvarOffsets,
493 llvm::Constant *Properties,
494 llvm::Constant *StrongIvarBitmap,
495 llvm::Constant *WeakIvarBitmap,
500 virtual llvm::Constant *GenerateProtocolMethodList(
504 void EmitProtocolMethodList(T &&Methods, llvm::Constant *&Required,
508 for (
const auto *I : Methods)
510 OptionalMethods.push_back(I);
512 RequiredMethods.push_back(I);
513 Required = GenerateProtocolMethodList(RequiredMethods);
514 Optional = GenerateProtocolMethodList(OptionalMethods);
520 const std::string &TypeEncoding);
536 void EmitClassRef(
const std::string &className);
540 const std::string &Name,
bool isWeak);
549 MessageSendInfo &MSI) = 0;
557 MessageSendInfo &MSI) = 0;
574 unsigned protocolClassVersion,
unsigned classABI=1);
597 virtual llvm::Constant *GetConstantSelector(
Selector Sel,
598 const std::string &TypeEncoding) {
599 llvm_unreachable(
"Runtime unable to generate constant selector");
605 llvm::Constant *GetEHType(
QualType T)
override;
615 llvm::Function *ModuleInitFunction()
override;
616 llvm::FunctionCallee GetPropertyGetFunction()
override;
617 llvm::FunctionCallee GetPropertySetFunction()
override;
618 llvm::FunctionCallee GetOptimizedPropertySetFunction(
bool atomic,
620 llvm::FunctionCallee GetSetStructFunction()
override;
621 llvm::FunctionCallee GetGetStructFunction()
override;
622 llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override;
623 llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override;
624 llvm::FunctionCallee EnumerationMutationFunction()
override;
632 bool ClearInsertionPoint=
true)
override;
639 bool threadlocal=
false)
override;
649 unsigned CVRQualifiers)
override;
676 class CGObjCGCC :
public CGObjCGNU {
679 LazyRuntimeFunction MsgLookupFn;
683 LazyRuntimeFunction MsgLookupSuperFn;
688 MessageSendInfo &MSI)
override {
691 EnforceType(Builder, Receiver, IdTy),
692 EnforceType(Builder, cmd, SelectorTy) };
694 imp->setMetadata(msgSendMDKind, node);
701 llvm::Value *lookupArgs[] = {EnforceType(Builder, ObjCSuper,
702 PtrToObjCSuperTy).getPointer(), cmd};
709 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
711 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
712 PtrToObjCSuperTy, SelectorTy);
717 class CGObjCGNUstep :
public CGObjCGNU {
720 LazyRuntimeFunction SlotLookupFn;
725 LazyRuntimeFunction SlotLookupSuperFn;
727 LazyRuntimeFunction SetPropertyAtomic;
729 LazyRuntimeFunction SetPropertyAtomicCopy;
731 LazyRuntimeFunction SetPropertyNonAtomic;
733 LazyRuntimeFunction SetPropertyNonAtomicCopy;
736 LazyRuntimeFunction CxxAtomicObjectGetFn;
739 LazyRuntimeFunction CxxAtomicObjectSetFn;
745 llvm::Constant *GetEHType(
QualType T)
override;
750 MessageSendInfo &MSI)
override {
752 llvm::FunctionCallee LookupFn = SlotLookupFn;
764 self = llvm::ConstantPointerNull::get(IdTy);
768 if (
auto *LookupFn2 = dyn_cast<llvm::Function>(LookupFn.getCallee()))
769 LookupFn2->addParamAttr(0, llvm::Attribute::NoCapture);
772 EnforceType(Builder, ReceiverPtr.
getPointer(), PtrToIdTy),
773 EnforceType(Builder, cmd, SelectorTy),
774 EnforceType(Builder,
self, IdTy) };
776 slot->setOnlyReadsMemory();
777 slot->setMetadata(msgSendMDKind, node);
785 Receiver = Builder.
CreateLoad(ReceiverPtr,
true);
791 MessageSendInfo &MSI)
override {
795 llvm::CallInst *slot =
797 slot->setOnlyReadsMemory();
804 CGObjCGNUstep(
CodeGenModule &Mod) : CGObjCGNUstep(Mod, 9, 3, 1) {}
805 CGObjCGNUstep(
CodeGenModule &Mod,
unsigned ABI,
unsigned ProtocolABI,
807 CGObjCGNU(Mod, ABI, ProtocolABI, ClassABI) {
810 llvm::StructType *SlotStructTy =
811 llvm::StructType::get(PtrTy, PtrTy, PtrTy, IntTy, IMPTy);
812 SlotTy = llvm::PointerType::getUnqual(SlotStructTy);
814 SlotLookupFn.init(&CGM,
"objc_msg_lookup_sender", SlotTy, PtrToIdTy,
817 SlotLookupSuperFn.init(&CGM,
"objc_slot_lookup_super", SlotTy,
818 PtrToObjCSuperTy, SelectorTy);
820 if (usesSEHExceptions) {
821 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
823 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy);
825 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
827 EnterCatchFn.init(&CGM,
"__cxa_begin_catch", PtrTy, PtrTy);
829 ExitCatchFn.init(&CGM,
"__cxa_end_catch", VoidTy);
831 ExceptionReThrowFn.init(&CGM,
"_Unwind_Resume_or_Rethrow", VoidTy,
833 }
else if (R.
getVersion() >= VersionTuple(1, 7)) {
834 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
836 EnterCatchFn.init(&CGM,
"objc_begin_catch", IdTy, PtrTy);
838 ExitCatchFn.init(&CGM,
"objc_end_catch", VoidTy);
840 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy, PtrTy);
842 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
843 SetPropertyAtomic.init(&CGM,
"objc_setProperty_atomic", VoidTy, IdTy,
844 SelectorTy, IdTy, PtrDiffTy);
845 SetPropertyAtomicCopy.init(&CGM,
"objc_setProperty_atomic_copy", VoidTy,
846 IdTy, SelectorTy, IdTy, PtrDiffTy);
847 SetPropertyNonAtomic.init(&CGM,
"objc_setProperty_nonatomic", VoidTy,
848 IdTy, SelectorTy, IdTy, PtrDiffTy);
849 SetPropertyNonAtomicCopy.init(&CGM,
"objc_setProperty_nonatomic_copy",
850 VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy);
853 CxxAtomicObjectSetFn.init(&CGM,
"objc_setCppObjectAtomic", VoidTy, PtrTy,
857 CxxAtomicObjectGetFn.init(&CGM,
"objc_getCppObjectAtomic", VoidTy, PtrTy,
861 llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override {
866 return CxxAtomicObjectGetFn;
869 llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override {
874 return CxxAtomicObjectSetFn;
877 llvm::FunctionCallee GetOptimizedPropertySetFunction(
bool atomic,
878 bool copy)
override {
889 if (copy)
return SetPropertyAtomicCopy;
890 return SetPropertyAtomic;
893 return copy ? SetPropertyNonAtomicCopy : SetPropertyNonAtomic;
900 class CGObjCGNUstep2 :
public CGObjCGNUstep {
905 ClassReferenceSection,
908 ProtocolReferenceSection,
910 ConstantStringSection
912 static const char *
const SectionsBaseNames[8];
913 static const char *
const PECOFFSectionsBaseNames[8];
914 template<SectionKind K>
915 std::string sectionName() {
916 if (CGM.
getTriple().isOSBinFormatCOFF()) {
917 std::string
name(PECOFFSectionsBaseNames[K]);
921 return SectionsBaseNames[K];
926 LazyRuntimeFunction MsgLookupSuperFn;
930 bool EmittedProtocol =
false;
935 bool EmittedProtocolRef =
false;
939 bool EmittedClass =
false;
943 typedef std::pair<std::string, std::pair<llvm::Constant*, int>> EarlyInitPair;
944 std::vector<EarlyInitPair> EarlyInitList;
946 std::string SymbolForClassRef(StringRef Name,
bool isWeak) {
948 return (ManglePublicSymbol(
"OBJC_WEAK_REF_CLASS_") + Name).str();
950 return (ManglePublicSymbol(
"OBJC_REF_CLASS_") + Name).str();
953 std::string SymbolForClass(StringRef Name) {
954 return (ManglePublicSymbol(
"OBJC_CLASS_") + Name).str();
956 void CallRuntimeFunction(
CGBuilderTy &B, StringRef FunctionName,
959 for (
auto *Arg : Args)
960 Types.push_back(Arg->getType());
961 llvm::FunctionType *FT = llvm::FunctionType::get(B.getVoidTy(), Types,
964 B.CreateCall(Fn, Args);
973 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
974 if (old != ObjCStrings.end())
982 (LiteralLength < 9) && !isNonASCII) {
988 for (
unsigned i=0 ;
i<LiteralLength ;
i++)
989 str |= ((uint64_t)SL->
getCodeUnit(
i)) << ((64 - 4 - 3) - (
i*7));
991 str |= LiteralLength << 3;
994 auto *ObjCStr = llvm::ConstantExpr::getIntToPtr(
995 llvm::ConstantInt::get(Int64Ty, str), IdTy);
996 ObjCStrings[Str] = ObjCStr;
1002 if (StringClass.empty()) StringClass =
"NSConstantString";
1004 std::string Sym = SymbolForClass(StringClass);
1006 llvm::Constant *
isa = TheModule.getNamedGlobal(Sym);
1009 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
1011 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1012 cast<llvm::GlobalValue>(
isa)->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
1014 }
else if (isa->getType() != PtrToIdTy)
1015 isa = llvm::ConstantExpr::getBitCast(isa, PtrToIdTy);
1028 auto Fields = Builder.beginStruct();
1029 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
1032 Fields.addNullPointer(PtrTy);
1039 unsigned NumU8CodeUnits = Str.size();
1044 const llvm::UTF8 *FromPtr = (
const llvm::UTF8 *)Str.data();
1045 llvm::UTF16 *ToPtr = &ToBuf[0];
1046 (void)llvm::ConvertUTF8toUTF16(&FromPtr, FromPtr + NumU8CodeUnits,
1047 &ToPtr, ToPtr + NumU8CodeUnits, llvm::strictConversion);
1048 uint32_t StringLength = ToPtr - &ToBuf[0];
1052 Fields.addInt(Int32Ty, 2);
1054 Fields.addInt(Int32Ty, StringLength);
1056 Fields.addInt(Int32Ty, StringLength * 2);
1058 Fields.addInt(Int32Ty, 0);
1060 auto Arr = llvm::makeArrayRef(&ToBuf[0], ToPtr+1);
1061 auto *
C = llvm::ConstantDataArray::get(VMContext, Arr);
1062 auto *Buffer =
new llvm::GlobalVariable(TheModule,
C->getType(),
1063 true, llvm::GlobalValue::PrivateLinkage,
C,
".str");
1064 Buffer->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1068 Fields.addInt(Int32Ty, 0);
1070 Fields.addInt(Int32Ty, Str.size());
1072 Fields.addInt(Int32Ty, Str.size());
1074 Fields.addInt(Int32Ty, 0);
1076 Fields.add(MakeConstantString(Str));
1078 std::string StringName;
1081 StringName =
".objc_str_";
1082 for (
int i=0,e=Str.size() ;
i<e ; ++
i) {
1083 unsigned char c = Str[
i];
1096 isNamed ? StringRef(StringName) :
".objc_string",
1097 Align,
false, isNamed ? llvm::GlobalValue::LinkOnceODRLinkage
1098 : llvm::GlobalValue::PrivateLinkage);
1099 ObjCStrGV->setSection(sectionName<ConstantStringSection>());
1101 ObjCStrGV->setComdat(TheModule.getOrInsertComdat(StringName));
1104 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1105 std::pair<llvm::Constant*, int>
v{ObjCStrGV, 0};
1106 EarlyInitList.emplace_back(Sym,
v);
1108 llvm::Constant *ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStrGV, IdTy);
1109 ObjCStrings[Str] = ObjCStr;
1110 ConstantStrings.push_back(ObjCStr);
1117 bool isSynthesized=
true,
bool 1127 auto Fields = PropertiesArray.
beginStruct(PropertyMetadataTy);
1130 std::string TypeStr =
1132 Fields.add(MakeConstantString(TypeStr));
1133 std::string typeStr;
1135 Fields.add(MakeConstantString(typeStr));
1139 Fields.add(GetConstantSelector(accessor->getSelector(), TypeStr));
1141 Fields.add(NULLPtr);
1156 llvm::StructType *ObjCMethodDescTy =
1158 { PtrToInt8Ty, PtrToInt8Ty });
1167 auto MethodList = Builder.beginStruct();
1169 MethodList.addInt(IntTy, Methods.size());
1171 llvm::DataLayout td(&TheModule);
1172 MethodList.addInt(IntTy, td.getTypeSizeInBits(ObjCMethodDescTy) /
1175 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
1176 for (
auto *M : Methods) {
1177 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
1178 Method.add(CGObjCGNU::GetConstantSelector(M));
1179 Method.add(GetTypeString(Context.getObjCEncodingForMethodDecl(M,
true)));
1180 Method.finishAndAddTo(MethodArray);
1182 MethodArray.finishAndAddTo(MethodList);
1183 return MethodList.finishAndCreateGlobal(
".objc_protocol_method_list",
1190 Protocols.push_back(
1191 llvm::ConstantExpr::getBitCast(GenerateProtocolRef(PI),
1193 return GenerateProtocolList(Protocols);
1197 llvm::Value *cmd, MessageSendInfo &MSI)
override {
1200 llvm::Value *lookupArgs[] = {CGObjCGNU::EnforceType(Builder, ObjCSuper,
1201 PtrToObjCSuperTy).getPointer(), cmd};
1205 llvm::GlobalVariable *GetClassVar(StringRef Name,
bool isWeak=
false) {
1206 std::string SymbolName = SymbolForClassRef(Name, isWeak);
1207 auto *ClassSymbol = TheModule.getNamedGlobal(SymbolName);
1210 ClassSymbol =
new llvm::GlobalVariable(TheModule,
1212 nullptr, SymbolName);
1218 ClassSymbol->setInitializer(
new llvm::GlobalVariable(TheModule,
1219 Int8Ty,
false, llvm::GlobalValue::ExternalWeakLinkage,
1220 nullptr, SymbolForClass(Name)));
1222 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1228 for (
const auto &Result : DC->
lookup(&II))
1229 if ((OID = dyn_cast<ObjCInterfaceDecl>(Result)))
1236 if (OIDDef !=
nullptr)
1239 auto Storage = llvm::GlobalValue::DefaultStorageClass;
1240 if (OID->
hasAttr<DLLImportAttr>())
1241 Storage = llvm::GlobalValue::DLLImportStorageClass;
1242 else if (OID->
hasAttr<DLLExportAttr>())
1243 Storage = llvm::GlobalValue::DLLExportStorageClass;
1245 cast<llvm::GlobalValue>(ClassSymbol)->setDLLStorageClass(Storage);
1248 assert(ClassSymbol->getName() == SymbolName);
1252 const std::string &Name,
1253 bool isWeak)
override {
1265 switch (Ownership) {
1287 llvm_unreachable(
"Method should not be called!");
1290 llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName)
override {
1291 std::string Name = SymbolForProtocol(ProtocolName);
1292 auto *GV = TheModule.getGlobalVariable(Name);
1295 GV =
new llvm::GlobalVariable(TheModule, ProtocolTy,
false,
1299 return llvm::ConstantExpr::getBitCast(GV, ProtocolPtrTy);
1303 llvm::StringMap<llvm::Constant*> ExistingProtocolRefs;
1308 auto *&Ref = ExistingProtocolRefs[Name];
1310 auto *&
Protocol = ExistingProtocols[Name];
1312 Protocol = GenerateProtocolRef(PD);
1313 std::string RefName = SymbolForProtocolRef(Name);
1314 assert(!TheModule.getGlobalVariable(RefName));
1316 auto GV =
new llvm::GlobalVariable(TheModule, ProtocolPtrTy,
1317 false, llvm::GlobalValue::LinkOnceODRLinkage,
1318 llvm::ConstantExpr::getBitCast(Protocol, ProtocolPtrTy), RefName);
1319 GV->setComdat(TheModule.getOrInsertComdat(RefName));
1320 GV->setSection(sectionName<ProtocolReferenceSection>());
1324 EmittedProtocolRef =
true;
1329 llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(ProtocolPtrTy,
1331 llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
1334 auto ProtocolBuilder = builder.beginStruct();
1335 ProtocolBuilder.addNullPointer(PtrTy);
1336 ProtocolBuilder.addInt(SizeTy, Protocols.size());
1337 ProtocolBuilder.add(ProtocolArray);
1338 return ProtocolBuilder.finishAndCreateGlobal(
".objc_protocol_list",
1347 auto *&
Protocol = ExistingProtocols[ProtocolName];
1351 EmittedProtocol =
true;
1353 auto SymName = SymbolForProtocol(ProtocolName);
1354 auto *OldGV = TheModule.getGlobalVariable(SymName);
1364 Protocol =
new llvm::GlobalVariable(TheModule, ProtocolTy,
1372 Protocols.push_back(
1373 llvm::ConstantExpr::getBitCast(GenerateProtocolRef(PI),
1375 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
1378 llvm::Constant *InstanceMethodList, *OptionalInstanceMethodList;
1379 llvm::Constant *ClassMethodList, *OptionalClassMethodList;
1381 OptionalInstanceMethodList);
1382 EmitProtocolMethodList(PD->
class_methods(), ClassMethodList,
1383 OptionalClassMethodList);
1388 auto ProtocolBuilder = builder.beginStruct();
1389 ProtocolBuilder.add(llvm::ConstantExpr::getIntToPtr(
1390 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
1391 ProtocolBuilder.add(MakeConstantString(ProtocolName));
1392 ProtocolBuilder.add(ProtocolList);
1393 ProtocolBuilder.add(InstanceMethodList);
1394 ProtocolBuilder.add(ClassMethodList);
1395 ProtocolBuilder.add(OptionalInstanceMethodList);
1396 ProtocolBuilder.add(OptionalClassMethodList);
1398 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
false,
false));
1400 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
false,
true));
1402 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
true,
false));
1404 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
true,
true));
1406 auto *GV = ProtocolBuilder.finishAndCreateGlobal(SymName,
1408 GV->setSection(sectionName<ProtocolSection>());
1409 GV->setComdat(TheModule.getOrInsertComdat(SymName));
1411 OldGV->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(GV,
1413 OldGV->removeFromParent();
1414 GV->setName(SymName);
1419 llvm::Constant *EnforceType(llvm::Constant *Val,
llvm::Type *Ty) {
1420 if (Val->getType() == Ty)
1422 return llvm::ConstantExpr::getBitCast(Val, Ty);
1425 const std::string &TypeEncoding)
override {
1426 return GetConstantSelector(Sel, TypeEncoding);
1428 llvm::Constant *GetTypeString(llvm::StringRef TypeEncoding) {
1429 if (TypeEncoding.empty())
1431 std::string MangledTypes = TypeEncoding;
1432 std::replace(MangledTypes.begin(), MangledTypes.end(),
1434 std::string TypesVarName =
".objc_sel_types_" + MangledTypes;
1435 auto *TypesGlobal = TheModule.getGlobalVariable(TypesVarName);
1437 llvm::Constant *Init = llvm::ConstantDataArray::getString(VMContext,
1439 auto *GV =
new llvm::GlobalVariable(TheModule, Init->getType(),
1440 true, llvm::GlobalValue::LinkOnceODRLinkage, Init, TypesVarName);
1441 GV->setComdat(TheModule.getOrInsertComdat(TypesVarName));
1445 return llvm::ConstantExpr::getGetElementPtr(TypesGlobal->getValueType(),
1446 TypesGlobal, Zeros);
1448 llvm::Constant *GetConstantSelector(
Selector Sel,
1449 const std::string &TypeEncoding)
override {
1454 std::string MangledTypes = TypeEncoding;
1455 std::replace(MangledTypes.begin(), MangledTypes.end(),
1457 auto SelVarName = (StringRef(
".objc_selector_") + Sel.
getAsString() +
"_" +
1458 MangledTypes).str();
1459 if (
auto *GV = TheModule.getNamedGlobal(SelVarName))
1460 return EnforceType(GV, SelectorTy);
1462 auto SelBuilder = builder.beginStruct();
1463 SelBuilder.add(ExportUniqueString(Sel.
getAsString(),
".objc_sel_name_",
1465 SelBuilder.add(GetTypeString(TypeEncoding));
1466 auto *GV = SelBuilder.finishAndCreateGlobal(SelVarName,
1468 GV->setComdat(TheModule.getOrInsertComdat(SelVarName));
1470 GV->setSection(sectionName<SelectorSection>());
1471 auto *SelVal = EnforceType(GV, SelectorTy);
1474 llvm::StructType *emptyStruct =
nullptr;
1483 std::pair<llvm::Constant*,llvm::Constant*>
1484 GetSectionBounds(StringRef Section) {
1485 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1486 if (emptyStruct ==
nullptr) {
1488 emptyStruct->setBody({},
true);
1490 auto ZeroInit = llvm::Constant::getNullValue(emptyStruct);
1491 auto Sym = [&](StringRef Prefix, StringRef SecSuffix) {
1492 auto *Sym =
new llvm::GlobalVariable(TheModule, emptyStruct,
1494 llvm::GlobalValue::LinkOnceODRLinkage, ZeroInit, Prefix +
1497 Sym->setSection((Section + SecSuffix).str());
1498 Sym->setComdat(TheModule.getOrInsertComdat((Prefix +
1503 return { Sym(
"__start_",
"$a"), Sym(
"__stop",
"$z") };
1505 auto *Start =
new llvm::GlobalVariable(TheModule, PtrTy,
1510 auto *Stop =
new llvm::GlobalVariable(TheModule, PtrTy,
1515 return { Start, Stop };
1520 llvm::Function *ModuleInitFunction()
override {
1522 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
1523 llvm::GlobalValue::LinkOnceODRLinkage,
".objcv2_load_function",
1526 LoadFunction->setComdat(TheModule.getOrInsertComdat(
".objcv2_load_function"));
1528 llvm::BasicBlock *EntryBB =
1531 B.SetInsertPoint(EntryBB);
1533 auto InitStructBuilder = builder.beginStruct();
1534 InitStructBuilder.addInt(Int64Ty, 0);
1535 auto §ionVec = CGM.
getTriple().isOSBinFormatCOFF() ? PECOFFSectionsBaseNames : SectionsBaseNames;
1536 for (
auto *s : sectionVec) {
1537 auto bounds = GetSectionBounds(s);
1538 InitStructBuilder.add(bounds.first);
1539 InitStructBuilder.add(bounds.second);
1541 auto *InitStruct = InitStructBuilder.finishAndCreateGlobal(
".objc_init",
1544 InitStruct->setComdat(TheModule.getOrInsertComdat(
".objc_init"));
1546 CallRuntimeFunction(B,
"__objc_load", {InitStruct});;
1553 auto *InitVar =
new llvm::GlobalVariable(TheModule, LoadFunction->getType(),
1554 true, llvm::GlobalValue::LinkOnceAnyLinkage,
1555 LoadFunction,
".objc_ctor");
1558 assert(InitVar->getName() ==
".objc_ctor");
1564 if (CGM.
getTriple().isOSBinFormatCOFF())
1565 InitVar->setSection(
".CRT$XCLz");
1569 InitVar->setSection(
".init_array");
1571 InitVar->setSection(
".ctors");
1574 InitVar->setComdat(TheModule.getOrInsertComdat(
".objc_ctor"));
1576 for (
auto *C : Categories) {
1577 auto *Cat = cast<llvm::GlobalVariable>(C->stripPointerCasts());
1578 Cat->setSection(sectionName<CategorySection>());
1582 StringRef Section) {
1583 auto nullBuilder = builder.beginStruct();
1584 for (
auto *F : Init)
1586 auto GV = nullBuilder.finishAndCreateGlobal(Name, CGM.
getPointerAlign(),
1587 false, llvm::GlobalValue::LinkOnceODRLinkage);
1588 GV->setSection(Section);
1589 GV->setComdat(TheModule.getOrInsertComdat(Name));
1594 for (
auto clsAlias : ClassAliases)
1595 createNullGlobal(std::string(
".objc_class_alias") +
1596 clsAlias.second, { MakeConstantString(clsAlias.second),
1597 GetClassVar(clsAlias.first) }, sectionName<ClassAliasSection>());
1602 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
1603 createNullGlobal(
".objc_null_selector", {NULLPtr, NULLPtr},
1604 sectionName<SelectorSection>());
1605 if (Categories.empty())
1606 createNullGlobal(
".objc_null_category", {NULLPtr, NULLPtr,
1607 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr},
1608 sectionName<CategorySection>());
1609 if (!EmittedClass) {
1610 createNullGlobal(
".objc_null_cls_init_ref", NULLPtr,
1611 sectionName<ClassSection>());
1612 createNullGlobal(
".objc_null_class_ref", { NULLPtr, NULLPtr },
1613 sectionName<ClassReferenceSection>());
1615 if (!EmittedProtocol)
1616 createNullGlobal(
".objc_null_protocol", {NULLPtr, NULLPtr, NULLPtr,
1617 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr,
1618 NULLPtr}, sectionName<ProtocolSection>());
1619 if (!EmittedProtocolRef)
1620 createNullGlobal(
".objc_null_protocol_ref", {NULLPtr},
1621 sectionName<ProtocolReferenceSection>());
1622 if (ClassAliases.empty())
1623 createNullGlobal(
".objc_null_class_alias", { NULLPtr, NULLPtr },
1624 sectionName<ClassAliasSection>());
1625 if (ConstantStrings.empty()) {
1626 auto i32Zero = llvm::ConstantInt::get(Int32Ty, 0);
1627 createNullGlobal(
".objc_null_constant_string", { NULLPtr, i32Zero,
1628 i32Zero, i32Zero, i32Zero, NULLPtr },
1629 sectionName<ConstantStringSection>());
1632 ConstantStrings.clear();
1636 if (EarlyInitList.size() > 0) {
1642 for (
const auto &lateInit : EarlyInitList) {
1643 auto *global = TheModule.getGlobalVariable(lateInit.first);
1645 b.CreateAlignedStore(global,
1652 auto *InitVar =
new llvm::GlobalVariable(CGM.
getModule(), Init->getType(),
1654 Init,
".objc_early_init_ptr");
1655 InitVar->setSection(
".CRT$XCLb");
1664 std::string TypeEncoding;
1667 std::replace(TypeEncoding.begin(), TypeEncoding.end(),
1669 const std::string Name =
"__objc_ivar_offset_" + ID->
getNameAsString()
1677 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
1678 if (!IvarOffsetPointer)
1679 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule, IntTy,
false,
1683 if (Offset->getType() != PtrDiffTy)
1684 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
1689 bool IsCOFF = CGM.
getTriple().isOSBinFormatCOFF();
1695 auto *classNameConstant = MakeConstantString(className);
1698 auto metaclassFields = builder.beginStruct();
1700 metaclassFields.addNullPointer(PtrTy);
1702 metaclassFields.addNullPointer(PtrTy);
1704 metaclassFields.add(classNameConstant);
1706 metaclassFields.addInt(LongTy, 0);
1709 metaclassFields.addInt(LongTy, 1);
1713 metaclassFields.addInt(LongTy, 0);
1715 metaclassFields.addNullPointer(PtrTy);
1720 metaclassFields.addNullPointer(PtrTy);
1725 metaclassFields.addBitCast(
1726 GenerateMethodList(className,
"", ClassMethods,
true),
1730 metaclassFields.addNullPointer(PtrTy);
1732 metaclassFields.addNullPointer(PtrTy);
1734 metaclassFields.addNullPointer(PtrTy);
1736 metaclassFields.addNullPointer(PtrTy);
1738 metaclassFields.addNullPointer(PtrTy);
1740 metaclassFields.addNullPointer(PtrTy);
1742 metaclassFields.addNullPointer(PtrTy);
1744 metaclassFields.addInt(LongTy, 0);
1746 metaclassFields.add(GeneratePropertyList(OID, classDecl,
true));
1748 auto *metaclass = metaclassFields.finishAndCreateGlobal(
1749 ManglePublicSymbol(
"OBJC_METACLASS_") + className,
1752 auto classFields = builder.beginStruct();
1754 classFields.add(metaclass);
1759 llvm::Constant *SuperClass =
nullptr;
1760 if (SuperClassDecl) {
1761 auto SuperClassName = SymbolForClass(SuperClassDecl->
getNameAsString());
1762 SuperClass = TheModule.getNamedGlobal(SuperClassName);
1765 SuperClass =
new llvm::GlobalVariable(TheModule, PtrTy,
false,
1768 auto Storage = llvm::GlobalValue::DefaultStorageClass;
1769 if (SuperClassDecl->
hasAttr<DLLImportAttr>())
1770 Storage = llvm::GlobalValue::DLLImportStorageClass;
1771 else if (SuperClassDecl->
hasAttr<DLLExportAttr>())
1772 Storage = llvm::GlobalValue::DLLExportStorageClass;
1774 cast<llvm::GlobalValue>(SuperClass)->setDLLStorageClass(Storage);
1778 classFields.add(llvm::ConstantExpr::getBitCast(SuperClass, PtrTy));
1780 classFields.addNullPointer(PtrTy);
1782 classFields.addNullPointer(PtrTy);
1784 classFields.add(classNameConstant);
1786 classFields.addInt(LongTy, 0);
1789 classFields.addInt(LongTy, 0);
1791 int superInstanceSize = !SuperClassDecl ? 0 :
1795 classFields.addInt(LongTy,
1797 superInstanceSize));
1800 classFields.addNullPointer(PtrTy);
1805 llvm::DataLayout td(&TheModule);
1808 auto ivarListBuilder =
b.beginStruct();
1810 ivarListBuilder.addInt(IntTy, ivar_count);
1812 llvm::StructType *ObjCIvarTy = llvm::StructType::get(
1818 ivarListBuilder.addInt(SizeTy, td.getTypeSizeInBits(ObjCIvarTy) /
1821 auto ivarArrayBuilder = ivarListBuilder.beginArray();
1824 auto ivarTy = IVD->getType();
1825 auto ivarBuilder = ivarArrayBuilder.beginStruct();
1827 ivarBuilder.add(MakeConstantString(IVD->getNameAsString()));
1829 std::string TypeStr;
1832 ivarBuilder.add(MakeConstantString(TypeStr));
1834 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
1835 uint64_t Offset = BaseOffset - superInstanceSize;
1836 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
1837 std::string OffsetName = GetIVarOffsetVariableName(classDecl, IVD);
1838 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
1840 OffsetVar->setInitializer(OffsetValue);
1842 OffsetVar =
new llvm::GlobalVariable(TheModule, IntTy,
1844 OffsetValue, OffsetName);
1845 auto ivarVisibility =
1851 OffsetVar->setVisibility(ivarVisibility);
1852 ivarBuilder.add(OffsetVar);
1854 ivarBuilder.addInt(Int32Ty,
1864 ivarBuilder.addInt(Int32Ty,
1865 (align << 3) | (1<<2) |
1866 FlagsForOwnership(ivarTy.getQualifiers().getObjCLifetime()));
1867 ivarBuilder.finishAndAddTo(ivarArrayBuilder);
1869 ivarArrayBuilder.finishAndAddTo(ivarListBuilder);
1870 auto ivarList = ivarListBuilder.finishAndCreateGlobal(
".objc_ivar_list",
1872 llvm::GlobalValue::PrivateLinkage);
1873 classFields.add(ivarList);
1877 InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
1880 if (propImpl->getPropertyImplementation() ==
1885 InstanceMethods.push_back(OMD);
1891 if (InstanceMethods.size() == 0)
1892 classFields.addNullPointer(PtrTy);
1894 classFields.addBitCast(
1895 GenerateMethodList(className,
"", InstanceMethods,
false),
1898 classFields.addNullPointer(PtrTy);
1900 classFields.addNullPointer(PtrTy);
1902 classFields.addNullPointer(PtrTy);
1904 classFields.addNullPointer(PtrTy);
1906 classFields.addNullPointer(PtrTy);
1909 for (
const auto *I : classDecl->
protocols())
1910 Protocols.push_back(
1911 llvm::ConstantExpr::getBitCast(GenerateProtocolRef(I),
1913 if (Protocols.empty())
1914 classFields.addNullPointer(PtrTy);
1916 classFields.add(GenerateProtocolList(Protocols));
1918 classFields.addNullPointer(PtrTy);
1920 classFields.addInt(LongTy, 0);
1922 classFields.add(GeneratePropertyList(OID, classDecl));
1925 classFields.finishAndCreateGlobal(SymbolForClass(className),
1928 auto *classRefSymbol = GetClassVar(className);
1929 classRefSymbol->setSection(sectionName<ClassReferenceSection>());
1930 classRefSymbol->setInitializer(llvm::ConstantExpr::getBitCast(classStruct, IdTy));
1935 cast<llvm::GlobalValue>(classStruct)->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1936 cast<llvm::GlobalValue>(classRefSymbol)->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1940 std::pair<llvm::Constant*, int>
v{classStruct, 1};
1941 EarlyInitList.emplace_back(SuperClass->getName(), std::move(
v));
1949 if (ClassPtrAlias) {
1950 ClassPtrAlias->replaceAllUsesWith(
1951 llvm::ConstantExpr::getBitCast(classStruct, IdTy));
1952 ClassPtrAlias->eraseFromParent();
1953 ClassPtrAlias =
nullptr;
1955 if (
auto Placeholder =
1956 TheModule.getNamedGlobal(SymbolForClass(className)))
1957 if (Placeholder != classStruct) {
1958 Placeholder->replaceAllUsesWith(
1959 llvm::ConstantExpr::getBitCast(classStruct, Placeholder->getType()));
1960 Placeholder->eraseFromParent();
1961 classStruct->setName(SymbolForClass(className));
1963 if (MetaClassPtrAlias) {
1964 MetaClassPtrAlias->replaceAllUsesWith(
1965 llvm::ConstantExpr::getBitCast(metaclass, IdTy));
1966 MetaClassPtrAlias->eraseFromParent();
1967 MetaClassPtrAlias =
nullptr;
1969 assert(classStruct->getName() == SymbolForClass(className));
1971 auto classInitRef =
new llvm::GlobalVariable(TheModule,
1973 classStruct, ManglePublicSymbol(
"OBJC_INIT_CLASS_") + className);
1974 classInitRef->setSection(sectionName<ClassSection>());
1977 EmittedClass =
true;
1980 CGObjCGNUstep2(
CodeGenModule &Mod) : CGObjCGNUstep(Mod, 10, 4, 2) {
1981 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
1982 PtrToObjCSuperTy, SelectorTy);
1991 PropertyMetadataTy =
1993 { PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty });
1998 const char *
const CGObjCGNUstep2::SectionsBaseNames[8] =
2002 "__objc_class_refs",
2005 "__objc_protocol_refs",
2006 "__objc_class_aliases",
2007 "__objc_constant_string" 2010 const char *
const CGObjCGNUstep2::PECOFFSectionsBaseNames[8] =
2023 class CGObjCObjFW:
public CGObjCGNU {
2027 LazyRuntimeFunction MsgLookupFn;
2030 LazyRuntimeFunction MsgLookupFnSRet;
2034 LazyRuntimeFunction MsgLookupSuperFn, MsgLookupSuperFnSRet;
2038 MessageSendInfo &MSI)
override {
2041 EnforceType(Builder, Receiver, IdTy),
2042 EnforceType(Builder, cmd, SelectorTy) };
2044 llvm::CallBase *imp;
2050 imp->setMetadata(msgSendMDKind, node);
2055 llvm::Value *cmd, MessageSendInfo &MSI)
override {
2058 EnforceType(Builder, ObjCSuper.
getPointer(), PtrToObjCSuperTy), cmd,
2068 bool isWeak)
override {
2070 return CGObjCGNU::GetClassNamed(CGF, Name, isWeak);
2073 std::string SymbolName =
"_OBJC_CLASS_" + Name;
2074 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(SymbolName);
2076 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
2078 nullptr, SymbolName);
2085 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
2086 MsgLookupFnSRet.init(&CGM,
"objc_msg_lookup_stret", IMPTy, IdTy,
2089 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
2090 PtrToObjCSuperTy, SelectorTy);
2091 MsgLookupSuperFnSRet.init(&CGM,
"objc_msg_lookup_super_stret", IMPTy,
2092 PtrToObjCSuperTy, SelectorTy);
2100 void CGObjCGNU::EmitClassRef(
const std::string &className) {
2101 std::string symbolRef =
"__objc_class_ref_" + className;
2103 if (TheModule.getGlobalVariable(symbolRef))
2105 std::string symbolName =
"__objc_class_name_" + className;
2106 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
2108 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
2110 nullptr, symbolName);
2112 new llvm::GlobalVariable(TheModule, ClassSymbol->getType(),
true,
2113 llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef);
2116 CGObjCGNU::CGObjCGNU(
CodeGenModule &cgm,
unsigned runtimeABIVersion,
2117 unsigned protocolClassVersion,
unsigned classABI)
2119 VMContext(cgm.getLLVMContext()), ClassPtrAlias(nullptr),
2120 MetaClassPtrAlias(nullptr), RuntimeVersion(runtimeABIVersion),
2121 ProtocolVersion(protocolClassVersion), ClassABIVersion(classABI) {
2123 msgSendMDKind = VMContext.getMDKindID(
"GNUObjCMessageSend");
2128 IntTy = cast<llvm::IntegerType>(
2130 LongTy = cast<llvm::IntegerType>(
2132 SizeTy = cast<llvm::IntegerType>(
2134 PtrDiffTy = cast<llvm::IntegerType>(
2138 Int8Ty = llvm::Type::getInt8Ty(VMContext);
2140 PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
2141 ProtocolPtrTy = llvm::PointerType::getUnqual(
2144 Zeros[0] = llvm::ConstantInt::get(LongTy, 0);
2145 Zeros[1] = Zeros[0];
2146 NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty);
2150 SelectorTy = PtrToInt8Ty;
2155 PtrToIntTy = llvm::PointerType::getUnqual(IntTy);
2156 PtrTy = PtrToInt8Ty;
2158 Int32Ty = llvm::Type::getInt32Ty(VMContext);
2159 Int64Ty = llvm::Type::getInt64Ty(VMContext);
2162 CGM.
getDataLayout().getPointerSizeInBits() == 32 ? Int32Ty : Int64Ty;
2173 PtrToIdTy = llvm::PointerType::getUnqual(IdTy);
2174 ProtocolTy = llvm::StructType::get(IdTy,
2196 PropertyMetadataTy = llvm::StructType::get(CGM.
getLLVMContext(), {
2197 PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty,
2198 PtrToInt8Ty, PtrToInt8Ty });
2200 ObjCSuperTy = llvm::StructType::get(IdTy, IdTy);
2201 PtrToObjCSuperTy = llvm::PointerType::getUnqual(ObjCSuperTy);
2203 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
2206 ExceptionThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy);
2207 ExceptionReThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy);
2209 SyncEnterFn.init(&CGM,
"objc_sync_enter", IntTy, IdTy);
2211 SyncExitFn.init(&CGM,
"objc_sync_exit", IntTy, IdTy);
2214 EnumerationMutationFn.init(&CGM,
"objc_enumerationMutation", VoidTy, IdTy);
2217 GetPropertyFn.init(&CGM,
"objc_getProperty", IdTy, IdTy, SelectorTy,
2220 SetPropertyFn.init(&CGM,
"objc_setProperty", VoidTy, IdTy, SelectorTy,
2221 PtrDiffTy, IdTy, BoolTy, BoolTy);
2223 GetStructPropertyFn.init(&CGM,
"objc_getPropertyStruct", VoidTy, PtrTy, PtrTy,
2224 PtrDiffTy, BoolTy, BoolTy);
2226 SetStructPropertyFn.init(&CGM,
"objc_setPropertyStruct", VoidTy, PtrTy, PtrTy,
2227 PtrDiffTy, BoolTy, BoolTy);
2230 llvm::Type *IMPArgs[] = { IdTy, SelectorTy };
2231 IMPTy = llvm::PointerType::getUnqual(llvm::FunctionType::get(IdTy, IMPArgs,
2236 RuntimeVersion = 10;
2251 IvarAssignFn.init(&CGM,
"objc_assign_ivar", IdTy, IdTy, IdTy, PtrDiffTy);
2253 StrongCastAssignFn.init(&CGM,
"objc_assign_strongCast", IdTy, IdTy,
2256 GlobalAssignFn.init(&CGM,
"objc_assign_global", IdTy, IdTy, PtrToIdTy);
2258 WeakAssignFn.init(&CGM,
"objc_assign_weak", IdTy, IdTy, PtrToIdTy);
2260 WeakReadFn.init(&CGM,
"objc_read_weak", IdTy, PtrToIdTy);
2262 MemMoveFn.init(&CGM,
"objc_memmove_collectable", PtrTy, PtrTy, PtrTy,
2268 const std::string &Name,
bool isWeak) {
2269 llvm::Constant *ClassName = MakeConstantString(Name);
2281 llvm::FunctionType::get(IdTy, PtrToInt8Ty,
true),
"objc_lookup_class");
2291 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value))
2297 auto *
Value = GetClassNamed(CGF,
"NSAutoreleasePool",
false);
2298 if (CGM.
getTriple().isOSBinFormatCOFF()) {
2299 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value)) {
2305 for (
const auto &Result : DC->
lookup(&II))
2306 if ((VD = dyn_cast<VarDecl>(Result)))
2316 const std::string &TypeEncoding) {
2318 llvm::GlobalAlias *SelValue =
nullptr;
2321 e = Types.end() ;
i!=e ;
i++) {
2322 if (
i->first == TypeEncoding) {
2323 SelValue =
i->second;
2329 SelectorTy->getElementType(), 0, llvm::GlobalValue::PrivateLinkage,
2330 ".objc_selector_" + Sel.
getAsString(), &TheModule);
2331 Types.emplace_back(TypeEncoding, SelValue);
2349 return GetTypedSelector(CGF, Sel, std::string());
2355 return GetTypedSelector(CGF, Method->
getSelector(), SelTypes);
2358 llvm::Constant *CGObjCGNU::GetEHType(
QualType T) {
2365 return MakeConstantString(
"@id");
2373 assert(OPT &&
"Invalid @catch type.");
2375 assert(IDecl &&
"Invalid @catch type.");
2379 llvm::Constant *CGObjCGNUstep::GetEHType(
QualType T) {
2380 if (usesSEHExceptions)
2384 return CGObjCGNU::GetEHType(T);
2392 llvm::Constant *IDEHType =
2393 CGM.
getModule().getGlobalVariable(
"__objc_id_type_info");
2396 new llvm::GlobalVariable(CGM.
getModule(), PtrToInt8Ty,
2399 nullptr,
"__objc_id_type_info");
2400 return llvm::ConstantExpr::getBitCast(IDEHType, PtrToInt8Ty);
2405 assert(PT &&
"Invalid @catch type.");
2407 assert(IT &&
"Invalid @catch type.");
2410 std::string typeinfoName =
"__objc_eh_typeinfo_" + className;
2413 llvm::Constant *typeinfo = TheModule.getGlobalVariable(typeinfoName);
2415 return llvm::ConstantExpr::getBitCast(typeinfo, PtrToInt8Ty);
2422 const char *vtableName =
"_ZTVN7gnustep7libobjc22__objc_class_type_infoE";
2423 auto *Vtable = TheModule.getGlobalVariable(vtableName);
2425 Vtable =
new llvm::GlobalVariable(TheModule, PtrToInt8Ty,
true,
2427 nullptr, vtableName);
2429 llvm::Constant *Two = llvm::ConstantInt::get(IntTy, 2);
2430 auto *BVtable = llvm::ConstantExpr::getBitCast(
2431 llvm::ConstantExpr::getGetElementPtr(Vtable->getValueType(), Vtable, Two),
2434 llvm::Constant *typeName =
2435 ExportUniqueString(className,
"__objc_eh_typename_");
2438 auto fields = builder.beginStruct();
2439 fields.add(BVtable);
2440 fields.add(typeName);
2441 llvm::Constant *TI =
2442 fields.finishAndCreateGlobal(
"__objc_eh_typeinfo_" + className,
2445 llvm::GlobalValue::LinkOnceODRLinkage);
2446 return llvm::ConstantExpr::getBitCast(TI, PtrToInt8Ty);
2452 std::string Str = SL->
getString().str();
2456 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
2457 if (old != ObjCStrings.end())
2462 if (StringClass.empty()) StringClass =
"NSConstantString";
2464 std::string Sym =
"_OBJC_CLASS_";
2467 llvm::Constant *isa = TheModule.getNamedGlobal(Sym);
2470 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
2471 llvm::GlobalValue::ExternalWeakLinkage,
nullptr, Sym);
2472 else if (isa->getType() != PtrToIdTy)
2473 isa = llvm::ConstantExpr::getBitCast(isa, PtrToIdTy);
2476 auto Fields = Builder.beginStruct();
2478 Fields.add(MakeConstantString(Str));
2479 Fields.addInt(IntTy, Str.size());
2480 llvm::Constant *ObjCStr =
2482 ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStr, PtrToInt8Ty);
2483 ObjCStrings[Str] = ObjCStr;
2484 ConstantStrings.push_back(ObjCStr);
2497 bool isCategoryImpl,
2499 bool IsClassMessage,
2504 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2508 if (Sel == ReleaseSel) {
2516 ActualArgs.
add(
RValue::get(EnforceType(Builder, Receiver, IdTy)), ASTIdTy);
2525 ReceiverClass = GetClassNamed(CGF,
2527 if (IsClassMessage) {
2530 llvm::PointerType::getUnqual(IdTy));
2534 ReceiverClass = EnforceType(Builder, ReceiverClass, IdTy);
2536 if (isCategoryImpl) {
2537 llvm::FunctionCallee classLookupFunction =
nullptr;
2538 if (IsClassMessage) {
2540 IdTy, PtrTy,
true),
"objc_get_meta_class");
2543 IdTy, PtrTy,
true),
"objc_get_class");
2545 ReceiverClass = Builder.CreateCall(classLookupFunction,
2553 if (IsClassMessage) {
2554 if (!MetaClassPtrAlias) {
2559 ReceiverClass = MetaClassPtrAlias;
2561 if (!ClassPtrAlias) {
2566 ReceiverClass = ClassPtrAlias;
2570 llvm::Type *CastTy = llvm::StructType::get(IdTy, IdTy);
2572 llvm::PointerType::getUnqual(CastTy));
2580 llvm::StructType *ObjCSuperTy =
2581 llvm::StructType::get(Receiver->getType(), IdTy);
2589 ObjCSuper = EnforceType(Builder, ObjCSuper, PtrToObjCSuperTy);
2592 llvm::Value *imp = LookupIMPSuper(CGF, ObjCSuper, cmd, MSI);
2593 imp = EnforceType(Builder, imp, MSI.MessengerType);
2595 llvm::Metadata *impMD[] = {
2596 llvm::MDString::get(VMContext, Sel.
getAsString()),
2598 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2599 llvm::Type::getInt1Ty(VMContext), IsClassMessage))};
2600 llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD);
2604 llvm::CallBase *call;
2605 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2606 call->setMetadata(msgSendMDKind, node);
2624 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2628 if (Sel == ReleaseSel) {
2647 llvm::BasicBlock *startBB =
nullptr;
2648 llvm::BasicBlock *messageBB =
nullptr;
2649 llvm::BasicBlock *continueBB =
nullptr;
2651 if (!isPointerSizedReturn) {
2652 startBB = Builder.GetInsertBlock();
2656 llvm::Value *isNil = Builder.CreateICmpEQ(Receiver,
2657 llvm::Constant::getNullValue(Receiver->getType()));
2658 Builder.CreateCondBr(isNil, continueBB, messageBB);
2668 cmd = EnforceType(Builder, cmd, SelectorTy);
2669 Receiver = EnforceType(Builder, Receiver, IdTy);
2671 llvm::Metadata *impMD[] = {
2672 llvm::MDString::get(VMContext, Sel.
getAsString()),
2673 llvm::MDString::get(VMContext, Class ? Class->
getNameAsString() :
""),
2674 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2675 llvm::Type::getInt1Ty(VMContext), Class !=
nullptr))};
2676 llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD);
2693 imp = LookupIMP(CGF, Receiver, cmd, node, MSI);
2700 "objc_msgSend_fpret")
2707 "objc_msgSend_stret")
2711 llvm::FunctionType::get(IdTy, IdTy,
true),
"objc_msgSend")
2719 imp = EnforceType(Builder, imp, MSI.MessengerType);
2721 llvm::CallBase *call;
2723 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2724 call->setMetadata(msgSendMDKind, node);
2727 if (!isPointerSizedReturn) {
2728 messageBB = CGF.
Builder.GetInsertBlock();
2729 CGF.
Builder.CreateBr(continueBB);
2733 llvm::PHINode *phi = Builder.CreatePHI(v->getType(), 2);
2734 phi->addIncoming(v, messageBB);
2735 phi->addIncoming(llvm::Constant::getNullValue(v->getType()), startBB);
2739 llvm::PHINode *phi = Builder.CreatePHI(v.
getType(), 2);
2742 CGF.
InitTempAlloca(NullVal, llvm::Constant::getNullValue(RetTy));
2744 phi->addIncoming(NullVal.
getPointer(), startBB);
2747 std::pair<llvm::Value*,llvm::Value*> v = msgRet.
getComplexVal();
2748 llvm::PHINode *phi = Builder.CreatePHI(v.first->getType(), 2);
2749 phi->addIncoming(v.first, messageBB);
2750 phi->addIncoming(llvm::Constant::getNullValue(v.first->getType()),
2752 llvm::PHINode *phi2 = Builder.CreatePHI(v.second->getType(), 2);
2753 phi2->addIncoming(v.second, messageBB);
2754 phi2->addIncoming(llvm::Constant::getNullValue(v.second->getType()),
2764 llvm::Constant *CGObjCGNU::
2765 GenerateMethodList(StringRef ClassName,
2766 StringRef CategoryName,
2768 bool isClassMethodList) {
2769 if (Methods.empty())
2774 auto MethodList = Builder.beginStruct();
2775 MethodList.addNullPointer(CGM.
Int8PtrTy);
2776 MethodList.addInt(Int32Ty, Methods.size());
2779 llvm::StructType *ObjCMethodTy =
2788 llvm::DataLayout td(&TheModule);
2789 MethodList.addInt(SizeTy, td.getTypeSizeInBits(ObjCMethodTy) /
2805 auto MethodArray = MethodList.beginArray();
2807 for (
const auto *OMD : Methods) {
2808 llvm::Constant *FnPtr =
2809 TheModule.getFunction(SymbolNameForMethod(ClassName, CategoryName,
2811 isClassMethodList));
2812 assert(FnPtr &&
"Can't generate metadata for method that doesn't exist");
2813 auto Method = MethodArray.beginStruct(ObjCMethodTy);
2815 Method.addBitCast(FnPtr, IMPTy);
2816 Method.
add(GetConstantSelector(OMD->getSelector(),
2820 Method.
add(MakeConstantString(OMD->getSelector().getAsString()));
2822 Method.addBitCast(FnPtr, IMPTy);
2824 Method.finishAndAddTo(MethodArray);
2826 MethodArray.finishAndAddTo(MethodList);
2829 return MethodList.finishAndCreateGlobal(
".objc_method_list",
2834 llvm::Constant *CGObjCGNU::
2840 if (IvarNames.empty())
2846 auto IvarList = Builder.beginStruct();
2847 IvarList.addInt(IntTy, (
int)IvarNames.size());
2850 llvm::StructType *ObjCIvarTy =
2851 llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, IntTy);
2854 auto Ivars = IvarList.beginArray(ObjCIvarTy);
2855 for (
unsigned int i = 0, e = IvarNames.size() ;
i < e ;
i++) {
2856 auto Ivar = Ivars.beginStruct(ObjCIvarTy);
2857 Ivar.
add(IvarNames[
i]);
2858 Ivar.
add(IvarTypes[i]);
2859 Ivar.
add(IvarOffsets[i]);
2860 Ivar.finishAndAddTo(Ivars);
2862 Ivars.finishAndAddTo(IvarList);
2865 return IvarList.finishAndCreateGlobal(
".objc_ivar_list",
2870 llvm::Constant *CGObjCGNU::GenerateClassStructure(
2871 llvm::Constant *MetaClass,
2872 llvm::Constant *SuperClass,
2875 llvm::Constant *Version,
2876 llvm::Constant *InstanceSize,
2877 llvm::Constant *IVars,
2878 llvm::Constant *Methods,
2879 llvm::Constant *Protocols,
2880 llvm::Constant *IvarOffsets,
2881 llvm::Constant *Properties,
2882 llvm::Constant *StrongIvarBitmap,
2883 llvm::Constant *WeakIvarBitmap,
2892 llvm::StructType *ClassTy = llvm::StructType::get(
2909 IvarOffsets->getType(),
2910 Properties->getType(),
2916 auto Elements = Builder.beginStruct(ClassTy);
2921 Elements.addBitCast(MetaClass, PtrToInt8Ty);
2923 Elements.add(SuperClass);
2925 Elements.add(MakeConstantString(Name,
".class_name"));
2927 Elements.addInt(LongTy, 0);
2929 Elements.addInt(LongTy, info);
2932 llvm::DataLayout td(&TheModule);
2933 Elements.addInt(LongTy,
2934 td.getTypeSizeInBits(ClassTy) /
2937 Elements.add(InstanceSize);
2939 Elements.add(IVars);
2941 Elements.add(Methods);
2944 Elements.add(NULLPtr);
2946 Elements.add(NULLPtr);
2948 Elements.add(NULLPtr);
2950 Elements.addBitCast(Protocols, PtrTy);
2952 Elements.add(NULLPtr);
2954 Elements.addInt(LongTy, ClassABIVersion);
2956 Elements.add(IvarOffsets);
2958 Elements.add(Properties);
2960 Elements.add(StrongIvarBitmap);
2962 Elements.add(WeakIvarBitmap);
2967 std::string ClassSym((isMeta ?
"_OBJC_METACLASS_":
"_OBJC_CLASS_") +
2969 llvm::GlobalVariable *ClassRef = TheModule.getNamedGlobal(ClassSym);
2970 llvm::Constant *Class =
2971 Elements.finishAndCreateGlobal(ClassSym, CGM.
getPointerAlign(),
false,
2974 ClassRef->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(Class,
2975 ClassRef->getType()));
2976 ClassRef->removeFromParent();
2977 Class->setName(ClassSym);
2982 llvm::Constant *CGObjCGNU::
2985 llvm::StructType *ObjCMethodDescTy =
2986 llvm::StructType::get(CGM.
getLLVMContext(), { PtrToInt8Ty, PtrToInt8Ty });
2989 auto MethodList = Builder.beginStruct();
2990 MethodList.addInt(IntTy, Methods.size());
2991 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
2992 for (
auto *M : Methods) {
2993 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
2995 Method.
add(MakeConstantString(Context.getObjCEncodingForMethodDecl(M)));
2996 Method.finishAndAddTo(MethodArray);
2998 MethodArray.finishAndAddTo(MethodList);
2999 return MethodList.finishAndCreateGlobal(
".objc_method_list",
3008 auto ProtocolList = Builder.beginStruct();
3009 ProtocolList.add(NULLPtr);
3010 ProtocolList.addInt(LongTy, Protocols.size());
3012 auto Elements = ProtocolList.beginArray(PtrToInt8Ty);
3013 for (
const std::string *iter = Protocols.begin(), *endIter = Protocols.end();
3014 iter != endIter ; iter++) {
3015 llvm::Constant *protocol =
nullptr;
3016 llvm::StringMap<llvm::Constant*>::iterator value =
3017 ExistingProtocols.find(*iter);
3018 if (value == ExistingProtocols.end()) {
3019 protocol = GenerateEmptyProtocol(*iter);
3021 protocol = value->getValue();
3023 Elements.addBitCast(protocol, PtrToInt8Ty);
3025 Elements.finishAndAddTo(ProtocolList);
3026 return ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
3041 CGObjCGNU::GenerateEmptyProtocol(StringRef ProtocolName) {
3042 llvm::Constant *ProtocolList = GenerateProtocolList({});
3043 llvm::Constant *MethodList = GenerateProtocolMethodList({});
3044 MethodList = llvm::ConstantExpr::getBitCast(MethodList, PtrToInt8Ty);
3048 auto Elements = Builder.beginStruct();
3052 Elements.add(llvm::ConstantExpr::getIntToPtr(
3053 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3055 Elements.add(MakeConstantString(ProtocolName,
".objc_protocol_name"));
3056 Elements.add(ProtocolList);
3057 Elements.add(MethodList);
3058 Elements.add(MethodList);
3059 Elements.add(MethodList);
3060 Elements.add(MethodList);
3061 Elements.add(NULLPtr);
3062 Elements.add(NULLPtr);
3063 return Elements.finishAndCreateGlobal(SymbolForProtocol(ProtocolName),
3076 Protocols.push_back(PI->getNameAsString());
3080 if (I->isOptional())
3081 OptionalInstanceMethods.push_back(I);
3083 InstanceMethods.push_back(I);
3088 if (I->isOptional())
3089 OptionalClassMethods.push_back(I);
3091 ClassMethods.push_back(I);
3093 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
3094 llvm::Constant *InstanceMethodList =
3095 GenerateProtocolMethodList(InstanceMethods);
3096 llvm::Constant *ClassMethodList =
3097 GenerateProtocolMethodList(ClassMethods);
3098 llvm::Constant *OptionalInstanceMethodList =
3099 GenerateProtocolMethodList(OptionalInstanceMethods);
3100 llvm::Constant *OptionalClassMethodList =
3101 GenerateProtocolMethodList(OptionalClassMethods);
3109 llvm::Constant *PropertyList =
3110 GeneratePropertyList(
nullptr, PD,
false,
false);
3111 llvm::Constant *OptionalPropertyList =
3112 GeneratePropertyList(
nullptr, PD,
false,
true);
3119 auto Elements = Builder.beginStruct();
3121 llvm::ConstantExpr::getIntToPtr(
3122 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3123 Elements.add(MakeConstantString(ProtocolName));
3124 Elements.add(ProtocolList);
3125 Elements.add(InstanceMethodList);
3126 Elements.add(ClassMethodList);
3127 Elements.add(OptionalInstanceMethodList);
3128 Elements.add(OptionalClassMethodList);
3129 Elements.add(PropertyList);
3130 Elements.add(OptionalPropertyList);
3131 ExistingProtocols[ProtocolName] =
3132 llvm::ConstantExpr::getBitCast(
3133 Elements.finishAndCreateGlobal(
".objc_protocol", CGM.
getPointerAlign()),
3136 void CGObjCGNU::GenerateProtocolHolderCategory() {
3140 auto Elements = Builder.beginStruct();
3142 const std::string ClassName =
"__ObjC_Protocol_Holder_Ugly_Hack";
3143 const std::string CategoryName =
"AnotherHack";
3144 Elements.add(MakeConstantString(CategoryName));
3145 Elements.add(MakeConstantString(ClassName));
3147 Elements.addBitCast(GenerateMethodList(
3148 ClassName, CategoryName, {},
false), PtrTy);
3150 Elements.addBitCast(GenerateMethodList(
3151 ClassName, CategoryName, {},
true), PtrTy);
3155 auto ProtocolList = ProtocolListBuilder.beginStruct();
3156 ProtocolList.add(NULLPtr);
3157 ProtocolList.addInt(LongTy, ExistingProtocols.size());
3158 auto ProtocolElements = ProtocolList.beginArray(PtrTy);
3159 for (
auto iter = ExistingProtocols.begin(), endIter = ExistingProtocols.end();
3160 iter != endIter ; iter++) {
3161 ProtocolElements.addBitCast(iter->getValue(), PtrTy);
3163 ProtocolElements.finishAndAddTo(ProtocolList);
3164 Elements.addBitCast(
3165 ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
3168 Categories.push_back(llvm::ConstantExpr::getBitCast(
3185 int bitCount = bits.size();
3187 if (bitCount < ptrBits) {
3189 for (
int i=0 ; i<bitCount ; ++
i) {
3190 if (bits[i]) val |= 1ULL<<(i+1);
3192 return llvm::ConstantInt::get(IntPtrTy, val);
3196 while (v < bitCount) {
3198 for (
int i=0 ; (i<32) && (v<bitCount) ; ++
i) {
3199 if (bits[v]) word |= 1<<
i;
3202 values.push_back(llvm::ConstantInt::get(Int32Ty, word));
3206 auto fields = builder.beginStruct();
3207 fields.addInt(Int32Ty, values.size());
3208 auto array = fields.beginArray();
3209 for (
auto v : values) array.add(v);
3210 array.finishAndAddTo(fields);
3212 llvm::Constant *GS =
3214 llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy);
3218 llvm::Constant *CGObjCGNU::GenerateCategoryProtocolList(
const 3223 return GenerateProtocolList(Protocols);
3235 auto Elements = Builder.beginStruct();
3236 Elements.add(MakeConstantString(CategoryName));
3237 Elements.add(MakeConstantString(ClassName));
3240 InstanceMethods.insert(InstanceMethods.begin(), OCD->
instmeth_begin(),
3242 Elements.addBitCast(
3243 GenerateMethodList(ClassName, CategoryName, InstanceMethods,
false),
3250 Elements.addBitCast(
3251 GenerateMethodList(ClassName, CategoryName, ClassMethods,
true),
3254 Elements.addBitCast(GenerateCategoryProtocolList(CatDecl), PtrTy);
3260 Elements.addBitCast(GeneratePropertyList(OCD, Category,
false), PtrTy);
3262 Elements.addBitCast(GeneratePropertyList(OCD, Category,
true), PtrTy);
3264 Elements.addNullPointer(PtrTy);
3265 Elements.addNullPointer(PtrTy);
3269 Categories.push_back(llvm::ConstantExpr::getBitCast(
3270 Elements.finishAndCreateGlobal(
3271 std::string(
".objc_category_")+ClassName+CategoryName,
3276 llvm::Constant *CGObjCGNU::GeneratePropertyList(
const Decl *Container,
3278 bool isClassProperty,
3279 bool protocolOptionalProperties) {
3282 llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
3283 bool isProtocol = isa<ObjCProtocolDecl>(OCD);
3286 std::function<void(const ObjCProtocolDecl *Proto)> collectProtocolProperties
3288 for (
const auto *
P : Proto->protocols())
3289 collectProtocolProperties(
P);
3291 if (isClassProperty != PD->isClassProperty())
3295 if (!isProtocol && !Context.getObjCPropertyImplDeclForPropertyDecl(PD, Container))
3299 Properties.push_back(PD);
3306 if (isClassProperty != PD->isClassProperty())
3309 Properties.push_back(PD);
3313 if (isClassProperty != PD->isClassProperty())
3317 if (isProtocol && (protocolOptionalProperties != PD->isOptional()))
3324 Properties.push_back(PD);
3329 collectProtocolProperties(
P);
3331 for (
const auto *
P : CD->protocols())
3332 collectProtocolProperties(
P);
3334 auto numProperties = Properties.size();
3336 if (numProperties == 0)
3340 auto propertyList = builder.beginStruct();
3341 auto properties = PushPropertyListHeader(propertyList, numProperties);
3345 for (
auto *property : Properties) {
3346 bool isSynthesized =
false;
3349 auto *propertyImpl = Context.getObjCPropertyImplDeclForPropertyDecl(property, Container);
3351 isSynthesized = (propertyImpl->getPropertyImplementation() ==
3353 isDynamic = (propertyImpl->getPropertyImplementation() ==
3357 PushProperty(properties, property, Container, isSynthesized, isDynamic);
3359 properties.finishAndAddTo(propertyList);
3361 return propertyList.finishAndCreateGlobal(
".objc_property_list",
3379 std::string SuperClassName;
3380 if (SuperClassDecl) {
3382 EmitClassRef(SuperClassName);
3392 std::string classSymbolName =
"__objc_class_name_" + ClassName;
3393 if (
auto *symbol = TheModule.getGlobalVariable(classSymbolName)) {
3394 symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0));
3396 new llvm::GlobalVariable(TheModule, LongTy,
false,
3398 llvm::ConstantInt::get(LongTy, 0),
3414 auto IvarOffsetValues = IvarOffsetBuilder.beginArray(PtrToIntTy);
3418 int superInstanceSize = !SuperClassDecl ? 0 :
3423 instanceSize = 0 - (instanceSize - superInstanceSize);
3429 IvarNames.push_back(MakeConstantString(IVD->getNameAsString()));
3431 std::string TypeStr;
3433 IvarTypes.push_back(MakeConstantString(TypeStr));
3434 IvarAligns.push_back(llvm::ConstantInt::get(IntTy,
3438 uint64_t Offset = BaseOffset;
3440 Offset = BaseOffset - superInstanceSize;
3442 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
3444 std::string OffsetName =
"__objc_ivar_offset_value_" + ClassName +
"." +
3445 IVD->getNameAsString();
3447 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
3449 OffsetVar->setInitializer(OffsetValue);
3455 OffsetVar =
new llvm::GlobalVariable(TheModule, Int32Ty,
3457 OffsetValue, OffsetName);
3458 IvarOffsets.push_back(OffsetValue);
3459 IvarOffsetValues.add(OffsetVar);
3461 IvarOwnership.push_back(lt);
3464 StrongIvars.push_back(
true);
3465 WeakIvars.push_back(
false);
3468 StrongIvars.push_back(
false);
3469 WeakIvars.push_back(
true);
3472 StrongIvars.push_back(
false);
3473 WeakIvars.push_back(
false);
3476 llvm::Constant *StrongIvarBitmap = MakeBitField(StrongIvars);
3477 llvm::Constant *WeakIvarBitmap = MakeBitField(WeakIvars);
3478 llvm::GlobalVariable *IvarOffsetArray =
3479 IvarOffsetValues.finishAndCreateGlobal(
".ivar.offsets",
3484 InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
3494 if (propertyImpl->getPropertyImplementation() ==
3499 InstanceMethods.push_back(accessor);
3505 llvm::Constant *Properties = GeneratePropertyList(OID, ClassDecl);
3509 for (
const auto *I : ClassDecl->
protocols())
3510 Protocols.push_back(I->getNameAsString());
3513 llvm::Constant *SuperClass;
3514 if (!SuperClassName.empty()) {
3515 SuperClass = MakeConstantString(SuperClassName,
".super_class_name");
3517 SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty);
3522 llvm::Constant *MethodList = GenerateMethodList(ClassName,
"",
3523 InstanceMethods,
false);
3524 llvm::Constant *ClassMethodList = GenerateMethodList(ClassName,
"",
3525 ClassMethods,
true);
3526 llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
3527 IvarOffsets, IvarAligns, IvarOwnership);
3539 llvm::Constant *offsetPointerIndexes[] = {Zeros[0],
3540 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 2 : 1),
nullptr,
3541 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 3 : 2) };
3543 unsigned ivarIndex = 0;
3546 const std::string Name = GetIVarOffsetVariableName(ClassDecl, IVD);
3547 offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, ivarIndex);
3549 llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr(
3550 cast<llvm::GlobalVariable>(IvarList)->getValueType(), IvarList,
3551 offsetPointerIndexes);
3553 llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name);
3555 offset->setInitializer(offsetValue);
3562 new llvm::GlobalVariable(TheModule, offsetValue->getType(),
3566 llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0);
3569 llvm::Constant *MetaClassStruct = GenerateClassStructure(
3570 NULLPtr, NULLPtr, 0x12L, ClassName.c_str(),
nullptr, Zeros[0],
3571 NULLPtr, ClassMethodList, NULLPtr, NULLPtr,
3572 GeneratePropertyList(OID, ClassDecl,
true), ZeroPtr, ZeroPtr,
true);
3577 llvm::Constant *ClassStruct = GenerateClassStructure(
3578 MetaClassStruct, SuperClass, 0x11L, ClassName.c_str(),
nullptr,
3579 llvm::ConstantInt::get(LongTy, instanceSize), IvarList, MethodList,
3580 GenerateProtocolList(Protocols), IvarOffsetArray, Properties,
3581 StrongIvarBitmap, WeakIvarBitmap);
3586 if (ClassPtrAlias) {
3587 ClassPtrAlias->replaceAllUsesWith(
3588 llvm::ConstantExpr::getBitCast(ClassStruct, IdTy));
3589 ClassPtrAlias->eraseFromParent();
3590 ClassPtrAlias =
nullptr;
3592 if (MetaClassPtrAlias) {
3593 MetaClassPtrAlias->replaceAllUsesWith(
3594 llvm::ConstantExpr::getBitCast(MetaClassStruct, IdTy));
3595 MetaClassPtrAlias->eraseFromParent();
3596 MetaClassPtrAlias =
nullptr;
3600 ClassStruct = llvm::ConstantExpr::getBitCast(ClassStruct, PtrToInt8Ty);
3601 Classes.push_back(ClassStruct);
3604 llvm::Function *CGObjCGNU::ModuleInitFunction() {
3606 if (Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
3607 ExistingProtocols.empty() && SelectorTable.empty())
3611 GenerateProtocolHolderCategory();
3613 llvm::StructType *selStructTy =
3614 dyn_cast<llvm::StructType>(SelectorTy->getElementType());
3618 { PtrToInt8Ty, PtrToInt8Ty });
3619 selStructPtrTy = llvm::PointerType::getUnqual(selStructTy);
3623 llvm::Constant *statics = NULLPtr;
3624 if (!ConstantStrings.empty()) {
3625 llvm::GlobalVariable *fileStatics = [&] {
3627 auto staticsStruct = builder.beginStruct();
3630 if (stringClass.empty()) stringClass =
"NXConstantString";
3631 staticsStruct.add(MakeConstantString(stringClass,
3632 ".objc_static_class_name"));
3634 auto array = staticsStruct.beginArray();
3635 array.addAll(ConstantStrings);
3637 array.finishAndAddTo(staticsStruct);
3639 return staticsStruct.finishAndCreateGlobal(
".objc_statics",
3644 auto allStaticsArray = builder.beginArray(fileStatics->getType());
3645 allStaticsArray.add(fileStatics);
3646 allStaticsArray.addNullPointer(fileStatics->getType());
3648 statics = allStaticsArray.finishAndCreateGlobal(
".objc_statics_ptr",
3650 statics = llvm::ConstantExpr::getBitCast(statics, PtrTy);
3656 unsigned selectorCount;
3659 llvm::GlobalVariable *selectorList = [&] {
3661 auto selectors = builder.beginArray(selStructTy);
3662 auto &table = SelectorTable;
3663 std::vector<Selector> allSelectors;
3664 for (
auto &entry : table)
3665 allSelectors.push_back(entry.first);
3666 llvm::sort(allSelectors);
3668 for (
auto &untypedSel : allSelectors) {
3669 std::string selNameStr = untypedSel.getAsString();
3670 llvm::Constant *selName = ExportUniqueString(selNameStr,
".objc_sel_name");
3672 for (TypedSelector &sel : table[untypedSel]) {
3673 llvm::Constant *selectorTypeEncoding = NULLPtr;
3674 if (!sel.first.empty())
3675 selectorTypeEncoding =
3676 MakeConstantString(sel.first,
".objc_sel_types");
3678 auto selStruct = selectors.beginStruct(selStructTy);
3679 selStruct.add(selName);
3680 selStruct.add(selectorTypeEncoding);
3681 selStruct.finishAndAddTo(selectors);
3684 selectorAliases.push_back(sel.second);
3689 selectorCount = selectors.size();
3695 auto selStruct = selectors.beginStruct(selStructTy);
3696 selStruct.add(NULLPtr);
3697 selStruct.add(NULLPtr);
3698 selStruct.finishAndAddTo(selectors);
3700 return selectors.finishAndCreateGlobal(
".objc_selector_list",
3705 for (
unsigned i = 0; i < selectorCount; ++
i) {
3706 llvm::Constant *idxs[] = {
3708 llvm::ConstantInt::get(Int32Ty, i)
3711 llvm::Constant *selPtr = llvm::ConstantExpr::getGetElementPtr(
3712 selectorList->getValueType(), selectorList, idxs);
3715 selPtr = llvm::ConstantExpr::getBitCast(selPtr, SelectorTy);
3716 selectorAliases[
i]->replaceAllUsesWith(selPtr);
3717 selectorAliases[
i]->eraseFromParent();
3720 llvm::GlobalVariable *symtab = [&] {
3722 auto symtab = builder.beginStruct();
3725 symtab.addInt(LongTy, selectorCount);
3727 symtab.addBitCast(selectorList, selStructPtrTy);
3730 symtab.addInt(CGM.
Int16Ty, Classes.size());
3732 symtab.addInt(CGM.
Int16Ty, Categories.size());
3735 auto classList = symtab.beginArray(PtrToInt8Ty);
3736 classList.addAll(Classes);
3737 classList.addAll(Categories);
3739 classList.add(statics);
3740 classList.add(NULLPtr);
3741 classList.finishAndAddTo(symtab);
3749 llvm::Constant *module = [&] {
3751 LongTy, LongTy, PtrToInt8Ty, symtab->getType(), IntTy
3753 llvm::StructType *moduleTy =
3755 makeArrayRef(moduleEltTys).drop_back(
unsigned(RuntimeVersion < 10)));
3758 auto module = builder.beginStruct(moduleTy);
3760 module.addInt(LongTy, RuntimeVersion);
3762 module.addInt(LongTy, CGM.
getDataLayout().getTypeStoreSize(moduleTy));
3769 module.add(MakeConstantString(path,
".objc_source_file_name"));
3772 if (RuntimeVersion >= 10) {
3775 module.addInt(IntTy, 2);
3779 module.addInt(IntTy, 1);
3781 module.addInt(IntTy, 0);
3784 module.addInt(IntTy, 1);
3795 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
3798 llvm::BasicBlock *EntryBB =
3801 Builder.SetInsertPoint(EntryBB);
3803 llvm::FunctionType *FT =
3804 llvm::FunctionType::get(Builder.getVoidTy(), module->getType(),
true);
3805 llvm::FunctionCallee Register =
3807 Builder.CreateCall(Register, module);
3809 if (!ClassAliases.empty()) {
3810 llvm::Type *ArgTypes[2] = {PtrTy, PtrToInt8Ty};
3811 llvm::FunctionType *RegisterAliasTy =
3812 llvm::FunctionType::get(Builder.getVoidTy(),
3816 llvm::GlobalValue::ExternalWeakLinkage,
"class_registerAlias_np",
3818 llvm::BasicBlock *AliasBB =
3820 llvm::BasicBlock *NoAliasBB =
3824 llvm::Value *HasRegisterAlias = Builder.CreateICmpNE(RegisterAlias,
3825 llvm::Constant::getNullValue(RegisterAlias->getType()));
3826 Builder.CreateCondBr(HasRegisterAlias, AliasBB, NoAliasBB);
3829 Builder.SetInsertPoint(AliasBB);
3831 for (std::vector<ClassAliasPair>::iterator iter = ClassAliases.begin();
3832 iter != ClassAliases.end(); ++iter) {
3833 llvm::Constant *TheClass =
3834 TheModule.getGlobalVariable(
"_OBJC_CLASS_" + iter->first,
true);
3836 TheClass = llvm::ConstantExpr::getBitCast(TheClass, PtrTy);
3837 Builder.CreateCall(RegisterAlias,
3838 {TheClass, MakeConstantString(iter->second)});
3842 Builder.CreateBr(NoAliasBB);
3845 Builder.SetInsertPoint(NoAliasBB);
3847 Builder.CreateRetVoid();
3849 return LoadFunction;
3852 llvm::Function *CGObjCGNU::GenerateMethod(
const ObjCMethodDecl *OMD,
3856 StringRef CategoryName = OCD ? OCD->
getName() :
"";
3857 StringRef ClassName = CD->
getName();
3862 llvm::FunctionType *MethodTy =
3864 std::string FunctionName = SymbolNameForMethod(ClassName, CategoryName,
3865 MethodName, isClassMethod);
3867 llvm::Function *Method
3875 llvm::FunctionCallee CGObjCGNU::GetPropertyGetFunction() {
3876 return GetPropertyFn;
3879 llvm::FunctionCallee CGObjCGNU::GetPropertySetFunction() {
3880 return SetPropertyFn;
3883 llvm::FunctionCallee CGObjCGNU::GetOptimizedPropertySetFunction(
bool atomic,
3888 llvm::FunctionCallee CGObjCGNU::GetGetStructFunction() {
3889 return GetStructPropertyFn;
3892 llvm::FunctionCallee CGObjCGNU::GetSetStructFunction() {
3893 return SetStructPropertyFn;
3896 llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectGetFunction() {
3900 llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectSetFunction() {
3904 llvm::FunctionCallee CGObjCGNU::EnumerationMutationFunction() {
3905 return EnumerationMutationFn;
3932 bool ClearInsertionPoint) {
3934 bool isRethrow =
false;
3938 ExceptionAsObject = Exception;
3941 "Unexpected rethrow outside @catch block.");
3945 if (isRethrow && usesSEHExceptions) {
3954 Throw->setDoesNotReturn();
3958 llvm::CallBase *Throw =
3960 Throw->setDoesNotReturn();
3962 CGF.
Builder.CreateUnreachable();
3963 if (ClearInsertionPoint)
3964 CGF.
Builder.ClearInsertionPoint();
3970 AddrWeakObj = EnforceType(B, AddrWeakObj, PtrToIdTy);
3971 return B.CreateCall(WeakReadFn, AddrWeakObj.
getPointer());
3977 src = EnforceType(B, src, IdTy);
3978 dst = EnforceType(B, dst, PtrToIdTy);
3979 B.CreateCall(WeakAssignFn, {src, dst.
getPointer()});
3986 src = EnforceType(B, src, IdTy);
3987 dst = EnforceType(B, dst, PtrToIdTy);
3989 assert(!threadlocal &&
"EmitObjCGlobalAssign - Threal Local API NYI");
3990 B.CreateCall(GlobalAssignFn, {src, dst.
getPointer()});
3997 src = EnforceType(B, src, IdTy);
3998 dst = EnforceType(B, dst, IdTy);
3999 B.CreateCall(IvarAssignFn, {src, dst.
getPointer(), ivarOffset});
4005 src = EnforceType(B, src, IdTy);
4006 dst = EnforceType(B, dst, PtrToIdTy);
4007 B.CreateCall(StrongCastAssignFn, {src, dst.
getPointer()});
4015 DestPtr = EnforceType(B, DestPtr, PtrTy);
4016 SrcPtr = EnforceType(B, SrcPtr, PtrTy);
4021 llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
4024 const std::string Name = GetIVarOffsetVariableName(ID, Ivar);
4028 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
4029 if (!IvarOffsetPointer)
4030 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule,
4031 llvm::Type::getInt32PtrTy(VMContext),
false,
4033 return IvarOffsetPointer;
4040 unsigned CVRQualifiers) {
4072 if (RuntimeVersion < 10 ||
4074 return CGF.
Builder.CreateZExtOrBitCast(
4077 ObjCIvarOffsetVariable(Interface, Ivar),
4081 std::string name =
"__objc_ivar_offset_value_" +
4084 llvm::Value *Offset = TheModule.getGlobalVariable(name);
4086 auto GV =
new llvm::GlobalVariable(TheModule, IntTy,
4087 false, llvm::GlobalValue::LinkOnceAnyLinkage,
4088 llvm::Constant::getNullValue(IntTy), name);
4093 if (Offset->getType() != PtrDiffTy)
4094 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
4098 return llvm::ConstantInt::get(PtrDiffTy, Offset,
true);
4104 switch (Runtime.getKind()) {
4106 if (Runtime.getVersion() >= VersionTuple(2, 0))
4107 return new CGObjCGNUstep2(CGM);
4108 return new CGObjCGNUstep(CGM);
4111 return new CGObjCGCC(CGM);
4114 return new CGObjCObjFW(CGM);
4120 llvm_unreachable(
"these runtimes are not GNU runtimes");
4122 llvm_unreachable(
"bad runtime");
const llvm::DataLayout & getDataLayout() const
ReturnValueSlot - Contains the address where the return value of a function can be stored...
const ObjCInterfaceType * getInterfaceType() const
If this pointer points to an Objective C @interface type, gets the type for that interface.
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
Defines the clang::ASTContext interface.
CharUnits getIntAlign() const
External linkage, which indicates that the entity can be referred to from other translation units...
protocol_range protocols() const
Smart pointer class that efficiently represents Objective-C method names.
QualType getObjCIdType() const
Represents the Objective-CC id type.
A (possibly-)qualified type.
bool ReturnTypeUsesSRet(const CGFunctionInfo &FI)
Return true iff the given type uses 'sret' when used as a return type.
CodeGenTypes & getTypes()
const CodeGenOptions & getCodeGenOpts() const
all_protocol_range all_referenced_protocols() const
Defines the clang::FileManager interface and associated types.
llvm::LLVMContext & getLLVMContext()
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
The standard implementation of ConstantInitBuilder used in Clang.
const ObjCProtocolList & getReferencedProtocols() const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Implements runtime-specific code generation functions.
Defines the SourceManager interface.
const ASTRecordLayout & getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const
Get or compute information about the layout of the specified Objective-C implementation.
Decl - This represents one declaration (or definition), e.g.
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
Represents Objective-C's @throw statement.
const TargetInfo & getTargetInfo() const
instmeth_iterator instmeth_end() const
constexpr XRayInstrMask Function
'gcc' is the Objective-C runtime shipped with GCC, implementing a fragile Objective-C ABI ...
Represents a variable declaration or definition.
uint64_t ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM, const ObjCInterfaceDecl *OID, const ObjCIvarDecl *Ivar)
Compute an offset to the given ivar, suitable for passing to EmitValueForIvarAtOffset.
Objects with "hidden" visibility are not seen by the dynamic linker.
const T * getAs() const
Member-template getAs<specific type>'.
llvm::GlobalVariable * finishAndCreateGlobal(As &&...args)
Given that this builder was created by beginning an array or struct directly on a ConstantInitBuilder...
ObjCMethodDecl - Represents an instance or class method declaration.
llvm::Value * getPointer() const
Defines the Objective-C statement AST node classes.
classmeth_range class_methods() const
protocol_range protocols() const
void add(RValue rvalue, QualType type)
llvm::Value * EmitObjCThrowOperand(const Expr *expr)
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
uint64_t getPointerWidth(unsigned AddrSpace) const
Return the width of pointers on this target, for the specified address space.
One of these records is kept for each identifier that is lexed.
'macosx-fragile' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the fragil...
void EmitAtSynchronizedStmt(CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S, llvm::FunctionCallee syncEnterFn, llvm::FunctionCallee syncExitFn)
Emits an @synchronize() statement, using the syncEnterFn and syncExitFn arguments as the functions ca...
This table allows us to fully hide how we implement multi-keyword caching.
Represents a class type in Objective C.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool isObjCIdType() const
static const ObjCInterfaceDecl * FindIvarInterface(ASTContext &Context, const ObjCInterfaceDecl *OID, const ObjCIvarDecl *OIVD)
instmeth_range instance_methods() const
ObjCMethodDecl * getSetterMethodDecl() const
virtual bool isDynamic(OpenMPScheduleClauseKind ScheduleKind) const
Check if the specified ScheduleKind is dynamic.
prop_range properties() const
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
const ASTRecordLayout & getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const
Get or compute information about the layout of the specified Objective-C interface.
void InitTempAlloca(Address Alloca, llvm::Value *Value)
InitTempAlloca - Provide an initial value for the given alloca which will be observable at all locati...
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Objects with "default" visibility are seen by the dynamic linker and act like normal objects...
virtual llvm::Value * EmitIvarOffset(CodeGen::CodeGenFunction &CGF, const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar)=0
MessageSendInfo getMessageSendInfo(const ObjCMethodDecl *method, QualType resultType, CallArgList &callArgs)
Compute the pointer-to-function type to which a message send should be casted in order to correctly c...
unsigned getLength() const
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
ObjCContainerDecl - Represents a container for method declarations.
const Expr * getThrowExpr() const
CharUnits - This is an opaque type for sizes expressed in character units.
CharUnits getAlignment() const
Return the alignment of this pointer.
Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void addCompilerUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.compiler.used metadata.
Represents an Objective-C protocol declaration.
CharUnits getPointerAlign() const
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
Represents an ObjC class declaration.
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface...
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
QualType getObjCProtoType() const
Retrieve the type of the Objective-C Protocol class.
std::string getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, bool Extended=false) const
Emit the encoded type for the method declaration Decl into S.
This object can be modified without requiring retains or releases.
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
'watchos' is a variant of iOS for Apple's watchOS.
StringRef getString() const
void addFrom(const CallArgList &other)
Add all the arguments from another CallArgList to this one.
ASTContext & getContext() const
ArrayBuilder beginArray(llvm::Type *eltTy=nullptr)
CGBlockInfo - Information to generate a block literal.
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
This represents one expression.
known_extensions_range known_extensions() const
'macosx' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the non-fragile AB...
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
std::string getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD, const Decl *Container) const
getObjCEncodingForPropertyDecl - Return the encoded type for this method declaration.
virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD)=0
Register an class alias.
llvm::PointerType * getType() const
Return the type of the pointer value.
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
DeclContext * getDeclContext()
uint32_t getCodeUnit(size_t i) const
Represents Objective-C's @synchronized statement.
ObjCInterfaceDecl * getSuperClass() const
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
virtual llvm::Value * GetSelector(CodeGenFunction &CGF, Selector Sel)=0
Get a selector for the specified name and type values.
clang::ObjCRuntime ObjCRuntime
propimpl_range property_impls() const
bool isa(CodeGen::Address addr)
bool isInstanceMethod() const
const TargetInfo & getTarget() const
Selector getSelector() const
'gnustep' is the modern non-fragile GNUstep runtime.
const LangOptions & getLangOpts() const
ASTContext & getContext() const
static bool isNamed(const NamedDecl *ND, const char(&Str)[Len])
void finishAndAddTo(AggregateBuilderBase &parent)
Given that this builder was created by beginning an array or struct component on the given parent bui...
The l-value was considered opaque, so the alignment was determined from a type.
const DirectoryEntry * getDir() const
Return the directory the file lives in.
There is no lifetime qualification on this type.
Address CreateBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
std::string getAsString() const
Derive the full selector name (e.g.
Assigning into this object requires the old value to be released and the new value to be retained...
bool ReturnTypeUsesFPRet(QualType ResultType)
Return true iff the given type uses 'fpret' when used as a return type.
classmeth_iterator classmeth_end() const
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
static DeclContext * castToDeclContext(const TranslationUnitDecl *D)
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
virtual void GenerateProtocol(const ObjCProtocolDecl *OPD)=0
Generate the named protocol.
StringRef getName() const
Interfaces are the core concept in Objective-C for object oriented design.
'objfw' is the Objective-C runtime included in ObjFW
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **callOrInvoke, SourceLocation Loc)
EmitCall - Generate a call of the given function, expecting the given result type, and using the given argument list which specifies both the LLVM arguments and the types they were derived from.
SmallVector< llvm::Value *, 8 > ObjCEHValueStack
ObjCEHValueStack - Stack of Objective-C exception values, used for rethrows.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const
Set visibility, dllimport/dllexport and dso_local.
llvm::IntegerType * Int16Ty
ObjCCategoryDecl * getCategoryDecl() const
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
Cached information about one file (either on disk or in the virtual file system). ...
const CGFunctionInfo & arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD)
Objective-C methods are C functions with some implicit parameters.
virtual CatchTypeInfo getCatchAllTypeInfo()
ObjCCategoryDecl - Represents a category declaration.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isAnyPointerType() const
Represents one property declaration in an Objective-C interface.
All available information about a concrete callee.
Assigning into this object requires a lifetime extension.
const VersionTuple & getVersion() const
classmeth_iterator classmeth_begin() const
The MS C++ ABI needs a pointer to RTTI data plus some flags to describe the type of a catch handler...
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
ConstantAddress GetAddrOfConstantCString(const std::string &Str, const char *GlobalName=nullptr)
Returns a pointer to a character array containing the literal and a terminating '\0' character...
StringRef getName() const
Return the actual identifier string.
void addUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.used metadata.
ObjCIvarDecl * getNextIvar()
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
This class organizes the cross-function state that is used while generating LLVM code.
StructBuilder beginStruct(llvm::StructType *ty=nullptr)
const ObjCInterfaceDecl * getClassInterface() const
Dataflow Directional Tag Classes.
CharUnits getSize() const
getSize - Get the record size in characters.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
void EmitTryCatchStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S, llvm::FunctionCallee beginCatchFn, llvm::FunctionCallee endCatchFn, llvm::FunctionCallee exceptionRethrowFn)
Emits a try / catch statement.
The basic abstraction for the target Objective-C runtime.
llvm::LoadInst * CreateAlignedLoad(llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
FileID getMainFileID() const
Returns the FileID of the main source file.
llvm::Constant * getPointer() const
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
const ObjCInterfaceDecl * getContainingInterface() const
Return the class interface that this ivar is logically contained in; this is either the interface whe...
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::Module & getModule() const
const ObjCInterfaceDecl * getClassInterface() const
'ios' is the Apple-provided NeXT-derived runtime on iOS or the iOS simulator; it is always non-fragil...
Represents a pointer to an Objective C object.
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
virtual llvm::Constant * getAddrOfRTTIDescriptor(QualType Ty)=0
llvm::Type * getElementType() const
Return the type of the values stored in this address.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
This class organizes the cross-module state that is used while lowering AST types to LLVM types...
void getObjCEncodingForType(QualType T, std::string &S, const FieldDecl *Field=nullptr, QualType *NotEncodedT=nullptr) const
Emit the Objective-CC type encoding for the given type T into S.
llvm::PointerType * Int8PtrTy
bool isObjCQualifiedIdType() const
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false)
Create or return a runtime function declaration with the specified type and name. ...
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
SourceManager & getSourceManager()
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Reading or writing from this object requires a barrier call.
TranslationUnitDecl * getTranslationUnitDecl() const
A specialization of Address that requires the address to be an LLVM Constant.
ObjCIvarDecl - Represents an ObjC instance variable.
A helper class of ConstantInitBuilder, used for building constant struct initializers.
bool containsNonAscii() const
void getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT, QualType T, std::string &S, bool Extended) const
getObjCEncodingForMethodParameter - Return the encoded type for a single method parameter or return t...
unsigned kind
All of the diagnostics that can be emitted by the frontend.
Represents Objective-C's @try ... @catch ... @finally statement.
StringLiteral - This represents a string literal expression, e.g.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
CGCXXABI & getCXXABI() const
The top declaration context.
static RValue get(llvm::Value *V)
Visibility getVisibility() const
Determines the visibility of this entity.
LValue EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF, const ObjCInterfaceDecl *OID, llvm::Value *BaseValue, const ObjCIvarDecl *Ivar, unsigned CVRQualifiers, llvm::Value *Offset)
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
llvm::Value * LoadObjCSelf()
LoadObjCSelf - Load the value of self.
std::string ObjCConstantStringClass
static RValue getAggregate(Address addr, bool isVolatile=false)
instmeth_iterator instmeth_begin() const
LValue - This represents an lvalue references.
ObjCMethodDecl * getGetterMethodDecl() const
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
Kind
The basic Objective-C runtimes that we know about.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value *> args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
CallArgList - Type for representing both the value and type of arguments in a call.
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration...
This class handles loading and caching of source files into memory.
A helper class of ConstantInitBuilder, used for building constant array initializers.
Abstract information about a function or function prototype.
ObjCCompatibleAliasDecl - Represents alias of a class.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PL, ArrayRef< Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
StringRef getName() const
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
CGObjCRuntime * CreateGNUObjCRuntime(CodeGenModule &CGM)
Creates an instance of an Objective-C runtime class.
ObjCCategoryDecl * FindCategoryDeclaration(IdentifierInfo *CategoryId) const
FindCategoryDeclaration - Finds category declaration in the list of categories for this class and ret...
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
const llvm::Triple & getTriple() const