30 #include "llvm/ADT/SmallVector.h" 31 #include "llvm/ADT/StringMap.h" 32 #include "llvm/IR/DataLayout.h" 33 #include "llvm/IR/Intrinsics.h" 34 #include "llvm/IR/LLVMContext.h" 35 #include "llvm/IR/Module.h" 36 #include "llvm/Support/Compiler.h" 37 #include "llvm/Support/ConvertUTF.h" 40 using namespace clang;
41 using namespace CodeGen;
45 std::string SymbolNameForMethod( StringRef ClassName,
46 StringRef CategoryName,
const Selector MethodName,
48 std::string MethodNameColonStripped = MethodName.
getAsString();
49 std::replace(MethodNameColonStripped.begin(), MethodNameColonStripped.end(),
51 return (Twine(isClassMethod ?
"_c_" :
"_i_") + ClassName +
"_" +
52 CategoryName +
"_" + MethodNameColonStripped).str();
58 class LazyRuntimeFunction {
60 llvm::FunctionType *FTy;
61 const char *FunctionName;
69 : CGM(nullptr), FunctionName(nullptr), Function(nullptr) {}
73 template <
typename... Tys>
81 FTy = llvm::FunctionType::get(RetTy, ArgTys,
false);
84 FTy = llvm::FunctionType::get(RetTy, None,
false);
88 llvm::FunctionType *getType() {
return FTy; }
92 operator llvm::FunctionCallee() {
109 llvm::Module &TheModule;
112 llvm::StructType *ObjCSuperTy;
115 llvm::PointerType *PtrToObjCSuperTy;
119 llvm::PointerType *SelectorTy;
122 llvm::IntegerType *Int8Ty;
125 llvm::PointerType *PtrToInt8Ty;
127 llvm::StructType *ProtocolTy;
129 llvm::PointerType *ProtocolPtrTy;
135 llvm::PointerType *IMPTy;
140 llvm::PointerType *IdTy;
143 llvm::PointerType *PtrToIdTy;
148 llvm::IntegerType *IntTy;
152 llvm::PointerType *PtrTy;
156 llvm::IntegerType *LongTy;
158 llvm::IntegerType *SizeTy;
160 llvm::IntegerType *IntPtrTy;
162 llvm::IntegerType *PtrDiffTy;
165 llvm::PointerType *PtrToIntTy;
169 llvm::IntegerType *Int32Ty;
171 llvm::IntegerType *Int64Ty;
173 llvm::StructType *PropertyMetadataTy;
177 unsigned msgSendMDKind;
180 bool usesSEHExceptions;
186 (R.
getVersion() >= VersionTuple(major, minor));
189 std::string ManglePublicSymbol(StringRef Name) {
190 return (StringRef(CGM.
getTriple().isOSBinFormatCOFF() ?
"$_" :
"._") + Name).str();
193 std::string SymbolForProtocol(Twine Name) {
194 return (ManglePublicSymbol(
"OBJC_PROTOCOL_") + Name).str();
197 std::string SymbolForProtocolRef(StringRef Name) {
198 return (ManglePublicSymbol(
"OBJC_REF_PROTOCOL_") + Name).str();
205 llvm::Constant *MakeConstantString(StringRef Str,
const char *Name =
"") {
207 return llvm::ConstantExpr::getGetElementPtr(Array.
getElementType(),
215 llvm::Constant *ExportUniqueString(
const std::string &Str,
216 const std::string &prefix,
217 bool Private=
false) {
218 std::string name = prefix + Str;
219 auto *ConstStr = TheModule.getGlobalVariable(name);
221 llvm::Constant *value = llvm::ConstantDataArray::getString(VMContext,Str);
222 auto *GV =
new llvm::GlobalVariable(TheModule, value->getType(),
true,
223 llvm::GlobalValue::LinkOnceODRLinkage, value,
name);
224 GV->setComdat(TheModule.getOrInsertComdat(name));
229 return llvm::ConstantExpr::getGetElementPtr(ConstStr->getValueType(),
235 const Decl *Container) {
238 std::string NameAndAttributes;
239 std::string TypeStr =
241 NameAndAttributes +=
'\0';
242 NameAndAttributes += TypeStr.length() + 3;
243 NameAndAttributes += TypeStr;
244 NameAndAttributes +=
'\0';
246 return MakeConstantString(NameAndAttributes);
255 int attrs =
property->getPropertyAttributes();
264 Fields.addInt(Int8Ty, attrs & 0xff);
270 attrs |= isSynthesized ? (1<<0) : 0;
274 Fields.addInt(Int8Ty, attrs & 0xff);
276 Fields.addInt(Int8Ty, 0);
277 Fields.addInt(Int8Ty, 0);
280 virtual llvm::Constant *GenerateCategoryProtocolList(
const 285 Fields.addInt(IntTy, count);
288 llvm::DataLayout td(&TheModule);
289 Fields.addInt(IntTy, td.getTypeSizeInBits(PropertyMetadataTy) /
300 bool isSynthesized=
true,
bool 302 auto Fields = PropertiesArray.
beginStruct(PropertyMetadataTy);
304 Fields.add(MakePropertyEncodingString(property, OCD));
305 PushPropertyAttributes(Fields, property, isSynthesized,
isDynamic);
309 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
310 Fields.add(MakeConstantString(accessor->getSelector().getAsString()));
311 Fields.add(TypeEncoding);
326 if (V->getType() == Ty)
return V;
330 if (V.
getType() == Ty)
return V;
335 llvm::Constant *Zeros[2];
337 llvm::Constant *NULLPtr;
339 llvm::LLVMContext &VMContext;
347 llvm::GlobalAlias *ClassPtrAlias;
352 llvm::GlobalAlias *MetaClassPtrAlias;
354 std::vector<llvm::Constant*> Classes;
356 std::vector<llvm::Constant*> Categories;
359 std::vector<llvm::Constant*> ConstantStrings;
363 llvm::StringMap<llvm::Constant*> ObjCStrings;
365 llvm::StringMap<llvm::Constant*> ExistingProtocols;
371 typedef std::pair<std::string, llvm::GlobalAlias*> TypedSelector;
375 typedef llvm::DenseMap<Selector, SmallVector<TypedSelector, 2> >
383 Selector RetainSel, ReleaseSel, AutoreleaseSel;
387 LazyRuntimeFunction IvarAssignFn, StrongCastAssignFn, MemMoveFn, WeakReadFn,
388 WeakAssignFn, GlobalAssignFn;
390 typedef std::pair<std::string, std::string> ClassAliasPair;
392 std::vector<ClassAliasPair> ClassAliases;
396 LazyRuntimeFunction ExceptionThrowFn;
399 LazyRuntimeFunction ExceptionReThrowFn;
402 LazyRuntimeFunction EnterCatchFn;
405 LazyRuntimeFunction ExitCatchFn;
407 LazyRuntimeFunction SyncEnterFn;
409 LazyRuntimeFunction SyncExitFn;
414 LazyRuntimeFunction EnumerationMutationFn;
417 LazyRuntimeFunction GetPropertyFn;
420 LazyRuntimeFunction SetPropertyFn;
422 LazyRuntimeFunction GetStructPropertyFn;
424 LazyRuntimeFunction SetStructPropertyFn;
436 const int ProtocolVersion;
439 const int ClassABIVersion;
455 llvm::Constant *GenerateMethodList(StringRef ClassName,
456 StringRef CategoryName,
458 bool isClassMethodList);
463 virtual llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName);
467 llvm::Constant *GeneratePropertyList(
const Decl *Container,
469 bool isClassProperty=
false,
470 bool protocolOptionalProperties=
false);
480 void GenerateProtocolHolderCategory();
483 llvm::Constant *GenerateClassStructure(
484 llvm::Constant *MetaClass,
485 llvm::Constant *SuperClass,
488 llvm::Constant *Version,
489 llvm::Constant *InstanceSize,
490 llvm::Constant *IVars,
491 llvm::Constant *Methods,
492 llvm::Constant *Protocols,
493 llvm::Constant *IvarOffsets,
494 llvm::Constant *Properties,
495 llvm::Constant *StrongIvarBitmap,
496 llvm::Constant *WeakIvarBitmap,
501 virtual llvm::Constant *GenerateProtocolMethodList(
505 void EmitProtocolMethodList(T &&Methods, llvm::Constant *&Required,
509 for (
const auto *I : Methods)
511 OptionalMethods.push_back(I);
513 RequiredMethods.push_back(I);
514 Required = GenerateProtocolMethodList(RequiredMethods);
515 Optional = GenerateProtocolMethodList(OptionalMethods);
521 const std::string &TypeEncoding);
537 void EmitClassRef(
const std::string &className);
541 const std::string &Name,
bool isWeak);
550 MessageSendInfo &MSI) = 0;
558 MessageSendInfo &MSI) = 0;
575 unsigned protocolClassVersion,
unsigned classABI=1);
598 virtual llvm::Constant *GetConstantSelector(
Selector Sel,
599 const std::string &TypeEncoding) {
600 llvm_unreachable(
"Runtime unable to generate constant selector");
606 llvm::Constant *GetEHType(
QualType T)
override;
610 void GenerateDirectMethodPrologue(
CodeGenFunction &CGF, llvm::Function *Fn,
619 llvm::Function *ModuleInitFunction()
override;
620 llvm::FunctionCallee GetPropertyGetFunction()
override;
621 llvm::FunctionCallee GetPropertySetFunction()
override;
622 llvm::FunctionCallee GetOptimizedPropertySetFunction(
bool atomic,
624 llvm::FunctionCallee GetSetStructFunction()
override;
625 llvm::FunctionCallee GetGetStructFunction()
override;
626 llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override;
627 llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override;
628 llvm::FunctionCallee EnumerationMutationFunction()
override;
636 bool ClearInsertionPoint=
true)
override;
643 bool threadlocal=
false)
override;
653 unsigned CVRQualifiers)
override;
680 class CGObjCGCC :
public CGObjCGNU {
683 LazyRuntimeFunction MsgLookupFn;
687 LazyRuntimeFunction MsgLookupSuperFn;
692 MessageSendInfo &MSI)
override {
695 EnforceType(Builder, Receiver, IdTy),
696 EnforceType(Builder, cmd, SelectorTy) };
698 imp->setMetadata(msgSendMDKind, node);
705 llvm::Value *lookupArgs[] = {EnforceType(Builder, ObjCSuper,
706 PtrToObjCSuperTy).getPointer(), cmd};
713 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
715 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
716 PtrToObjCSuperTy, SelectorTy);
721 class CGObjCGNUstep :
public CGObjCGNU {
724 LazyRuntimeFunction SlotLookupFn;
729 LazyRuntimeFunction SlotLookupSuperFn;
731 LazyRuntimeFunction SetPropertyAtomic;
733 LazyRuntimeFunction SetPropertyAtomicCopy;
735 LazyRuntimeFunction SetPropertyNonAtomic;
737 LazyRuntimeFunction SetPropertyNonAtomicCopy;
740 LazyRuntimeFunction CxxAtomicObjectGetFn;
743 LazyRuntimeFunction CxxAtomicObjectSetFn;
749 llvm::Constant *GetEHType(
QualType T)
override;
754 MessageSendInfo &MSI)
override {
756 llvm::FunctionCallee LookupFn = SlotLookupFn;
768 self = llvm::ConstantPointerNull::get(IdTy);
772 if (
auto *LookupFn2 = dyn_cast<llvm::Function>(LookupFn.getCallee()))
773 LookupFn2->addParamAttr(0, llvm::Attribute::NoCapture);
776 EnforceType(Builder, ReceiverPtr.
getPointer(), PtrToIdTy),
777 EnforceType(Builder, cmd, SelectorTy),
778 EnforceType(Builder,
self, IdTy) };
780 slot->setOnlyReadsMemory();
781 slot->setMetadata(msgSendMDKind, node);
789 Receiver = Builder.
CreateLoad(ReceiverPtr,
true);
795 MessageSendInfo &MSI)
override {
799 llvm::CallInst *slot =
801 slot->setOnlyReadsMemory();
808 CGObjCGNUstep(
CodeGenModule &Mod) : CGObjCGNUstep(Mod, 9, 3, 1) {}
809 CGObjCGNUstep(
CodeGenModule &Mod,
unsigned ABI,
unsigned ProtocolABI,
811 CGObjCGNU(Mod, ABI, ProtocolABI, ClassABI) {
814 llvm::StructType *SlotStructTy =
815 llvm::StructType::get(PtrTy, PtrTy, PtrTy, IntTy, IMPTy);
816 SlotTy = llvm::PointerType::getUnqual(SlotStructTy);
818 SlotLookupFn.init(&CGM,
"objc_msg_lookup_sender", SlotTy, PtrToIdTy,
821 SlotLookupSuperFn.init(&CGM,
"objc_slot_lookup_super", SlotTy,
822 PtrToObjCSuperTy, SelectorTy);
824 if (usesSEHExceptions) {
825 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
827 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy);
829 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
831 EnterCatchFn.init(&CGM,
"__cxa_begin_catch", PtrTy, PtrTy);
833 ExitCatchFn.init(&CGM,
"__cxa_end_catch", VoidTy);
835 ExceptionReThrowFn.init(&CGM,
"_Unwind_Resume_or_Rethrow", VoidTy,
837 }
else if (R.
getVersion() >= VersionTuple(1, 7)) {
838 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
840 EnterCatchFn.init(&CGM,
"objc_begin_catch", IdTy, PtrTy);
842 ExitCatchFn.init(&CGM,
"objc_end_catch", VoidTy);
844 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy, PtrTy);
846 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
847 SetPropertyAtomic.init(&CGM,
"objc_setProperty_atomic", VoidTy, IdTy,
848 SelectorTy, IdTy, PtrDiffTy);
849 SetPropertyAtomicCopy.init(&CGM,
"objc_setProperty_atomic_copy", VoidTy,
850 IdTy, SelectorTy, IdTy, PtrDiffTy);
851 SetPropertyNonAtomic.init(&CGM,
"objc_setProperty_nonatomic", VoidTy,
852 IdTy, SelectorTy, IdTy, PtrDiffTy);
853 SetPropertyNonAtomicCopy.init(&CGM,
"objc_setProperty_nonatomic_copy",
854 VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy);
857 CxxAtomicObjectSetFn.init(&CGM,
"objc_setCppObjectAtomic", VoidTy, PtrTy,
861 CxxAtomicObjectGetFn.init(&CGM,
"objc_getCppObjectAtomic", VoidTy, PtrTy,
865 llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override {
870 return CxxAtomicObjectGetFn;
873 llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override {
878 return CxxAtomicObjectSetFn;
881 llvm::FunctionCallee GetOptimizedPropertySetFunction(
bool atomic,
882 bool copy)
override {
893 if (copy)
return SetPropertyAtomicCopy;
894 return SetPropertyAtomic;
897 return copy ? SetPropertyNonAtomicCopy : SetPropertyNonAtomic;
904 class CGObjCGNUstep2 :
public CGObjCGNUstep {
909 ClassReferenceSection,
912 ProtocolReferenceSection,
914 ConstantStringSection
916 static const char *
const SectionsBaseNames[8];
917 static const char *
const PECOFFSectionsBaseNames[8];
918 template<SectionKind K>
919 std::string sectionName() {
920 if (CGM.
getTriple().isOSBinFormatCOFF()) {
921 std::string
name(PECOFFSectionsBaseNames[K]);
925 return SectionsBaseNames[K];
930 LazyRuntimeFunction MsgLookupSuperFn;
934 bool EmittedProtocol =
false;
939 bool EmittedProtocolRef =
false;
943 bool EmittedClass =
false;
947 typedef std::pair<std::string, std::pair<llvm::Constant*, int>> EarlyInitPair;
948 std::vector<EarlyInitPair> EarlyInitList;
950 std::string SymbolForClassRef(StringRef Name,
bool isWeak) {
952 return (ManglePublicSymbol(
"OBJC_WEAK_REF_CLASS_") + Name).str();
954 return (ManglePublicSymbol(
"OBJC_REF_CLASS_") + Name).str();
957 std::string SymbolForClass(StringRef Name) {
958 return (ManglePublicSymbol(
"OBJC_CLASS_") + Name).str();
960 void CallRuntimeFunction(
CGBuilderTy &B, StringRef FunctionName,
963 for (
auto *Arg : Args)
964 Types.push_back(Arg->getType());
965 llvm::FunctionType *FT = llvm::FunctionType::get(B.getVoidTy(), Types,
968 B.CreateCall(Fn, Args);
977 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
978 if (old != ObjCStrings.end())
986 (LiteralLength < 9) && !isNonASCII) {
992 for (
unsigned i=0 ; i<LiteralLength ; i++)
993 str |= ((uint64_t)SL->
getCodeUnit(i)) << ((64 - 4 - 3) - (i*7));
995 str |= LiteralLength << 3;
998 auto *ObjCStr = llvm::ConstantExpr::getIntToPtr(
999 llvm::ConstantInt::get(Int64Ty, str), IdTy);
1000 ObjCStrings[Str] = ObjCStr;
1006 if (StringClass.empty()) StringClass =
"NSConstantString";
1008 std::string Sym = SymbolForClass(StringClass);
1010 llvm::Constant *
isa = TheModule.getNamedGlobal(Sym);
1013 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
1015 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1016 cast<llvm::GlobalValue>(
isa)->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
1018 }
else if (isa->getType() != PtrToIdTy)
1019 isa = llvm::ConstantExpr::getBitCast(isa, PtrToIdTy);
1032 auto Fields = Builder.beginStruct();
1033 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
1036 Fields.addNullPointer(PtrTy);
1043 unsigned NumU8CodeUnits = Str.size();
1048 const llvm::UTF8 *FromPtr = (
const llvm::UTF8 *)Str.data();
1049 llvm::UTF16 *ToPtr = &ToBuf[0];
1050 (void)llvm::ConvertUTF8toUTF16(&FromPtr, FromPtr + NumU8CodeUnits,
1051 &ToPtr, ToPtr + NumU8CodeUnits, llvm::strictConversion);
1052 uint32_t StringLength = ToPtr - &ToBuf[0];
1056 Fields.addInt(Int32Ty, 2);
1058 Fields.addInt(Int32Ty, StringLength);
1060 Fields.addInt(Int32Ty, StringLength * 2);
1062 Fields.addInt(Int32Ty, 0);
1064 auto Arr = llvm::makeArrayRef(&ToBuf[0], ToPtr+1);
1065 auto *
C = llvm::ConstantDataArray::get(VMContext, Arr);
1066 auto *Buffer =
new llvm::GlobalVariable(TheModule,
C->getType(),
1067 true, llvm::GlobalValue::PrivateLinkage,
C,
".str");
1068 Buffer->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1072 Fields.addInt(Int32Ty, 0);
1074 Fields.addInt(Int32Ty, Str.size());
1076 Fields.addInt(Int32Ty, Str.size());
1078 Fields.addInt(Int32Ty, 0);
1080 Fields.add(MakeConstantString(Str));
1082 std::string StringName;
1085 StringName =
".objc_str_";
1086 for (
int i=0,e=Str.size() ; i<e ; ++i) {
1087 unsigned char c = Str[i];
1100 isNamed ? StringRef(StringName) :
".objc_string",
1101 Align,
false, isNamed ? llvm::GlobalValue::LinkOnceODRLinkage
1102 : llvm::GlobalValue::PrivateLinkage);
1103 ObjCStrGV->setSection(sectionName<ConstantStringSection>());
1105 ObjCStrGV->setComdat(TheModule.getOrInsertComdat(StringName));
1108 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1109 std::pair<llvm::Constant*, int>
v{ObjCStrGV, 0};
1110 EarlyInitList.emplace_back(Sym,
v);
1112 llvm::Constant *ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStrGV, IdTy);
1113 ObjCStrings[Str] = ObjCStr;
1114 ConstantStrings.push_back(ObjCStr);
1121 bool isSynthesized=
true,
bool 1131 auto Fields = PropertiesArray.
beginStruct(PropertyMetadataTy);
1134 std::string TypeStr =
1136 Fields.add(MakeConstantString(TypeStr));
1137 std::string typeStr;
1139 Fields.add(MakeConstantString(typeStr));
1143 Fields.add(GetConstantSelector(accessor->getSelector(), TypeStr));
1145 Fields.add(NULLPtr);
1160 llvm::StructType *ObjCMethodDescTy =
1162 { PtrToInt8Ty, PtrToInt8Ty });
1171 auto MethodList = Builder.beginStruct();
1173 MethodList.addInt(IntTy, Methods.size());
1175 llvm::DataLayout td(&TheModule);
1176 MethodList.addInt(IntTy, td.getTypeSizeInBits(ObjCMethodDescTy) /
1179 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
1180 for (
auto *M : Methods) {
1181 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
1182 Method.add(CGObjCGNU::GetConstantSelector(M));
1183 Method.add(GetTypeString(Context.getObjCEncodingForMethodDecl(M,
true)));
1184 Method.finishAndAddTo(MethodArray);
1186 MethodArray.finishAndAddTo(MethodList);
1187 return MethodList.finishAndCreateGlobal(
".objc_protocol_method_list",
1194 Protocols.push_back(
1195 llvm::ConstantExpr::getBitCast(GenerateProtocolRef(PI),
1197 return GenerateProtocolList(Protocols);
1201 llvm::Value *cmd, MessageSendInfo &MSI)
override {
1204 llvm::Value *lookupArgs[] = {CGObjCGNU::EnforceType(Builder, ObjCSuper,
1205 PtrToObjCSuperTy).getPointer(), cmd};
1209 llvm::GlobalVariable *GetClassVar(StringRef Name,
bool isWeak=
false) {
1210 std::string SymbolName = SymbolForClassRef(Name, isWeak);
1211 auto *ClassSymbol = TheModule.getNamedGlobal(SymbolName);
1214 ClassSymbol =
new llvm::GlobalVariable(TheModule,
1216 nullptr, SymbolName);
1222 ClassSymbol->setInitializer(
new llvm::GlobalVariable(TheModule,
1223 Int8Ty,
false, llvm::GlobalValue::ExternalWeakLinkage,
1224 nullptr, SymbolForClass(Name)));
1226 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1232 for (
const auto &Result : DC->
lookup(&II))
1233 if ((OID = dyn_cast<ObjCInterfaceDecl>(Result)))
1239 assert(OID &&
"Failed to find ObjCInterfaceDecl");
1241 if (OIDDef !=
nullptr)
1244 auto Storage = llvm::GlobalValue::DefaultStorageClass;
1245 if (OID->
hasAttr<DLLImportAttr>())
1246 Storage = llvm::GlobalValue::DLLImportStorageClass;
1247 else if (OID->
hasAttr<DLLExportAttr>())
1248 Storage = llvm::GlobalValue::DLLExportStorageClass;
1250 cast<llvm::GlobalValue>(ClassSymbol)->setDLLStorageClass(Storage);
1253 assert(ClassSymbol->getName() == SymbolName);
1257 const std::string &Name,
1258 bool isWeak)
override {
1270 switch (Ownership) {
1292 llvm_unreachable(
"Method should not be called!");
1295 llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName)
override {
1296 std::string Name = SymbolForProtocol(ProtocolName);
1297 auto *GV = TheModule.getGlobalVariable(Name);
1300 GV =
new llvm::GlobalVariable(TheModule, ProtocolTy,
false,
1304 return llvm::ConstantExpr::getBitCast(GV, ProtocolPtrTy);
1308 llvm::StringMap<llvm::Constant*> ExistingProtocolRefs;
1313 auto *&Ref = ExistingProtocolRefs[Name];
1315 auto *&
Protocol = ExistingProtocols[Name];
1317 Protocol = GenerateProtocolRef(PD);
1318 std::string RefName = SymbolForProtocolRef(Name);
1319 assert(!TheModule.getGlobalVariable(RefName));
1321 auto GV =
new llvm::GlobalVariable(TheModule, ProtocolPtrTy,
1322 false, llvm::GlobalValue::LinkOnceODRLinkage,
1323 llvm::ConstantExpr::getBitCast(Protocol, ProtocolPtrTy), RefName);
1324 GV->setComdat(TheModule.getOrInsertComdat(RefName));
1325 GV->setSection(sectionName<ProtocolReferenceSection>());
1329 EmittedProtocolRef =
true;
1334 llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(ProtocolPtrTy,
1336 llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
1339 auto ProtocolBuilder = builder.beginStruct();
1340 ProtocolBuilder.addNullPointer(PtrTy);
1341 ProtocolBuilder.addInt(SizeTy, Protocols.size());
1342 ProtocolBuilder.add(ProtocolArray);
1343 return ProtocolBuilder.finishAndCreateGlobal(
".objc_protocol_list",
1352 auto *&
Protocol = ExistingProtocols[ProtocolName];
1356 EmittedProtocol =
true;
1358 auto SymName = SymbolForProtocol(ProtocolName);
1359 auto *OldGV = TheModule.getGlobalVariable(SymName);
1369 Protocol =
new llvm::GlobalVariable(TheModule, ProtocolTy,
1377 Protocols.push_back(
1378 llvm::ConstantExpr::getBitCast(GenerateProtocolRef(PI),
1380 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
1383 llvm::Constant *InstanceMethodList, *OptionalInstanceMethodList;
1384 llvm::Constant *ClassMethodList, *OptionalClassMethodList;
1386 OptionalInstanceMethodList);
1387 EmitProtocolMethodList(PD->
class_methods(), ClassMethodList,
1388 OptionalClassMethodList);
1393 auto ProtocolBuilder = builder.beginStruct();
1394 ProtocolBuilder.add(llvm::ConstantExpr::getIntToPtr(
1395 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
1396 ProtocolBuilder.add(MakeConstantString(ProtocolName));
1397 ProtocolBuilder.add(ProtocolList);
1398 ProtocolBuilder.add(InstanceMethodList);
1399 ProtocolBuilder.add(ClassMethodList);
1400 ProtocolBuilder.add(OptionalInstanceMethodList);
1401 ProtocolBuilder.add(OptionalClassMethodList);
1403 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
false,
false));
1405 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
false,
true));
1407 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
true,
false));
1409 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
true,
true));
1411 auto *GV = ProtocolBuilder.finishAndCreateGlobal(SymName,
1413 GV->setSection(sectionName<ProtocolSection>());
1414 GV->setComdat(TheModule.getOrInsertComdat(SymName));
1416 OldGV->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(GV,
1418 OldGV->removeFromParent();
1419 GV->setName(SymName);
1424 llvm::Constant *EnforceType(llvm::Constant *Val,
llvm::Type *Ty) {
1425 if (Val->getType() == Ty)
1427 return llvm::ConstantExpr::getBitCast(Val, Ty);
1430 const std::string &TypeEncoding)
override {
1431 return GetConstantSelector(Sel, TypeEncoding);
1433 llvm::Constant *GetTypeString(llvm::StringRef TypeEncoding) {
1434 if (TypeEncoding.empty())
1436 std::string MangledTypes = TypeEncoding;
1437 std::replace(MangledTypes.begin(), MangledTypes.end(),
1439 std::string TypesVarName =
".objc_sel_types_" + MangledTypes;
1440 auto *TypesGlobal = TheModule.getGlobalVariable(TypesVarName);
1442 llvm::Constant *Init = llvm::ConstantDataArray::getString(VMContext,
1444 auto *GV =
new llvm::GlobalVariable(TheModule, Init->getType(),
1445 true, llvm::GlobalValue::LinkOnceODRLinkage, Init, TypesVarName);
1446 GV->setComdat(TheModule.getOrInsertComdat(TypesVarName));
1450 return llvm::ConstantExpr::getGetElementPtr(TypesGlobal->getValueType(),
1451 TypesGlobal, Zeros);
1453 llvm::Constant *GetConstantSelector(
Selector Sel,
1454 const std::string &TypeEncoding)
override {
1459 std::string MangledTypes = TypeEncoding;
1460 std::replace(MangledTypes.begin(), MangledTypes.end(),
1462 auto SelVarName = (StringRef(
".objc_selector_") + Sel.
getAsString() +
"_" +
1463 MangledTypes).str();
1464 if (
auto *GV = TheModule.getNamedGlobal(SelVarName))
1465 return EnforceType(GV, SelectorTy);
1467 auto SelBuilder = builder.beginStruct();
1468 SelBuilder.add(ExportUniqueString(Sel.
getAsString(),
".objc_sel_name_",
1470 SelBuilder.add(GetTypeString(TypeEncoding));
1471 auto *GV = SelBuilder.finishAndCreateGlobal(SelVarName,
1473 GV->setComdat(TheModule.getOrInsertComdat(SelVarName));
1475 GV->setSection(sectionName<SelectorSection>());
1476 auto *SelVal = EnforceType(GV, SelectorTy);
1479 llvm::StructType *emptyStruct =
nullptr;
1488 std::pair<llvm::Constant*,llvm::Constant*>
1489 GetSectionBounds(StringRef Section) {
1490 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1491 if (emptyStruct ==
nullptr) {
1493 emptyStruct->setBody({},
true);
1495 auto ZeroInit = llvm::Constant::getNullValue(emptyStruct);
1496 auto Sym = [&](StringRef Prefix, StringRef SecSuffix) {
1497 auto *Sym =
new llvm::GlobalVariable(TheModule, emptyStruct,
1499 llvm::GlobalValue::LinkOnceODRLinkage, ZeroInit, Prefix +
1502 Sym->setSection((Section + SecSuffix).str());
1503 Sym->setComdat(TheModule.getOrInsertComdat((Prefix +
1508 return { Sym(
"__start_",
"$a"), Sym(
"__stop",
"$z") };
1510 auto *Start =
new llvm::GlobalVariable(TheModule, PtrTy,
1515 auto *Stop =
new llvm::GlobalVariable(TheModule, PtrTy,
1520 return { Start, Stop };
1525 llvm::Function *ModuleInitFunction()
override {
1527 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
1528 llvm::GlobalValue::LinkOnceODRLinkage,
".objcv2_load_function",
1531 LoadFunction->setComdat(TheModule.getOrInsertComdat(
".objcv2_load_function"));
1533 llvm::BasicBlock *EntryBB =
1536 B.SetInsertPoint(EntryBB);
1538 auto InitStructBuilder = builder.beginStruct();
1539 InitStructBuilder.addInt(Int64Ty, 0);
1540 auto §ionVec = CGM.
getTriple().isOSBinFormatCOFF() ? PECOFFSectionsBaseNames : SectionsBaseNames;
1541 for (
auto *s : sectionVec) {
1542 auto bounds = GetSectionBounds(s);
1543 InitStructBuilder.add(bounds.first);
1544 InitStructBuilder.add(bounds.second);
1546 auto *InitStruct = InitStructBuilder.finishAndCreateGlobal(
".objc_init",
1549 InitStruct->setComdat(TheModule.getOrInsertComdat(
".objc_init"));
1551 CallRuntimeFunction(B,
"__objc_load", {InitStruct});;
1558 auto *InitVar =
new llvm::GlobalVariable(TheModule, LoadFunction->getType(),
1559 true, llvm::GlobalValue::LinkOnceAnyLinkage,
1560 LoadFunction,
".objc_ctor");
1563 assert(InitVar->getName() ==
".objc_ctor");
1569 if (CGM.
getTriple().isOSBinFormatCOFF())
1570 InitVar->setSection(
".CRT$XCLz");
1574 InitVar->setSection(
".init_array");
1576 InitVar->setSection(
".ctors");
1579 InitVar->setComdat(TheModule.getOrInsertComdat(
".objc_ctor"));
1581 for (
auto *C : Categories) {
1582 auto *Cat = cast<llvm::GlobalVariable>(C->stripPointerCasts());
1583 Cat->setSection(sectionName<CategorySection>());
1587 StringRef Section) {
1588 auto nullBuilder = builder.beginStruct();
1589 for (
auto *F : Init)
1591 auto GV = nullBuilder.finishAndCreateGlobal(Name, CGM.
getPointerAlign(),
1592 false, llvm::GlobalValue::LinkOnceODRLinkage);
1593 GV->setSection(Section);
1594 GV->setComdat(TheModule.getOrInsertComdat(Name));
1599 for (
auto clsAlias : ClassAliases)
1600 createNullGlobal(std::string(
".objc_class_alias") +
1601 clsAlias.second, { MakeConstantString(clsAlias.second),
1602 GetClassVar(clsAlias.first) }, sectionName<ClassAliasSection>());
1607 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
1608 createNullGlobal(
".objc_null_selector", {NULLPtr, NULLPtr},
1609 sectionName<SelectorSection>());
1610 if (Categories.empty())
1611 createNullGlobal(
".objc_null_category", {NULLPtr, NULLPtr,
1612 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr},
1613 sectionName<CategorySection>());
1614 if (!EmittedClass) {
1615 createNullGlobal(
".objc_null_cls_init_ref", NULLPtr,
1616 sectionName<ClassSection>());
1617 createNullGlobal(
".objc_null_class_ref", { NULLPtr, NULLPtr },
1618 sectionName<ClassReferenceSection>());
1620 if (!EmittedProtocol)
1621 createNullGlobal(
".objc_null_protocol", {NULLPtr, NULLPtr, NULLPtr,
1622 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr,
1623 NULLPtr}, sectionName<ProtocolSection>());
1624 if (!EmittedProtocolRef)
1625 createNullGlobal(
".objc_null_protocol_ref", {NULLPtr},
1626 sectionName<ProtocolReferenceSection>());
1627 if (ClassAliases.empty())
1628 createNullGlobal(
".objc_null_class_alias", { NULLPtr, NULLPtr },
1629 sectionName<ClassAliasSection>());
1630 if (ConstantStrings.empty()) {
1631 auto i32Zero = llvm::ConstantInt::get(Int32Ty, 0);
1632 createNullGlobal(
".objc_null_constant_string", { NULLPtr, i32Zero,
1633 i32Zero, i32Zero, i32Zero, NULLPtr },
1634 sectionName<ConstantStringSection>());
1637 ConstantStrings.clear();
1641 if (EarlyInitList.size() > 0) {
1647 for (
const auto &lateInit : EarlyInitList) {
1648 auto *global = TheModule.getGlobalVariable(lateInit.first);
1650 b.CreateAlignedStore(global,
1657 auto *InitVar =
new llvm::GlobalVariable(CGM.
getModule(), Init->getType(),
1659 Init,
".objc_early_init_ptr");
1660 InitVar->setSection(
".CRT$XCLb");
1669 std::string TypeEncoding;
1672 std::replace(TypeEncoding.begin(), TypeEncoding.end(),
1674 const std::string Name =
"__objc_ivar_offset_" + ID->
getNameAsString()
1682 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
1683 if (!IvarOffsetPointer)
1684 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule, IntTy,
false,
1688 if (Offset->getType() != PtrDiffTy)
1689 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
1694 bool IsCOFF = CGM.
getTriple().isOSBinFormatCOFF();
1700 auto *classNameConstant = MakeConstantString(className);
1703 auto metaclassFields = builder.beginStruct();
1705 metaclassFields.addNullPointer(PtrTy);
1707 metaclassFields.addNullPointer(PtrTy);
1709 metaclassFields.add(classNameConstant);
1711 metaclassFields.addInt(LongTy, 0);
1714 metaclassFields.addInt(LongTy, 1);
1718 metaclassFields.addInt(LongTy, 0);
1720 metaclassFields.addNullPointer(PtrTy);
1725 metaclassFields.addNullPointer(PtrTy);
1730 metaclassFields.addBitCast(
1731 GenerateMethodList(className,
"", ClassMethods,
true),
1735 metaclassFields.addNullPointer(PtrTy);
1737 metaclassFields.addNullPointer(PtrTy);
1739 metaclassFields.addNullPointer(PtrTy);
1741 metaclassFields.addNullPointer(PtrTy);
1743 metaclassFields.addNullPointer(PtrTy);
1745 metaclassFields.addNullPointer(PtrTy);
1747 metaclassFields.addNullPointer(PtrTy);
1749 metaclassFields.addInt(LongTy, 0);
1751 metaclassFields.add(GeneratePropertyList(OID, classDecl,
true));
1753 auto *metaclass = metaclassFields.finishAndCreateGlobal(
1754 ManglePublicSymbol(
"OBJC_METACLASS_") + className,
1757 auto classFields = builder.beginStruct();
1759 classFields.add(metaclass);
1764 llvm::Constant *SuperClass =
nullptr;
1765 if (SuperClassDecl) {
1766 auto SuperClassName = SymbolForClass(SuperClassDecl->
getNameAsString());
1767 SuperClass = TheModule.getNamedGlobal(SuperClassName);
1770 SuperClass =
new llvm::GlobalVariable(TheModule, PtrTy,
false,
1773 auto Storage = llvm::GlobalValue::DefaultStorageClass;
1774 if (SuperClassDecl->
hasAttr<DLLImportAttr>())
1775 Storage = llvm::GlobalValue::DLLImportStorageClass;
1776 else if (SuperClassDecl->
hasAttr<DLLExportAttr>())
1777 Storage = llvm::GlobalValue::DLLExportStorageClass;
1779 cast<llvm::GlobalValue>(SuperClass)->setDLLStorageClass(Storage);
1783 classFields.add(llvm::ConstantExpr::getBitCast(SuperClass, PtrTy));
1785 classFields.addNullPointer(PtrTy);
1787 classFields.addNullPointer(PtrTy);
1789 classFields.add(classNameConstant);
1791 classFields.addInt(LongTy, 0);
1794 classFields.addInt(LongTy, 0);
1796 int superInstanceSize = !SuperClassDecl ? 0 :
1800 classFields.addInt(LongTy,
1802 superInstanceSize));
1805 classFields.addNullPointer(PtrTy);
1810 llvm::DataLayout td(&TheModule);
1813 auto ivarListBuilder = b.beginStruct();
1815 ivarListBuilder.addInt(IntTy, ivar_count);
1817 llvm::StructType *ObjCIvarTy = llvm::StructType::get(
1823 ivarListBuilder.addInt(SizeTy, td.getTypeSizeInBits(ObjCIvarTy) /
1826 auto ivarArrayBuilder = ivarListBuilder.beginArray();
1829 auto ivarTy = IVD->getType();
1830 auto ivarBuilder = ivarArrayBuilder.beginStruct();
1832 ivarBuilder.add(MakeConstantString(IVD->getNameAsString()));
1834 std::string TypeStr;
1837 ivarBuilder.add(MakeConstantString(TypeStr));
1839 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
1840 uint64_t Offset = BaseOffset - superInstanceSize;
1841 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
1842 std::string OffsetName = GetIVarOffsetVariableName(classDecl, IVD);
1843 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
1845 OffsetVar->setInitializer(OffsetValue);
1847 OffsetVar =
new llvm::GlobalVariable(TheModule, IntTy,
1849 OffsetValue, OffsetName);
1850 auto ivarVisibility =
1856 OffsetVar->setVisibility(ivarVisibility);
1857 ivarBuilder.add(OffsetVar);
1859 ivarBuilder.addInt(Int32Ty,
1870 ivarBuilder.addInt(Int32Ty,
1871 (align << 3) | (1<<2) |
1872 FlagsForOwnership(ivarTy.getQualifiers().getObjCLifetime()));
1873 ivarBuilder.finishAndAddTo(ivarArrayBuilder);
1875 ivarArrayBuilder.finishAndAddTo(ivarListBuilder);
1876 auto ivarList = ivarListBuilder.finishAndCreateGlobal(
".objc_ivar_list",
1878 llvm::GlobalValue::PrivateLinkage);
1879 classFields.add(ivarList);
1883 InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
1886 if (propImpl->getPropertyImplementation() ==
1889 if (OMD && OMD->hasBody())
1890 InstanceMethods.push_back(OMD);
1892 addIfExists(propImpl->getGetterMethodDecl());
1893 addIfExists(propImpl->getSetterMethodDecl());
1896 if (InstanceMethods.size() == 0)
1897 classFields.addNullPointer(PtrTy);
1899 classFields.addBitCast(
1900 GenerateMethodList(className,
"", InstanceMethods,
false),
1903 classFields.addNullPointer(PtrTy);
1905 classFields.addNullPointer(PtrTy);
1907 classFields.addNullPointer(PtrTy);
1909 classFields.addNullPointer(PtrTy);
1911 classFields.addNullPointer(PtrTy);
1914 for (
const auto *I : classDecl->
protocols())
1915 Protocols.push_back(
1916 llvm::ConstantExpr::getBitCast(GenerateProtocolRef(I),
1918 if (Protocols.empty())
1919 classFields.addNullPointer(PtrTy);
1921 classFields.add(GenerateProtocolList(Protocols));
1923 classFields.addNullPointer(PtrTy);
1925 classFields.addInt(LongTy, 0);
1927 classFields.add(GeneratePropertyList(OID, classDecl));
1930 classFields.finishAndCreateGlobal(SymbolForClass(className),
1933 auto *classRefSymbol = GetClassVar(className);
1934 classRefSymbol->setSection(sectionName<ClassReferenceSection>());
1935 classRefSymbol->setInitializer(llvm::ConstantExpr::getBitCast(classStruct, IdTy));
1940 cast<llvm::GlobalValue>(classStruct)->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1941 cast<llvm::GlobalValue>(classRefSymbol)->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1945 std::pair<llvm::Constant*, int>
v{classStruct, 1};
1946 EarlyInitList.emplace_back(SuperClass->getName(), std::move(
v));
1954 if (ClassPtrAlias) {
1955 ClassPtrAlias->replaceAllUsesWith(
1956 llvm::ConstantExpr::getBitCast(classStruct, IdTy));
1957 ClassPtrAlias->eraseFromParent();
1958 ClassPtrAlias =
nullptr;
1960 if (
auto Placeholder =
1961 TheModule.getNamedGlobal(SymbolForClass(className)))
1962 if (Placeholder != classStruct) {
1963 Placeholder->replaceAllUsesWith(
1964 llvm::ConstantExpr::getBitCast(classStruct, Placeholder->getType()));
1965 Placeholder->eraseFromParent();
1966 classStruct->setName(SymbolForClass(className));
1968 if (MetaClassPtrAlias) {
1969 MetaClassPtrAlias->replaceAllUsesWith(
1970 llvm::ConstantExpr::getBitCast(metaclass, IdTy));
1971 MetaClassPtrAlias->eraseFromParent();
1972 MetaClassPtrAlias =
nullptr;
1974 assert(classStruct->getName() == SymbolForClass(className));
1976 auto classInitRef =
new llvm::GlobalVariable(TheModule,
1978 classStruct, ManglePublicSymbol(
"OBJC_INIT_CLASS_") + className);
1979 classInitRef->setSection(sectionName<ClassSection>());
1982 EmittedClass =
true;
1985 CGObjCGNUstep2(
CodeGenModule &Mod) : CGObjCGNUstep(Mod, 10, 4, 2) {
1986 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
1987 PtrToObjCSuperTy, SelectorTy);
1996 PropertyMetadataTy =
1998 { PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty });
2003 const char *
const CGObjCGNUstep2::SectionsBaseNames[8] =
2007 "__objc_class_refs",
2010 "__objc_protocol_refs",
2011 "__objc_class_aliases",
2012 "__objc_constant_string" 2015 const char *
const CGObjCGNUstep2::PECOFFSectionsBaseNames[8] =
2028 class CGObjCObjFW:
public CGObjCGNU {
2032 LazyRuntimeFunction MsgLookupFn;
2035 LazyRuntimeFunction MsgLookupFnSRet;
2039 LazyRuntimeFunction MsgLookupSuperFn, MsgLookupSuperFnSRet;
2043 MessageSendInfo &MSI)
override {
2046 EnforceType(Builder, Receiver, IdTy),
2047 EnforceType(Builder, cmd, SelectorTy) };
2049 llvm::CallBase *imp;
2055 imp->setMetadata(msgSendMDKind, node);
2060 llvm::Value *cmd, MessageSendInfo &MSI)
override {
2063 EnforceType(Builder, ObjCSuper.
getPointer(), PtrToObjCSuperTy), cmd,
2073 bool isWeak)
override {
2075 return CGObjCGNU::GetClassNamed(CGF, Name, isWeak);
2078 std::string SymbolName =
"_OBJC_CLASS_" + Name;
2079 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(SymbolName);
2081 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
2083 nullptr, SymbolName);
2090 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
2091 MsgLookupFnSRet.init(&CGM,
"objc_msg_lookup_stret", IMPTy, IdTy,
2094 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
2095 PtrToObjCSuperTy, SelectorTy);
2096 MsgLookupSuperFnSRet.init(&CGM,
"objc_msg_lookup_super_stret", IMPTy,
2097 PtrToObjCSuperTy, SelectorTy);
2105 void CGObjCGNU::EmitClassRef(
const std::string &className) {
2106 std::string symbolRef =
"__objc_class_ref_" + className;
2108 if (TheModule.getGlobalVariable(symbolRef))
2110 std::string symbolName =
"__objc_class_name_" + className;
2111 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
2113 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
2115 nullptr, symbolName);
2117 new llvm::GlobalVariable(TheModule, ClassSymbol->getType(),
true,
2118 llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef);
2121 CGObjCGNU::CGObjCGNU(
CodeGenModule &cgm,
unsigned runtimeABIVersion,
2122 unsigned protocolClassVersion,
unsigned classABI)
2124 VMContext(cgm.getLLVMContext()), ClassPtrAlias(nullptr),
2125 MetaClassPtrAlias(nullptr), RuntimeVersion(runtimeABIVersion),
2126 ProtocolVersion(protocolClassVersion), ClassABIVersion(classABI) {
2128 msgSendMDKind = VMContext.getMDKindID(
"GNUObjCMessageSend");
2133 IntTy = cast<llvm::IntegerType>(
2135 LongTy = cast<llvm::IntegerType>(
2137 SizeTy = cast<llvm::IntegerType>(
2139 PtrDiffTy = cast<llvm::IntegerType>(
2143 Int8Ty = llvm::Type::getInt8Ty(VMContext);
2145 PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
2146 ProtocolPtrTy = llvm::PointerType::getUnqual(
2149 Zeros[0] = llvm::ConstantInt::get(LongTy, 0);
2150 Zeros[1] = Zeros[0];
2151 NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty);
2155 SelectorTy = PtrToInt8Ty;
2160 PtrToIntTy = llvm::PointerType::getUnqual(IntTy);
2161 PtrTy = PtrToInt8Ty;
2163 Int32Ty = llvm::Type::getInt32Ty(VMContext);
2164 Int64Ty = llvm::Type::getInt64Ty(VMContext);
2167 CGM.
getDataLayout().getPointerSizeInBits() == 32 ? Int32Ty : Int64Ty;
2178 PtrToIdTy = llvm::PointerType::getUnqual(IdTy);
2179 ProtocolTy = llvm::StructType::get(IdTy,
2201 PropertyMetadataTy = llvm::StructType::get(CGM.
getLLVMContext(), {
2202 PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty,
2203 PtrToInt8Ty, PtrToInt8Ty });
2205 ObjCSuperTy = llvm::StructType::get(IdTy, IdTy);
2206 PtrToObjCSuperTy = llvm::PointerType::getUnqual(ObjCSuperTy);
2208 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
2211 ExceptionThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy);
2212 ExceptionReThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy);
2214 SyncEnterFn.init(&CGM,
"objc_sync_enter", IntTy, IdTy);
2216 SyncExitFn.init(&CGM,
"objc_sync_exit", IntTy, IdTy);
2219 EnumerationMutationFn.init(&CGM,
"objc_enumerationMutation", VoidTy, IdTy);
2222 GetPropertyFn.init(&CGM,
"objc_getProperty", IdTy, IdTy, SelectorTy,
2225 SetPropertyFn.init(&CGM,
"objc_setProperty", VoidTy, IdTy, SelectorTy,
2226 PtrDiffTy, IdTy, BoolTy, BoolTy);
2228 GetStructPropertyFn.init(&CGM,
"objc_getPropertyStruct", VoidTy, PtrTy, PtrTy,
2229 PtrDiffTy, BoolTy, BoolTy);
2231 SetStructPropertyFn.init(&CGM,
"objc_setPropertyStruct", VoidTy, PtrTy, PtrTy,
2232 PtrDiffTy, BoolTy, BoolTy);
2235 llvm::Type *IMPArgs[] = { IdTy, SelectorTy };
2236 IMPTy = llvm::PointerType::getUnqual(llvm::FunctionType::get(IdTy, IMPArgs,
2241 RuntimeVersion = 10;
2256 IvarAssignFn.init(&CGM,
"objc_assign_ivar", IdTy, IdTy, IdTy, PtrDiffTy);
2258 StrongCastAssignFn.init(&CGM,
"objc_assign_strongCast", IdTy, IdTy,
2261 GlobalAssignFn.init(&CGM,
"objc_assign_global", IdTy, IdTy, PtrToIdTy);
2263 WeakAssignFn.init(&CGM,
"objc_assign_weak", IdTy, IdTy, PtrToIdTy);
2265 WeakReadFn.init(&CGM,
"objc_read_weak", IdTy, PtrToIdTy);
2267 MemMoveFn.init(&CGM,
"objc_memmove_collectable", PtrTy, PtrTy, PtrTy,
2273 const std::string &Name,
bool isWeak) {
2274 llvm::Constant *ClassName = MakeConstantString(Name);
2286 llvm::FunctionType::get(IdTy, PtrToInt8Ty,
true),
"objc_lookup_class");
2296 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value))
2302 auto *
Value = GetClassNamed(CGF,
"NSAutoreleasePool",
false);
2303 if (CGM.
getTriple().isOSBinFormatCOFF()) {
2304 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value)) {
2310 for (
const auto &Result : DC->
lookup(&II))
2311 if ((VD = dyn_cast<VarDecl>(Result)))
2321 const std::string &TypeEncoding) {
2323 llvm::GlobalAlias *SelValue =
nullptr;
2326 e = Types.end() ; i!=e ; i++) {
2327 if (i->first == TypeEncoding) {
2328 SelValue = i->second;
2334 SelectorTy->getElementType(), 0, llvm::GlobalValue::PrivateLinkage,
2335 ".objc_selector_" + Sel.
getAsString(), &TheModule);
2336 Types.emplace_back(TypeEncoding, SelValue);
2354 return GetTypedSelector(CGF, Sel, std::string());
2360 return GetTypedSelector(CGF, Method->
getSelector(), SelTypes);
2363 llvm::Constant *CGObjCGNU::GetEHType(
QualType T) {
2370 return MakeConstantString(
"@id");
2378 assert(OPT &&
"Invalid @catch type.");
2380 assert(IDecl &&
"Invalid @catch type.");
2384 llvm::Constant *CGObjCGNUstep::GetEHType(
QualType T) {
2385 if (usesSEHExceptions)
2389 return CGObjCGNU::GetEHType(T);
2397 llvm::Constant *IDEHType =
2398 CGM.
getModule().getGlobalVariable(
"__objc_id_type_info");
2401 new llvm::GlobalVariable(CGM.
getModule(), PtrToInt8Ty,
2404 nullptr,
"__objc_id_type_info");
2405 return llvm::ConstantExpr::getBitCast(IDEHType, PtrToInt8Ty);
2410 assert(PT &&
"Invalid @catch type.");
2412 assert(IT &&
"Invalid @catch type.");
2415 std::string typeinfoName =
"__objc_eh_typeinfo_" + className;
2418 llvm::Constant *typeinfo = TheModule.getGlobalVariable(typeinfoName);
2420 return llvm::ConstantExpr::getBitCast(typeinfo, PtrToInt8Ty);
2427 const char *vtableName =
"_ZTVN7gnustep7libobjc22__objc_class_type_infoE";
2428 auto *Vtable = TheModule.getGlobalVariable(vtableName);
2430 Vtable =
new llvm::GlobalVariable(TheModule, PtrToInt8Ty,
true,
2432 nullptr, vtableName);
2434 llvm::Constant *Two = llvm::ConstantInt::get(IntTy, 2);
2435 auto *BVtable = llvm::ConstantExpr::getBitCast(
2436 llvm::ConstantExpr::getGetElementPtr(Vtable->getValueType(), Vtable, Two),
2439 llvm::Constant *typeName =
2440 ExportUniqueString(className,
"__objc_eh_typename_");
2443 auto fields = builder.beginStruct();
2444 fields.add(BVtable);
2445 fields.add(typeName);
2446 llvm::Constant *TI =
2447 fields.finishAndCreateGlobal(
"__objc_eh_typeinfo_" + className,
2450 llvm::GlobalValue::LinkOnceODRLinkage);
2451 return llvm::ConstantExpr::getBitCast(TI, PtrToInt8Ty);
2457 std::string Str = SL->
getString().str();
2461 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
2462 if (old != ObjCStrings.end())
2467 if (StringClass.empty()) StringClass =
"NSConstantString";
2469 std::string Sym =
"_OBJC_CLASS_";
2472 llvm::Constant *isa = TheModule.getNamedGlobal(Sym);
2475 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
2476 llvm::GlobalValue::ExternalWeakLinkage,
nullptr, Sym);
2477 else if (isa->getType() != PtrToIdTy)
2478 isa = llvm::ConstantExpr::getBitCast(isa, PtrToIdTy);
2481 auto Fields = Builder.beginStruct();
2483 Fields.add(MakeConstantString(Str));
2484 Fields.addInt(IntTy, Str.size());
2485 llvm::Constant *ObjCStr =
2487 ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStr, PtrToInt8Ty);
2488 ObjCStrings[Str] = ObjCStr;
2489 ConstantStrings.push_back(ObjCStr);
2502 bool isCategoryImpl,
2504 bool IsClassMessage,
2509 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2513 if (Sel == ReleaseSel) {
2521 ActualArgs.
add(
RValue::get(EnforceType(Builder, Receiver, IdTy)), ASTIdTy);
2530 ReceiverClass = GetClassNamed(CGF,
2532 if (IsClassMessage) {
2535 llvm::PointerType::getUnqual(IdTy));
2539 ReceiverClass = EnforceType(Builder, ReceiverClass, IdTy);
2541 if (isCategoryImpl) {
2542 llvm::FunctionCallee classLookupFunction =
nullptr;
2543 if (IsClassMessage) {
2545 IdTy, PtrTy,
true),
"objc_get_meta_class");
2548 IdTy, PtrTy,
true),
"objc_get_class");
2550 ReceiverClass = Builder.CreateCall(classLookupFunction,
2558 if (IsClassMessage) {
2559 if (!MetaClassPtrAlias) {
2564 ReceiverClass = MetaClassPtrAlias;
2566 if (!ClassPtrAlias) {
2571 ReceiverClass = ClassPtrAlias;
2575 llvm::Type *CastTy = llvm::StructType::get(IdTy, IdTy);
2577 llvm::PointerType::getUnqual(CastTy));
2585 llvm::StructType *ObjCSuperTy =
2586 llvm::StructType::get(Receiver->getType(), IdTy);
2594 ObjCSuper = EnforceType(Builder, ObjCSuper, PtrToObjCSuperTy);
2597 llvm::Value *imp = LookupIMPSuper(CGF, ObjCSuper, cmd, MSI);
2598 imp = EnforceType(Builder, imp, MSI.MessengerType);
2600 llvm::Metadata *impMD[] = {
2601 llvm::MDString::get(VMContext, Sel.
getAsString()),
2603 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2604 llvm::Type::getInt1Ty(VMContext), IsClassMessage))};
2605 llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD);
2609 llvm::CallBase *call;
2610 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2611 call->setMetadata(msgSendMDKind, node);
2629 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2633 if (Sel == ReleaseSel) {
2652 llvm::BasicBlock *startBB =
nullptr;
2653 llvm::BasicBlock *messageBB =
nullptr;
2654 llvm::BasicBlock *continueBB =
nullptr;
2656 if (!isPointerSizedReturn) {
2657 startBB = Builder.GetInsertBlock();
2661 llvm::Value *isNil = Builder.CreateICmpEQ(Receiver,
2662 llvm::Constant::getNullValue(Receiver->getType()));
2663 Builder.CreateCondBr(isNil, continueBB, messageBB);
2673 cmd = EnforceType(Builder, cmd, SelectorTy);
2674 Receiver = EnforceType(Builder, Receiver, IdTy);
2676 llvm::Metadata *impMD[] = {
2677 llvm::MDString::get(VMContext, Sel.
getAsString()),
2678 llvm::MDString::get(VMContext, Class ? Class->
getNameAsString() :
""),
2679 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2680 llvm::Type::getInt1Ty(VMContext), Class !=
nullptr))};
2681 llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD);
2698 imp = LookupIMP(CGF, Receiver, cmd, node, MSI);
2705 "objc_msgSend_fpret")
2712 "objc_msgSend_stret")
2716 llvm::FunctionType::get(IdTy, IdTy,
true),
"objc_msgSend")
2724 imp = EnforceType(Builder, imp, MSI.MessengerType);
2726 llvm::CallBase *call;
2728 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2729 call->setMetadata(msgSendMDKind, node);
2732 if (!isPointerSizedReturn) {
2733 messageBB = CGF.
Builder.GetInsertBlock();
2734 CGF.
Builder.CreateBr(continueBB);
2738 llvm::PHINode *phi = Builder.CreatePHI(v->getType(), 2);
2739 phi->addIncoming(v, messageBB);
2740 phi->addIncoming(llvm::Constant::getNullValue(v->getType()), startBB);
2744 llvm::PHINode *phi = Builder.CreatePHI(v.
getType(), 2);
2747 CGF.
InitTempAlloca(NullVal, llvm::Constant::getNullValue(RetTy));
2749 phi->addIncoming(NullVal.
getPointer(), startBB);
2752 std::pair<llvm::Value*,llvm::Value*> v = msgRet.
getComplexVal();
2753 llvm::PHINode *phi = Builder.CreatePHI(v.first->getType(), 2);
2754 phi->addIncoming(v.first, messageBB);
2755 phi->addIncoming(llvm::Constant::getNullValue(v.first->getType()),
2757 llvm::PHINode *phi2 = Builder.CreatePHI(v.second->getType(), 2);
2758 phi2->addIncoming(v.second, messageBB);
2759 phi2->addIncoming(llvm::Constant::getNullValue(v.second->getType()),
2769 llvm::Constant *CGObjCGNU::
2770 GenerateMethodList(StringRef ClassName,
2771 StringRef CategoryName,
2773 bool isClassMethodList) {
2774 if (Methods.empty())
2779 auto MethodList = Builder.beginStruct();
2780 MethodList.addNullPointer(CGM.
Int8PtrTy);
2781 MethodList.addInt(Int32Ty, Methods.size());
2784 llvm::StructType *ObjCMethodTy =
2793 llvm::DataLayout td(&TheModule);
2794 MethodList.addInt(SizeTy, td.getTypeSizeInBits(ObjCMethodTy) /
2810 auto MethodArray = MethodList.beginArray();
2812 for (
const auto *OMD : Methods) {
2813 llvm::Constant *FnPtr =
2814 TheModule.getFunction(SymbolNameForMethod(ClassName, CategoryName,
2816 isClassMethodList));
2817 assert(FnPtr &&
"Can't generate metadata for method that doesn't exist");
2818 auto Method = MethodArray.beginStruct(ObjCMethodTy);
2820 Method.addBitCast(FnPtr, IMPTy);
2821 Method.
add(GetConstantSelector(OMD->getSelector(),
2825 Method.
add(MakeConstantString(OMD->getSelector().getAsString()));
2827 Method.addBitCast(FnPtr, IMPTy);
2829 Method.finishAndAddTo(MethodArray);
2831 MethodArray.finishAndAddTo(MethodList);
2834 return MethodList.finishAndCreateGlobal(
".objc_method_list",
2839 llvm::Constant *CGObjCGNU::
2845 if (IvarNames.empty())
2851 auto IvarList = Builder.beginStruct();
2852 IvarList.addInt(IntTy, (
int)IvarNames.size());
2855 llvm::StructType *ObjCIvarTy =
2856 llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, IntTy);
2859 auto Ivars = IvarList.beginArray(ObjCIvarTy);
2860 for (
unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {
2861 auto Ivar = Ivars.beginStruct(ObjCIvarTy);
2862 Ivar.
add(IvarNames[i]);
2863 Ivar.
add(IvarTypes[i]);
2864 Ivar.
add(IvarOffsets[i]);
2865 Ivar.finishAndAddTo(Ivars);
2867 Ivars.finishAndAddTo(IvarList);
2870 return IvarList.finishAndCreateGlobal(
".objc_ivar_list",
2875 llvm::Constant *CGObjCGNU::GenerateClassStructure(
2876 llvm::Constant *MetaClass,
2877 llvm::Constant *SuperClass,
2880 llvm::Constant *Version,
2881 llvm::Constant *InstanceSize,
2882 llvm::Constant *IVars,
2883 llvm::Constant *Methods,
2884 llvm::Constant *Protocols,
2885 llvm::Constant *IvarOffsets,
2886 llvm::Constant *Properties,
2887 llvm::Constant *StrongIvarBitmap,
2888 llvm::Constant *WeakIvarBitmap,
2897 llvm::StructType *ClassTy = llvm::StructType::get(
2914 IvarOffsets->getType(),
2915 Properties->getType(),
2921 auto Elements = Builder.beginStruct(ClassTy);
2926 Elements.addBitCast(MetaClass, PtrToInt8Ty);
2928 Elements.add(SuperClass);
2930 Elements.add(MakeConstantString(Name,
".class_name"));
2932 Elements.addInt(LongTy, 0);
2934 Elements.addInt(LongTy, info);
2937 llvm::DataLayout td(&TheModule);
2938 Elements.addInt(LongTy,
2939 td.getTypeSizeInBits(ClassTy) /
2942 Elements.add(InstanceSize);
2944 Elements.add(IVars);
2946 Elements.add(Methods);
2949 Elements.add(NULLPtr);
2951 Elements.add(NULLPtr);
2953 Elements.add(NULLPtr);
2955 Elements.addBitCast(Protocols, PtrTy);
2957 Elements.add(NULLPtr);
2959 Elements.addInt(LongTy, ClassABIVersion);
2961 Elements.add(IvarOffsets);
2963 Elements.add(Properties);
2965 Elements.add(StrongIvarBitmap);
2967 Elements.add(WeakIvarBitmap);
2972 std::string ClassSym((isMeta ?
"_OBJC_METACLASS_":
"_OBJC_CLASS_") +
2974 llvm::GlobalVariable *ClassRef = TheModule.getNamedGlobal(ClassSym);
2975 llvm::Constant *Class =
2976 Elements.finishAndCreateGlobal(ClassSym, CGM.
getPointerAlign(),
false,
2979 ClassRef->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(Class,
2980 ClassRef->getType()));
2981 ClassRef->removeFromParent();
2982 Class->setName(ClassSym);
2987 llvm::Constant *CGObjCGNU::
2990 llvm::StructType *ObjCMethodDescTy =
2991 llvm::StructType::get(CGM.
getLLVMContext(), { PtrToInt8Ty, PtrToInt8Ty });
2994 auto MethodList = Builder.beginStruct();
2995 MethodList.addInt(IntTy, Methods.size());
2996 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
2997 for (
auto *M : Methods) {
2998 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
3000 Method.
add(MakeConstantString(Context.getObjCEncodingForMethodDecl(M)));
3001 Method.finishAndAddTo(MethodArray);
3003 MethodArray.finishAndAddTo(MethodList);
3004 return MethodList.finishAndCreateGlobal(
".objc_method_list",
3013 auto ProtocolList = Builder.beginStruct();
3014 ProtocolList.add(NULLPtr);
3015 ProtocolList.addInt(LongTy, Protocols.size());
3017 auto Elements = ProtocolList.beginArray(PtrToInt8Ty);
3018 for (
const std::string *iter = Protocols.begin(), *endIter = Protocols.end();
3019 iter != endIter ; iter++) {
3020 llvm::Constant *protocol =
nullptr;
3021 llvm::StringMap<llvm::Constant*>::iterator value =
3022 ExistingProtocols.find(*iter);
3023 if (value == ExistingProtocols.end()) {
3024 protocol = GenerateEmptyProtocol(*iter);
3026 protocol = value->getValue();
3028 Elements.addBitCast(protocol, PtrToInt8Ty);
3030 Elements.finishAndAddTo(ProtocolList);
3031 return ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
3040 assert(protocol &&
"Unknown protocol");
3047 CGObjCGNU::GenerateEmptyProtocol(StringRef ProtocolName) {
3048 llvm::Constant *ProtocolList = GenerateProtocolList({});
3049 llvm::Constant *MethodList = GenerateProtocolMethodList({});
3050 MethodList = llvm::ConstantExpr::getBitCast(MethodList, PtrToInt8Ty);
3054 auto Elements = Builder.beginStruct();
3058 Elements.add(llvm::ConstantExpr::getIntToPtr(
3059 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3061 Elements.add(MakeConstantString(ProtocolName,
".objc_protocol_name"));
3062 Elements.add(ProtocolList);
3063 Elements.add(MethodList);
3064 Elements.add(MethodList);
3065 Elements.add(MethodList);
3066 Elements.add(MethodList);
3067 Elements.add(NULLPtr);
3068 Elements.add(NULLPtr);
3069 return Elements.finishAndCreateGlobal(SymbolForProtocol(ProtocolName),
3082 Protocols.push_back(PI->getNameAsString());
3086 if (I->isOptional())
3087 OptionalInstanceMethods.push_back(I);
3089 InstanceMethods.push_back(I);
3094 if (I->isOptional())
3095 OptionalClassMethods.push_back(I);
3097 ClassMethods.push_back(I);
3099 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
3100 llvm::Constant *InstanceMethodList =
3101 GenerateProtocolMethodList(InstanceMethods);
3102 llvm::Constant *ClassMethodList =
3103 GenerateProtocolMethodList(ClassMethods);
3104 llvm::Constant *OptionalInstanceMethodList =
3105 GenerateProtocolMethodList(OptionalInstanceMethods);
3106 llvm::Constant *OptionalClassMethodList =
3107 GenerateProtocolMethodList(OptionalClassMethods);
3115 llvm::Constant *PropertyList =
3116 GeneratePropertyList(
nullptr, PD,
false,
false);
3117 llvm::Constant *OptionalPropertyList =
3118 GeneratePropertyList(
nullptr, PD,
false,
true);
3125 auto Elements = Builder.beginStruct();
3127 llvm::ConstantExpr::getIntToPtr(
3128 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3129 Elements.add(MakeConstantString(ProtocolName));
3130 Elements.add(ProtocolList);
3131 Elements.add(InstanceMethodList);
3132 Elements.add(ClassMethodList);
3133 Elements.add(OptionalInstanceMethodList);
3134 Elements.add(OptionalClassMethodList);
3135 Elements.add(PropertyList);
3136 Elements.add(OptionalPropertyList);
3137 ExistingProtocols[ProtocolName] =
3138 llvm::ConstantExpr::getBitCast(
3139 Elements.finishAndCreateGlobal(
".objc_protocol", CGM.
getPointerAlign()),
3142 void CGObjCGNU::GenerateProtocolHolderCategory() {
3146 auto Elements = Builder.beginStruct();
3148 const std::string ClassName =
"__ObjC_Protocol_Holder_Ugly_Hack";
3149 const std::string CategoryName =
"AnotherHack";
3150 Elements.add(MakeConstantString(CategoryName));
3151 Elements.add(MakeConstantString(ClassName));
3153 Elements.addBitCast(GenerateMethodList(
3154 ClassName, CategoryName, {},
false), PtrTy);
3156 Elements.addBitCast(GenerateMethodList(
3157 ClassName, CategoryName, {},
true), PtrTy);
3161 auto ProtocolList = ProtocolListBuilder.beginStruct();
3162 ProtocolList.add(NULLPtr);
3163 ProtocolList.addInt(LongTy, ExistingProtocols.size());
3164 auto ProtocolElements = ProtocolList.beginArray(PtrTy);
3165 for (
auto iter = ExistingProtocols.begin(), endIter = ExistingProtocols.end();
3166 iter != endIter ; iter++) {
3167 ProtocolElements.addBitCast(iter->getValue(), PtrTy);
3169 ProtocolElements.finishAndAddTo(ProtocolList);
3170 Elements.addBitCast(
3171 ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
3174 Categories.push_back(llvm::ConstantExpr::getBitCast(
3191 int bitCount = bits.size();
3193 if (bitCount < ptrBits) {
3195 for (
int i=0 ; i<bitCount ; ++i) {
3196 if (bits[i]) val |= 1ULL<<(i+1);
3198 return llvm::ConstantInt::get(IntPtrTy, val);
3202 while (v < bitCount) {
3204 for (
int i=0 ; (i<32) && (v<bitCount) ; ++i) {
3205 if (bits[v]) word |= 1<<i;
3208 values.push_back(llvm::ConstantInt::get(Int32Ty, word));
3212 auto fields = builder.beginStruct();
3213 fields.addInt(Int32Ty, values.size());
3214 auto array = fields.beginArray();
3215 for (
auto v : values) array.add(v);
3216 array.finishAndAddTo(fields);
3218 llvm::Constant *GS =
3220 llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy);
3224 llvm::Constant *CGObjCGNU::GenerateCategoryProtocolList(
const 3229 return GenerateProtocolList(Protocols);
3241 auto Elements = Builder.beginStruct();
3242 Elements.add(MakeConstantString(CategoryName));
3243 Elements.add(MakeConstantString(ClassName));
3246 InstanceMethods.insert(InstanceMethods.begin(), OCD->
instmeth_begin(),
3248 Elements.addBitCast(
3249 GenerateMethodList(ClassName, CategoryName, InstanceMethods,
false),
3256 Elements.addBitCast(
3257 GenerateMethodList(ClassName, CategoryName, ClassMethods,
true),
3260 Elements.addBitCast(GenerateCategoryProtocolList(CatDecl), PtrTy);
3266 Elements.addBitCast(GeneratePropertyList(OCD, Category,
false), PtrTy);
3268 Elements.addBitCast(GeneratePropertyList(OCD, Category,
true), PtrTy);
3270 Elements.addNullPointer(PtrTy);
3271 Elements.addNullPointer(PtrTy);
3275 Categories.push_back(llvm::ConstantExpr::getBitCast(
3276 Elements.finishAndCreateGlobal(
3277 std::string(
".objc_category_")+ClassName+CategoryName,
3282 llvm::Constant *CGObjCGNU::GeneratePropertyList(
const Decl *Container,
3284 bool isClassProperty,
3285 bool protocolOptionalProperties) {
3288 llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
3289 bool isProtocol = isa<ObjCProtocolDecl>(OCD);
3292 std::function<void(const ObjCProtocolDecl *Proto)> collectProtocolProperties
3294 for (
const auto *
P : Proto->protocols())
3295 collectProtocolProperties(
P);
3297 if (isClassProperty != PD->isClassProperty())
3301 if (!isProtocol && !Context.getObjCPropertyImplDeclForPropertyDecl(PD, Container))
3305 Properties.push_back(PD);
3312 if (isClassProperty != PD->isClassProperty())
3315 Properties.push_back(PD);
3319 if (isClassProperty != PD->isClassProperty())
3323 if (isProtocol && (protocolOptionalProperties != PD->isOptional()))
3330 Properties.push_back(PD);
3335 collectProtocolProperties(
P);
3337 for (
const auto *
P : CD->protocols())
3338 collectProtocolProperties(
P);
3340 auto numProperties = Properties.size();
3342 if (numProperties == 0)
3346 auto propertyList = builder.beginStruct();
3347 auto properties = PushPropertyListHeader(propertyList, numProperties);
3351 for (
auto *property : Properties) {
3352 bool isSynthesized =
false;
3355 auto *propertyImpl = Context.getObjCPropertyImplDeclForPropertyDecl(property, Container);
3357 isSynthesized = (propertyImpl->getPropertyImplementation() ==
3359 isDynamic = (propertyImpl->getPropertyImplementation() ==
3363 PushProperty(properties, property, Container, isSynthesized, isDynamic);
3365 properties.finishAndAddTo(propertyList);
3367 return propertyList.finishAndCreateGlobal(
".objc_property_list",
3385 std::string SuperClassName;
3386 if (SuperClassDecl) {
3388 EmitClassRef(SuperClassName);
3398 std::string classSymbolName =
"__objc_class_name_" + ClassName;
3399 if (
auto *symbol = TheModule.getGlobalVariable(classSymbolName)) {
3400 symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0));
3402 new llvm::GlobalVariable(TheModule, LongTy,
false,
3404 llvm::ConstantInt::get(LongTy, 0),
3420 auto IvarOffsetValues = IvarOffsetBuilder.beginArray(PtrToIntTy);
3424 int superInstanceSize = !SuperClassDecl ? 0 :
3429 instanceSize = 0 - (instanceSize - superInstanceSize);
3435 IvarNames.push_back(MakeConstantString(IVD->getNameAsString()));
3437 std::string TypeStr;
3439 IvarTypes.push_back(MakeConstantString(TypeStr));
3440 IvarAligns.push_back(llvm::ConstantInt::get(IntTy,
3444 uint64_t Offset = BaseOffset;
3446 Offset = BaseOffset - superInstanceSize;
3448 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
3450 std::string OffsetName =
"__objc_ivar_offset_value_" + ClassName +
"." +
3451 IVD->getNameAsString();
3453 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
3455 OffsetVar->setInitializer(OffsetValue);
3461 OffsetVar =
new llvm::GlobalVariable(TheModule, Int32Ty,
3463 OffsetValue, OffsetName);
3464 IvarOffsets.push_back(OffsetValue);
3465 IvarOffsetValues.add(OffsetVar);
3467 IvarOwnership.push_back(lt);
3470 StrongIvars.push_back(
true);
3471 WeakIvars.push_back(
false);
3474 StrongIvars.push_back(
false);
3475 WeakIvars.push_back(
true);
3478 StrongIvars.push_back(
false);
3479 WeakIvars.push_back(
false);
3482 llvm::Constant *StrongIvarBitmap = MakeBitField(StrongIvars);
3483 llvm::Constant *WeakIvarBitmap = MakeBitField(WeakIvars);
3484 llvm::GlobalVariable *IvarOffsetArray =
3485 IvarOffsetValues.finishAndCreateGlobal(
".ivar.offsets",
3490 InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
3500 if (propertyImpl->getPropertyImplementation() ==
3504 InstanceMethods.push_back(accessor);
3506 addPropertyMethod(propertyImpl->getGetterMethodDecl());
3507 addPropertyMethod(propertyImpl->getSetterMethodDecl());
3510 llvm::Constant *Properties = GeneratePropertyList(OID, ClassDecl);
3514 for (
const auto *I : ClassDecl->
protocols())
3515 Protocols.push_back(I->getNameAsString());
3518 llvm::Constant *SuperClass;
3519 if (!SuperClassName.empty()) {
3520 SuperClass = MakeConstantString(SuperClassName,
".super_class_name");
3522 SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty);
3527 llvm::Constant *MethodList = GenerateMethodList(ClassName,
"",
3528 InstanceMethods,
false);
3529 llvm::Constant *ClassMethodList = GenerateMethodList(ClassName,
"",
3530 ClassMethods,
true);
3531 llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
3532 IvarOffsets, IvarAligns, IvarOwnership);
3544 llvm::Constant *offsetPointerIndexes[] = {Zeros[0],
3545 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 2 : 1),
nullptr,
3546 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 3 : 2) };
3548 unsigned ivarIndex = 0;
3551 const std::string Name = GetIVarOffsetVariableName(ClassDecl, IVD);
3552 offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, ivarIndex);
3554 llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr(
3555 cast<llvm::GlobalVariable>(IvarList)->getValueType(), IvarList,
3556 offsetPointerIndexes);
3558 llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name);
3560 offset->setInitializer(offsetValue);
3567 new llvm::GlobalVariable(TheModule, offsetValue->getType(),
3571 llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0);
3574 llvm::Constant *MetaClassStruct = GenerateClassStructure(
3575 NULLPtr, NULLPtr, 0x12L, ClassName.c_str(),
nullptr, Zeros[0],
3576 NULLPtr, ClassMethodList, NULLPtr, NULLPtr,
3577 GeneratePropertyList(OID, ClassDecl,
true), ZeroPtr, ZeroPtr,
true);
3582 llvm::Constant *ClassStruct = GenerateClassStructure(
3583 MetaClassStruct, SuperClass, 0x11L, ClassName.c_str(),
nullptr,
3584 llvm::ConstantInt::get(LongTy, instanceSize), IvarList, MethodList,
3585 GenerateProtocolList(Protocols), IvarOffsetArray, Properties,
3586 StrongIvarBitmap, WeakIvarBitmap);
3591 if (ClassPtrAlias) {
3592 ClassPtrAlias->replaceAllUsesWith(
3593 llvm::ConstantExpr::getBitCast(ClassStruct, IdTy));
3594 ClassPtrAlias->eraseFromParent();
3595 ClassPtrAlias =
nullptr;
3597 if (MetaClassPtrAlias) {
3598 MetaClassPtrAlias->replaceAllUsesWith(
3599 llvm::ConstantExpr::getBitCast(MetaClassStruct, IdTy));
3600 MetaClassPtrAlias->eraseFromParent();
3601 MetaClassPtrAlias =
nullptr;
3605 ClassStruct = llvm::ConstantExpr::getBitCast(ClassStruct, PtrToInt8Ty);
3606 Classes.push_back(ClassStruct);
3609 llvm::Function *CGObjCGNU::ModuleInitFunction() {
3611 if (Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
3612 ExistingProtocols.empty() && SelectorTable.empty())
3616 GenerateProtocolHolderCategory();
3618 llvm::StructType *selStructTy =
3619 dyn_cast<llvm::StructType>(SelectorTy->getElementType());
3623 { PtrToInt8Ty, PtrToInt8Ty });
3624 selStructPtrTy = llvm::PointerType::getUnqual(selStructTy);
3628 llvm::Constant *statics = NULLPtr;
3629 if (!ConstantStrings.empty()) {
3630 llvm::GlobalVariable *fileStatics = [&] {
3632 auto staticsStruct = builder.beginStruct();
3635 if (stringClass.empty()) stringClass =
"NXConstantString";
3636 staticsStruct.add(MakeConstantString(stringClass,
3637 ".objc_static_class_name"));
3639 auto array = staticsStruct.beginArray();
3640 array.addAll(ConstantStrings);
3642 array.finishAndAddTo(staticsStruct);
3644 return staticsStruct.finishAndCreateGlobal(
".objc_statics",
3649 auto allStaticsArray = builder.beginArray(fileStatics->getType());
3650 allStaticsArray.add(fileStatics);
3651 allStaticsArray.addNullPointer(fileStatics->getType());
3653 statics = allStaticsArray.finishAndCreateGlobal(
".objc_statics_ptr",
3655 statics = llvm::ConstantExpr::getBitCast(statics, PtrTy);
3661 unsigned selectorCount;
3664 llvm::GlobalVariable *selectorList = [&] {
3666 auto selectors = builder.beginArray(selStructTy);
3667 auto &table = SelectorTable;
3668 std::vector<Selector> allSelectors;
3669 for (
auto &entry : table)
3670 allSelectors.push_back(entry.first);
3671 llvm::sort(allSelectors);
3673 for (
auto &untypedSel : allSelectors) {
3674 std::string selNameStr = untypedSel.getAsString();
3675 llvm::Constant *selName = ExportUniqueString(selNameStr,
".objc_sel_name");
3677 for (TypedSelector &sel : table[untypedSel]) {
3678 llvm::Constant *selectorTypeEncoding = NULLPtr;
3679 if (!sel.first.empty())
3680 selectorTypeEncoding =
3681 MakeConstantString(sel.first,
".objc_sel_types");
3683 auto selStruct = selectors.beginStruct(selStructTy);
3684 selStruct.add(selName);
3685 selStruct.add(selectorTypeEncoding);
3686 selStruct.finishAndAddTo(selectors);
3689 selectorAliases.push_back(sel.second);
3694 selectorCount = selectors.size();
3700 auto selStruct = selectors.beginStruct(selStructTy);
3701 selStruct.add(NULLPtr);
3702 selStruct.add(NULLPtr);
3703 selStruct.finishAndAddTo(selectors);
3705 return selectors.finishAndCreateGlobal(
".objc_selector_list",
3710 for (
unsigned i = 0; i < selectorCount; ++i) {
3711 llvm::Constant *idxs[] = {
3713 llvm::ConstantInt::get(Int32Ty, i)
3716 llvm::Constant *selPtr = llvm::ConstantExpr::getGetElementPtr(
3717 selectorList->getValueType(), selectorList, idxs);
3720 selPtr = llvm::ConstantExpr::getBitCast(selPtr, SelectorTy);
3721 selectorAliases[i]->replaceAllUsesWith(selPtr);
3722 selectorAliases[i]->eraseFromParent();
3725 llvm::GlobalVariable *symtab = [&] {
3727 auto symtab = builder.beginStruct();
3730 symtab.addInt(LongTy, selectorCount);
3732 symtab.addBitCast(selectorList, selStructPtrTy);
3735 symtab.addInt(CGM.
Int16Ty, Classes.size());
3737 symtab.addInt(CGM.
Int16Ty, Categories.size());
3740 auto classList = symtab.beginArray(PtrToInt8Ty);
3741 classList.addAll(Classes);
3742 classList.addAll(Categories);
3744 classList.add(statics);
3745 classList.add(NULLPtr);
3746 classList.finishAndAddTo(symtab);
3754 llvm::Constant *module = [&] {
3756 LongTy, LongTy, PtrToInt8Ty, symtab->getType(), IntTy
3758 llvm::StructType *moduleTy =
3760 makeArrayRef(moduleEltTys).drop_back(
unsigned(RuntimeVersion < 10)));
3763 auto module = builder.beginStruct(moduleTy);
3765 module.addInt(LongTy, RuntimeVersion);
3767 module.addInt(LongTy, CGM.
getDataLayout().getTypeStoreSize(moduleTy));
3774 module.add(MakeConstantString(path,
".objc_source_file_name"));
3777 if (RuntimeVersion >= 10) {
3780 module.addInt(IntTy, 2);
3784 module.addInt(IntTy, 1);
3786 module.addInt(IntTy, 0);
3789 module.addInt(IntTy, 1);
3800 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
3803 llvm::BasicBlock *EntryBB =
3806 Builder.SetInsertPoint(EntryBB);
3808 llvm::FunctionType *FT =
3809 llvm::FunctionType::get(Builder.getVoidTy(), module->getType(),
true);
3810 llvm::FunctionCallee Register =
3812 Builder.CreateCall(Register, module);
3814 if (!ClassAliases.empty()) {
3815 llvm::Type *ArgTypes[2] = {PtrTy, PtrToInt8Ty};
3816 llvm::FunctionType *RegisterAliasTy =
3817 llvm::FunctionType::get(Builder.getVoidTy(),
3821 llvm::GlobalValue::ExternalWeakLinkage,
"class_registerAlias_np",
3823 llvm::BasicBlock *AliasBB =
3825 llvm::BasicBlock *NoAliasBB =
3829 llvm::Value *HasRegisterAlias = Builder.CreateICmpNE(RegisterAlias,
3830 llvm::Constant::getNullValue(RegisterAlias->getType()));
3831 Builder.CreateCondBr(HasRegisterAlias, AliasBB, NoAliasBB);
3834 Builder.SetInsertPoint(AliasBB);
3836 for (std::vector<ClassAliasPair>::iterator iter = ClassAliases.begin();
3837 iter != ClassAliases.end(); ++iter) {
3838 llvm::Constant *TheClass =
3839 TheModule.getGlobalVariable(
"_OBJC_CLASS_" + iter->first,
true);
3841 TheClass = llvm::ConstantExpr::getBitCast(TheClass, PtrTy);
3842 Builder.CreateCall(RegisterAlias,
3843 {TheClass, MakeConstantString(iter->second)});
3847 Builder.CreateBr(NoAliasBB);
3850 Builder.SetInsertPoint(NoAliasBB);
3852 Builder.CreateRetVoid();
3854 return LoadFunction;
3857 llvm::Function *CGObjCGNU::GenerateMethod(
const ObjCMethodDecl *OMD,
3861 StringRef CategoryName = OCD ? OCD->
getName() :
"";
3862 StringRef ClassName = CD->
getName();
3867 llvm::FunctionType *MethodTy =
3869 std::string FunctionName = SymbolNameForMethod(ClassName, CategoryName,
3870 MethodName, isClassMethod);
3872 llvm::Function *Method
3887 llvm::FunctionCallee CGObjCGNU::GetPropertyGetFunction() {
3888 return GetPropertyFn;
3891 llvm::FunctionCallee CGObjCGNU::GetPropertySetFunction() {
3892 return SetPropertyFn;
3895 llvm::FunctionCallee CGObjCGNU::GetOptimizedPropertySetFunction(
bool atomic,
3900 llvm::FunctionCallee CGObjCGNU::GetGetStructFunction() {
3901 return GetStructPropertyFn;
3904 llvm::FunctionCallee CGObjCGNU::GetSetStructFunction() {
3905 return SetStructPropertyFn;
3908 llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectGetFunction() {
3912 llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectSetFunction() {
3916 llvm::FunctionCallee CGObjCGNU::EnumerationMutationFunction() {
3917 return EnumerationMutationFn;
3944 bool ClearInsertionPoint) {
3946 bool isRethrow =
false;
3950 ExceptionAsObject = Exception;
3953 "Unexpected rethrow outside @catch block.");
3957 if (isRethrow && usesSEHExceptions) {
3966 Throw->setDoesNotReturn();
3970 llvm::CallBase *Throw =
3972 Throw->setDoesNotReturn();
3974 CGF.
Builder.CreateUnreachable();
3975 if (ClearInsertionPoint)
3976 CGF.
Builder.ClearInsertionPoint();
3982 AddrWeakObj = EnforceType(B, AddrWeakObj, PtrToIdTy);
3983 return B.CreateCall(WeakReadFn, AddrWeakObj.
getPointer());
3989 src = EnforceType(B, src, IdTy);
3990 dst = EnforceType(B, dst, PtrToIdTy);
3991 B.CreateCall(WeakAssignFn, {src, dst.
getPointer()});
3998 src = EnforceType(B, src, IdTy);
3999 dst = EnforceType(B, dst, PtrToIdTy);
4001 assert(!threadlocal &&
"EmitObjCGlobalAssign - Threal Local API NYI");
4002 B.CreateCall(GlobalAssignFn, {src, dst.
getPointer()});
4009 src = EnforceType(B, src, IdTy);
4010 dst = EnforceType(B, dst, IdTy);
4011 B.CreateCall(IvarAssignFn, {src, dst.
getPointer(), ivarOffset});
4017 src = EnforceType(B, src, IdTy);
4018 dst = EnforceType(B, dst, PtrToIdTy);
4019 B.CreateCall(StrongCastAssignFn, {src, dst.
getPointer()});
4027 DestPtr = EnforceType(B, DestPtr, PtrTy);
4028 SrcPtr = EnforceType(B, SrcPtr, PtrTy);
4033 llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
4036 const std::string Name = GetIVarOffsetVariableName(ID, Ivar);
4040 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
4041 if (!IvarOffsetPointer)
4042 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule,
4043 llvm::Type::getInt32PtrTy(VMContext),
false,
4045 return IvarOffsetPointer;
4052 unsigned CVRQualifiers) {
4084 if (RuntimeVersion < 10 ||
4086 return CGF.
Builder.CreateZExtOrBitCast(
4089 ObjCIvarOffsetVariable(Interface, Ivar),
4093 std::string name =
"__objc_ivar_offset_value_" +
4096 llvm::Value *Offset = TheModule.getGlobalVariable(name);
4098 auto GV =
new llvm::GlobalVariable(TheModule, IntTy,
4099 false, llvm::GlobalValue::LinkOnceAnyLinkage,
4100 llvm::Constant::getNullValue(IntTy), name);
4105 if (Offset->getType() != PtrDiffTy)
4106 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
4110 return llvm::ConstantInt::get(PtrDiffTy, Offset,
true);
4116 switch (Runtime.getKind()) {
4118 if (Runtime.getVersion() >= VersionTuple(2, 0))
4119 return new CGObjCGNUstep2(CGM);
4120 return new CGObjCGNUstep(CGM);
4123 return new CGObjCGCC(CGM);
4126 return new CGObjCObjFW(CGM);
4132 llvm_unreachable(
"these runtimes are not GNU runtimes");
4134 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.
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
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.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
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.
const T * castAs() const
Member-template castAs<specific type>.
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.
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name. ...
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...
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