30 #include "llvm/ADT/SmallVector.h" 31 #include "llvm/ADT/StringMap.h" 32 #include "llvm/IR/CallSite.h" 33 #include "llvm/IR/DataLayout.h" 34 #include "llvm/IR/Intrinsics.h" 35 #include "llvm/IR/LLVMContext.h" 36 #include "llvm/IR/Module.h" 37 #include "llvm/Support/Compiler.h" 38 #include "llvm/Support/ConvertUTF.h" 41 using namespace clang;
42 using namespace CodeGen;
46 std::string SymbolNameForMethod( StringRef ClassName,
47 StringRef CategoryName,
const Selector MethodName,
49 std::string MethodNameColonStripped = MethodName.
getAsString();
50 std::replace(MethodNameColonStripped.begin(), MethodNameColonStripped.end(),
52 return (Twine(isClassMethod ?
"_c_" :
"_i_") + ClassName +
"_" +
53 CategoryName +
"_" + MethodNameColonStripped).
str();
59 class LazyRuntimeFunction {
61 llvm::FunctionType *FTy;
62 const char *FunctionName;
70 : CGM(nullptr), FunctionName(nullptr), Function(nullptr) {}
74 template <
typename... Tys>
82 FTy = llvm::FunctionType::get(RetTy, ArgTys,
false);
85 FTy = llvm::FunctionType::get(RetTy, None,
false);
89 llvm::FunctionType *getType() {
return FTy; }
93 operator llvm::Constant *() {
101 operator llvm::Function *() {
102 return cast<llvm::Function>((llvm::Constant *)*
this);
113 llvm::Module &TheModule;
116 llvm::StructType *ObjCSuperTy;
119 llvm::PointerType *PtrToObjCSuperTy;
123 llvm::PointerType *SelectorTy;
126 llvm::IntegerType *Int8Ty;
129 llvm::PointerType *PtrToInt8Ty;
131 llvm::StructType *ProtocolTy;
133 llvm::PointerType *ProtocolPtrTy;
139 llvm::PointerType *IMPTy;
144 llvm::PointerType *IdTy;
147 llvm::PointerType *PtrToIdTy;
152 llvm::IntegerType *IntTy;
156 llvm::PointerType *PtrTy;
160 llvm::IntegerType *LongTy;
162 llvm::IntegerType *SizeTy;
164 llvm::IntegerType *IntPtrTy;
166 llvm::IntegerType *PtrDiffTy;
169 llvm::PointerType *PtrToIntTy;
173 llvm::IntegerType *Int32Ty;
175 llvm::IntegerType *Int64Ty;
177 llvm::StructType *PropertyMetadataTy;
181 unsigned msgSendMDKind;
184 bool usesSEHExceptions;
190 (R.
getVersion() >= VersionTuple(major, minor));
193 std::string SymbolForProtocol(StringRef Name) {
194 return (StringRef(
"._OBJC_PROTOCOL_") + Name).str();
197 std::string SymbolForProtocolRef(StringRef Name) {
198 return (StringRef(
"._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;
616 llvm::Function *ModuleInitFunction()
override;
617 llvm::Constant *GetPropertyGetFunction()
override;
618 llvm::Constant *GetPropertySetFunction()
override;
619 llvm::Constant *GetOptimizedPropertySetFunction(
bool atomic,
621 llvm::Constant *GetSetStructFunction()
override;
622 llvm::Constant *GetGetStructFunction()
override;
623 llvm::Constant *GetCppAtomicObjectGetFunction()
override;
624 llvm::Constant *GetCppAtomicObjectSetFunction()
override;
625 llvm::Constant *EnumerationMutationFunction()
override;
633 bool ClearInsertionPoint=
true)
override;
640 bool threadlocal=
false)
override;
650 unsigned CVRQualifiers)
override;
677 class CGObjCGCC :
public CGObjCGNU {
680 LazyRuntimeFunction MsgLookupFn;
684 LazyRuntimeFunction MsgLookupSuperFn;
689 MessageSendInfo &MSI)
override {
692 EnforceType(Builder, Receiver, IdTy),
693 EnforceType(Builder, cmd, SelectorTy) };
695 imp->setMetadata(msgSendMDKind, node);
696 return imp.getInstruction();
702 llvm::Value *lookupArgs[] = {EnforceType(Builder, ObjCSuper,
703 PtrToObjCSuperTy).getPointer(), cmd};
710 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
712 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
713 PtrToObjCSuperTy, SelectorTy);
718 class CGObjCGNUstep :
public CGObjCGNU {
721 LazyRuntimeFunction SlotLookupFn;
726 LazyRuntimeFunction SlotLookupSuperFn;
728 LazyRuntimeFunction SetPropertyAtomic;
730 LazyRuntimeFunction SetPropertyAtomicCopy;
732 LazyRuntimeFunction SetPropertyNonAtomic;
734 LazyRuntimeFunction SetPropertyNonAtomicCopy;
737 LazyRuntimeFunction CxxAtomicObjectGetFn;
740 LazyRuntimeFunction CxxAtomicObjectSetFn;
746 llvm::Constant *GetEHType(
QualType T)
override;
751 MessageSendInfo &MSI)
override {
753 llvm::Function *LookupFn = SlotLookupFn;
765 self = llvm::ConstantPointerNull::get(IdTy);
769 LookupFn->addParamAttr(0, llvm::Attribute::NoCapture);
772 EnforceType(Builder, ReceiverPtr.
getPointer(), PtrToIdTy),
773 EnforceType(Builder, cmd, SelectorTy),
774 EnforceType(Builder,
self, IdTy) };
776 slot.setOnlyReadsMemory();
777 slot->setMetadata(msgSendMDKind, node);
786 Receiver = Builder.
CreateLoad(ReceiverPtr,
true);
792 MessageSendInfo &MSI)
override {
796 llvm::CallInst *slot =
798 slot->setOnlyReadsMemory();
805 CGObjCGNUstep(
CodeGenModule &Mod) : CGObjCGNUstep(Mod, 9, 3, 1) {}
806 CGObjCGNUstep(
CodeGenModule &Mod,
unsigned ABI,
unsigned ProtocolABI,
808 CGObjCGNU(Mod, ABI, ProtocolABI, ClassABI) {
811 llvm::StructType *SlotStructTy =
812 llvm::StructType::get(PtrTy, PtrTy, PtrTy, IntTy, IMPTy);
813 SlotTy = llvm::PointerType::getUnqual(SlotStructTy);
815 SlotLookupFn.init(&CGM,
"objc_msg_lookup_sender", SlotTy, PtrToIdTy,
818 SlotLookupSuperFn.init(&CGM,
"objc_slot_lookup_super", SlotTy,
819 PtrToObjCSuperTy, SelectorTy);
821 if (usesSEHExceptions) {
822 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
824 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy);
826 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
828 EnterCatchFn.init(&CGM,
"__cxa_begin_catch", PtrTy, PtrTy);
830 ExitCatchFn.init(&CGM,
"__cxa_end_catch", VoidTy);
832 ExceptionReThrowFn.init(&CGM,
"_Unwind_Resume_or_Rethrow", VoidTy,
834 }
else if (R.
getVersion() >= VersionTuple(1, 7)) {
835 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
837 EnterCatchFn.init(&CGM,
"objc_begin_catch", IdTy, PtrTy);
839 ExitCatchFn.init(&CGM,
"objc_end_catch", VoidTy);
841 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy, PtrTy);
843 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
844 SetPropertyAtomic.init(&CGM,
"objc_setProperty_atomic", VoidTy, IdTy,
845 SelectorTy, IdTy, PtrDiffTy);
846 SetPropertyAtomicCopy.init(&CGM,
"objc_setProperty_atomic_copy", VoidTy,
847 IdTy, SelectorTy, IdTy, PtrDiffTy);
848 SetPropertyNonAtomic.init(&CGM,
"objc_setProperty_nonatomic", VoidTy,
849 IdTy, SelectorTy, IdTy, PtrDiffTy);
850 SetPropertyNonAtomicCopy.init(&CGM,
"objc_setProperty_nonatomic_copy",
851 VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy);
854 CxxAtomicObjectSetFn.init(&CGM,
"objc_setCppObjectAtomic", VoidTy, PtrTy,
858 CxxAtomicObjectGetFn.init(&CGM,
"objc_getCppObjectAtomic", VoidTy, PtrTy,
862 llvm::Constant *GetCppAtomicObjectGetFunction()
override {
867 return CxxAtomicObjectGetFn;
870 llvm::Constant *GetCppAtomicObjectSetFunction()
override {
875 return CxxAtomicObjectSetFn;
878 llvm::Constant *GetOptimizedPropertySetFunction(
bool atomic,
879 bool copy)
override {
890 if (copy)
return SetPropertyAtomicCopy;
891 return SetPropertyAtomic;
894 return copy ? SetPropertyNonAtomicCopy : SetPropertyNonAtomic;
901 class CGObjCGNUstep2 :
public CGObjCGNUstep {
906 ClassReferenceSection,
909 ProtocolReferenceSection,
911 ConstantStringSection
913 static const char *
const SectionsBaseNames[8];
914 template<SectionKind K>
915 std::string sectionName() {
916 std::string name(SectionsBaseNames[K]);
924 LazyRuntimeFunction MsgLookupSuperFn;
928 bool EmittedProtocol =
false;
933 bool EmittedProtocolRef =
false;
937 bool EmittedClass =
false;
940 std::string SymbolForClassRef(StringRef Name,
bool isWeak) {
942 return (StringRef(
"._OBJC_WEAK_REF_CLASS_") + Name).str();
944 return (StringRef(
"._OBJC_REF_CLASS_") + Name).str();
947 std::string SymbolForClass(StringRef Name) {
948 return (StringRef(
"._OBJC_CLASS_") + Name).str();
950 void CallRuntimeFunction(
CGBuilderTy &B, StringRef FunctionName,
953 for (
auto *Arg : Args)
954 Types.push_back(Arg->getType());
955 llvm::FunctionType *FT = llvm::FunctionType::get(B.getVoidTy(), Types,
958 B.CreateCall(Fn, Args);
967 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
968 if (old != ObjCStrings.end())
976 (LiteralLength < 9) && !isNonASCII) {
982 for (
unsigned i=0 ; i<LiteralLength ; i++)
983 str |= ((uint64_t)SL->
getCodeUnit(i)) << ((64 - 4 - 3) - (i*7));
985 str |= LiteralLength << 3;
988 auto *ObjCStr = llvm::ConstantExpr::getIntToPtr(
989 llvm::ConstantInt::get(Int64Ty, str), IdTy);
990 ObjCStrings[Str] = ObjCStr;
996 if (StringClass.empty()) StringClass =
"NSConstantString";
998 std::string Sym = SymbolForClass(StringClass);
1000 llvm::Constant *
isa = TheModule.getNamedGlobal(Sym);
1003 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
1005 else if (isa->getType() != PtrToIdTy)
1006 isa = llvm::ConstantExpr::getBitCast(isa, PtrToIdTy);
1019 auto Fields = Builder.beginStruct();
1026 unsigned NumU8CodeUnits = Str.size();
1031 const llvm::UTF8 *FromPtr = (
const llvm::UTF8 *)Str.data();
1032 llvm::UTF16 *ToPtr = &ToBuf[0];
1033 (void)llvm::ConvertUTF8toUTF16(&FromPtr, FromPtr + NumU8CodeUnits,
1034 &ToPtr, ToPtr + NumU8CodeUnits, llvm::strictConversion);
1035 uint32_t StringLength = ToPtr - &ToBuf[0];
1039 Fields.addInt(Int32Ty, 2);
1041 Fields.addInt(Int32Ty, StringLength);
1043 Fields.addInt(Int32Ty, StringLength * 2);
1045 Fields.addInt(Int32Ty, 0);
1047 auto Arr = llvm::makeArrayRef(&ToBuf[0], ToPtr+1);
1048 auto *
C = llvm::ConstantDataArray::get(VMContext, Arr);
1049 auto *Buffer =
new llvm::GlobalVariable(TheModule,
C->getType(),
1050 true, llvm::GlobalValue::PrivateLinkage,
C,
".str");
1051 Buffer->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1055 Fields.addInt(Int32Ty, 0);
1057 Fields.addInt(Int32Ty, Str.size());
1059 Fields.addInt(Int32Ty, Str.size());
1061 Fields.addInt(Int32Ty, 0);
1063 Fields.add(MakeConstantString(Str));
1065 std::string StringName;
1068 StringName =
".objc_str_";
1069 for (
int i=0,e=Str.size() ; i<e ; ++i) {
1070 unsigned char c = Str[i];
1083 isNamed ? StringRef(StringName) :
".objc_string",
1084 Align,
false, isNamed ? llvm::GlobalValue::LinkOnceODRLinkage
1085 : llvm::GlobalValue::PrivateLinkage);
1086 ObjCStrGV->setSection(sectionName<ConstantStringSection>());
1088 ObjCStrGV->setComdat(TheModule.getOrInsertComdat(StringName));
1091 llvm::Constant *ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStrGV, IdTy);
1092 ObjCStrings[Str] = ObjCStr;
1093 ConstantStrings.push_back(ObjCStr);
1100 bool isSynthesized=
true,
bool 1110 auto Fields = PropertiesArray.
beginStruct(PropertyMetadataTy);
1113 std::string TypeStr =
1115 Fields.add(MakeConstantString(TypeStr));
1116 std::string typeStr;
1118 Fields.add(MakeConstantString(typeStr));
1122 Fields.add(GetConstantSelector(accessor->getSelector(), TypeStr));
1124 Fields.add(NULLPtr);
1139 llvm::StructType *ObjCMethodDescTy =
1141 { PtrToInt8Ty, PtrToInt8Ty });
1150 auto MethodList = Builder.beginStruct();
1152 MethodList.addInt(IntTy, Methods.size());
1154 llvm::DataLayout td(&TheModule);
1155 MethodList.addInt(IntTy, td.getTypeSizeInBits(ObjCMethodDescTy) /
1158 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
1159 for (
auto *M : Methods) {
1160 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
1161 Method.add(CGObjCGNU::GetConstantSelector(M));
1162 Method.add(GetTypeString(Context.getObjCEncodingForMethodDecl(M,
true)));
1163 Method.finishAndAddTo(MethodArray);
1165 MethodArray.finishAndAddTo(MethodList);
1166 return MethodList.finishAndCreateGlobal(
".objc_protocol_method_list",
1173 Protocols.push_back(
1174 llvm::ConstantExpr::getBitCast(GenerateProtocolRef(PI),
1176 return GenerateProtocolList(Protocols);
1180 llvm::Value *cmd, MessageSendInfo &MSI)
override {
1183 llvm::Value *lookupArgs[] = {CGObjCGNU::EnforceType(Builder, ObjCSuper,
1184 PtrToObjCSuperTy).getPointer(), cmd};
1188 llvm::GlobalVariable *GetClassVar(StringRef Name,
bool isWeak=
false) {
1189 std::string SymbolName = SymbolForClassRef(Name, isWeak);
1190 auto *ClassSymbol = TheModule.getNamedGlobal(SymbolName);
1193 ClassSymbol =
new llvm::GlobalVariable(TheModule,
1195 nullptr, SymbolName);
1201 ClassSymbol->setInitializer(
new llvm::GlobalVariable(TheModule,
1202 Int8Ty,
false, llvm::GlobalValue::ExternalWeakLinkage,
1203 nullptr, SymbolForClass(Name)));
1204 assert(ClassSymbol->getName() == SymbolName);
1208 const std::string &Name,
1209 bool isWeak)
override {
1221 switch (Ownership) {
1243 llvm_unreachable(
"Method should not be called!");
1246 llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName)
override {
1247 std::string Name = SymbolForProtocol(ProtocolName);
1248 auto *GV = TheModule.getGlobalVariable(Name);
1251 GV =
new llvm::GlobalVariable(TheModule, ProtocolTy,
false,
1255 return llvm::ConstantExpr::getBitCast(GV, ProtocolPtrTy);
1259 llvm::StringMap<llvm::Constant*> ExistingProtocolRefs;
1264 auto *&Ref = ExistingProtocolRefs[Name];
1266 auto *&
Protocol = ExistingProtocols[Name];
1268 Protocol = GenerateProtocolRef(PD);
1269 std::string RefName = SymbolForProtocolRef(Name);
1270 assert(!TheModule.getGlobalVariable(RefName));
1272 auto GV =
new llvm::GlobalVariable(TheModule, ProtocolPtrTy,
1273 false, llvm::GlobalValue::LinkOnceODRLinkage,
1274 llvm::ConstantExpr::getBitCast(Protocol, ProtocolPtrTy), RefName);
1275 GV->setComdat(TheModule.getOrInsertComdat(RefName));
1276 GV->setSection(sectionName<ProtocolReferenceSection>());
1280 EmittedProtocolRef =
true;
1285 llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(ProtocolPtrTy,
1287 llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
1290 auto ProtocolBuilder = builder.beginStruct();
1291 ProtocolBuilder.addNullPointer(PtrTy);
1292 ProtocolBuilder.addInt(SizeTy, Protocols.size());
1293 ProtocolBuilder.add(ProtocolArray);
1294 return ProtocolBuilder.finishAndCreateGlobal(
".objc_protocol_list",
1303 auto *&
Protocol = ExistingProtocols[ProtocolName];
1307 EmittedProtocol =
true;
1309 auto SymName = SymbolForProtocol(ProtocolName);
1310 auto *OldGV = TheModule.getGlobalVariable(SymName);
1320 Protocol =
new llvm::GlobalVariable(TheModule, ProtocolTy,
1328 Protocols.push_back(
1329 llvm::ConstantExpr::getBitCast(GenerateProtocolRef(PI),
1331 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
1334 llvm::Constant *InstanceMethodList, *OptionalInstanceMethodList;
1335 llvm::Constant *ClassMethodList, *OptionalClassMethodList;
1337 OptionalInstanceMethodList);
1338 EmitProtocolMethodList(PD->
class_methods(), ClassMethodList,
1339 OptionalClassMethodList);
1344 auto ProtocolBuilder = builder.beginStruct();
1345 ProtocolBuilder.add(llvm::ConstantExpr::getIntToPtr(
1346 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
1347 ProtocolBuilder.add(MakeConstantString(ProtocolName));
1348 ProtocolBuilder.add(ProtocolList);
1349 ProtocolBuilder.add(InstanceMethodList);
1350 ProtocolBuilder.add(ClassMethodList);
1351 ProtocolBuilder.add(OptionalInstanceMethodList);
1352 ProtocolBuilder.add(OptionalClassMethodList);
1354 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
false,
false));
1356 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
false,
true));
1358 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
true,
false));
1360 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
true,
true));
1362 auto *GV = ProtocolBuilder.finishAndCreateGlobal(SymName,
1364 GV->setSection(sectionName<ProtocolSection>());
1365 GV->setComdat(TheModule.getOrInsertComdat(SymName));
1367 OldGV->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(GV,
1369 OldGV->removeFromParent();
1370 GV->setName(SymName);
1375 llvm::Constant *EnforceType(llvm::Constant *Val,
llvm::Type *Ty) {
1376 if (Val->getType() == Ty)
1378 return llvm::ConstantExpr::getBitCast(Val, Ty);
1381 const std::string &TypeEncoding)
override {
1382 return GetConstantSelector(Sel, TypeEncoding);
1384 llvm::Constant *GetTypeString(llvm::StringRef TypeEncoding) {
1385 if (TypeEncoding.empty())
1387 std::string MangledTypes = TypeEncoding;
1388 std::replace(MangledTypes.begin(), MangledTypes.end(),
1390 std::string TypesVarName =
".objc_sel_types_" + MangledTypes;
1391 auto *TypesGlobal = TheModule.getGlobalVariable(TypesVarName);
1393 llvm::Constant *Init = llvm::ConstantDataArray::getString(VMContext,
1395 auto *GV =
new llvm::GlobalVariable(TheModule, Init->getType(),
1396 true, llvm::GlobalValue::LinkOnceODRLinkage, Init, TypesVarName);
1397 GV->setComdat(TheModule.getOrInsertComdat(TypesVarName));
1401 return llvm::ConstantExpr::getGetElementPtr(TypesGlobal->getValueType(),
1402 TypesGlobal, Zeros);
1404 llvm::Constant *GetConstantSelector(
Selector Sel,
1405 const std::string &TypeEncoding)
override {
1410 std::string MangledTypes = TypeEncoding;
1411 std::replace(MangledTypes.begin(), MangledTypes.end(),
1413 auto SelVarName = (StringRef(
".objc_selector_") + Sel.
getAsString() +
"_" +
1414 MangledTypes).
str();
1415 if (
auto *GV = TheModule.getNamedGlobal(SelVarName))
1416 return EnforceType(GV, SelectorTy);
1418 auto SelBuilder = builder.beginStruct();
1419 SelBuilder.add(ExportUniqueString(Sel.
getAsString(),
".objc_sel_name_",
1421 SelBuilder.add(GetTypeString(TypeEncoding));
1422 auto *GV = SelBuilder.finishAndCreateGlobal(SelVarName,
1424 GV->setComdat(TheModule.getOrInsertComdat(SelVarName));
1426 GV->setSection(sectionName<SelectorSection>());
1427 auto *SelVal = EnforceType(GV, SelectorTy);
1430 llvm::StructType *emptyStruct =
nullptr;
1439 std::pair<llvm::Constant*,llvm::Constant*>
1440 GetSectionBounds(StringRef Section) {
1441 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1442 if (emptyStruct ==
nullptr) {
1444 emptyStruct->setBody({},
true);
1446 auto ZeroInit = llvm::Constant::getNullValue(emptyStruct);
1447 auto Sym = [&](StringRef Prefix, StringRef SecSuffix) {
1448 auto *Sym =
new llvm::GlobalVariable(TheModule, emptyStruct,
1450 llvm::GlobalValue::LinkOnceODRLinkage, ZeroInit, Prefix +
1453 Sym->setSection((Section + SecSuffix).
str());
1454 Sym->setComdat(TheModule.getOrInsertComdat((Prefix +
1456 Sym->setAlignment(1);
1459 return { Sym(
"__start_",
"$a"), Sym(
"__stop",
"$z") };
1461 auto *Start =
new llvm::GlobalVariable(TheModule, PtrTy,
1466 auto *Stop =
new llvm::GlobalVariable(TheModule, PtrTy,
1471 return { Start, Stop };
1476 llvm::Function *ModuleInitFunction()
override {
1478 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
1479 llvm::GlobalValue::LinkOnceODRLinkage,
".objcv2_load_function",
1482 LoadFunction->setComdat(TheModule.getOrInsertComdat(
".objcv2_load_function"));
1484 llvm::BasicBlock *EntryBB =
1487 B.SetInsertPoint(EntryBB);
1489 auto InitStructBuilder = builder.beginStruct();
1490 InitStructBuilder.addInt(Int64Ty, 0);
1491 for (
auto *s : SectionsBaseNames) {
1492 auto bounds = GetSectionBounds(s);
1493 InitStructBuilder.add(bounds.first);
1494 InitStructBuilder.add(bounds.second);
1496 auto *InitStruct = InitStructBuilder.finishAndCreateGlobal(
".objc_init",
1499 InitStruct->setComdat(TheModule.getOrInsertComdat(
".objc_init"));
1501 CallRuntimeFunction(B,
"__objc_load", {InitStruct});;
1508 auto *InitVar =
new llvm::GlobalVariable(TheModule, LoadFunction->getType(),
1509 true, llvm::GlobalValue::LinkOnceAnyLinkage,
1510 LoadFunction,
".objc_ctor");
1513 assert(InitVar->getName() ==
".objc_ctor");
1519 if (CGM.
getTriple().isOSBinFormatCOFF())
1520 InitVar->setSection(
".CRT$XCLz");
1522 InitVar->setSection(
".ctors");
1524 InitVar->setComdat(TheModule.getOrInsertComdat(
".objc_ctor"));
1526 for (
auto *C : Categories) {
1527 auto *Cat = cast<llvm::GlobalVariable>(C->stripPointerCasts());
1528 Cat->setSection(sectionName<CategorySection>());
1532 StringRef Section) {
1533 auto nullBuilder = builder.beginStruct();
1534 for (
auto *F : Init)
1536 auto GV = nullBuilder.finishAndCreateGlobal(Name, CGM.
getPointerAlign(),
1537 false, llvm::GlobalValue::LinkOnceODRLinkage);
1538 GV->setSection(Section);
1539 GV->setComdat(TheModule.getOrInsertComdat(Name));
1544 for (
auto clsAlias : ClassAliases)
1545 createNullGlobal(std::string(
".objc_class_alias") +
1546 clsAlias.second, { MakeConstantString(clsAlias.second),
1547 GetClassVar(clsAlias.first) }, sectionName<ClassAliasSection>());
1552 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
1553 createNullGlobal(
".objc_null_selector", {NULLPtr, NULLPtr},
1554 sectionName<SelectorSection>());
1555 if (Categories.empty())
1556 createNullGlobal(
".objc_null_category", {NULLPtr, NULLPtr,
1557 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr},
1558 sectionName<CategorySection>());
1559 if (!EmittedClass) {
1560 createNullGlobal(
".objc_null_cls_init_ref", NULLPtr,
1561 sectionName<ClassSection>());
1562 createNullGlobal(
".objc_null_class_ref", { NULLPtr, NULLPtr },
1563 sectionName<ClassReferenceSection>());
1565 if (!EmittedProtocol)
1566 createNullGlobal(
".objc_null_protocol", {NULLPtr, NULLPtr, NULLPtr,
1567 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr,
1568 NULLPtr}, sectionName<ProtocolSection>());
1569 if (!EmittedProtocolRef)
1570 createNullGlobal(
".objc_null_protocol_ref", {NULLPtr},
1571 sectionName<ProtocolReferenceSection>());
1572 if (ClassAliases.empty())
1573 createNullGlobal(
".objc_null_class_alias", { NULLPtr, NULLPtr },
1574 sectionName<ClassAliasSection>());
1575 if (ConstantStrings.empty()) {
1576 auto i32Zero = llvm::ConstantInt::get(Int32Ty, 0);
1577 createNullGlobal(
".objc_null_constant_string", { NULLPtr, i32Zero,
1578 i32Zero, i32Zero, i32Zero, NULLPtr },
1579 sectionName<ConstantStringSection>());
1582 ConstantStrings.clear();
1591 std::string TypeEncoding;
1594 std::replace(TypeEncoding.begin(), TypeEncoding.end(),
1596 const std::string Name =
"__objc_ivar_offset_" + ID->
getNameAsString()
1604 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
1605 if (!IvarOffsetPointer)
1606 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule, IntTy,
false,
1610 if (Offset->getType() != PtrDiffTy)
1611 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
1621 auto *classNameConstant = MakeConstantString(className);
1624 auto metaclassFields = builder.beginStruct();
1626 metaclassFields.addNullPointer(PtrTy);
1628 metaclassFields.addNullPointer(PtrTy);
1630 metaclassFields.add(classNameConstant);
1632 metaclassFields.addInt(LongTy, 0);
1635 metaclassFields.addInt(LongTy, 1);
1639 metaclassFields.addInt(LongTy, 0);
1641 metaclassFields.addNullPointer(PtrTy);
1646 metaclassFields.addNullPointer(PtrTy);
1651 metaclassFields.addBitCast(
1652 GenerateMethodList(className,
"", ClassMethods,
true),
1656 metaclassFields.addNullPointer(PtrTy);
1658 metaclassFields.addNullPointer(PtrTy);
1660 metaclassFields.addNullPointer(PtrTy);
1662 metaclassFields.addNullPointer(PtrTy);
1664 metaclassFields.addNullPointer(PtrTy);
1666 metaclassFields.addNullPointer(PtrTy);
1668 metaclassFields.addNullPointer(PtrTy);
1670 metaclassFields.addInt(LongTy, 0);
1672 metaclassFields.add(GeneratePropertyList(OID, classDecl,
true));
1674 auto *metaclass = metaclassFields.finishAndCreateGlobal(
"._OBJC_METACLASS_" 1677 auto classFields = builder.beginStruct();
1679 classFields.add(metaclass);
1684 if (SuperClassDecl) {
1685 auto SuperClassName = SymbolForClass(SuperClassDecl->
getNameAsString());
1686 llvm::Constant *SuperClass = TheModule.getNamedGlobal(SuperClassName);
1689 SuperClass =
new llvm::GlobalVariable(TheModule, PtrTy,
false,
1692 classFields.add(llvm::ConstantExpr::getBitCast(SuperClass, PtrTy));
1694 classFields.addNullPointer(PtrTy);
1696 classFields.add(classNameConstant);
1698 classFields.addInt(LongTy, 0);
1701 classFields.addInt(LongTy, 0);
1703 int superInstanceSize = !SuperClassDecl ? 0 :
1707 classFields.addInt(LongTy,
1709 superInstanceSize));
1712 classFields.addNullPointer(PtrTy);
1717 llvm::DataLayout td(&TheModule);
1720 auto ivarListBuilder = b.beginStruct();
1722 ivarListBuilder.addInt(IntTy, ivar_count);
1724 llvm::StructType *ObjCIvarTy = llvm::StructType::get(
1730 ivarListBuilder.addInt(SizeTy, td.getTypeSizeInBits(ObjCIvarTy) /
1733 auto ivarArrayBuilder = ivarListBuilder.beginArray();
1737 auto ivarTy = IVD->getType();
1738 auto ivarBuilder = ivarArrayBuilder.beginStruct();
1740 ivarBuilder.add(MakeConstantString(IVD->getNameAsString()));
1742 std::string TypeStr;
1745 ivarBuilder.add(MakeConstantString(TypeStr));
1747 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
1748 uint64_t Offset = BaseOffset - superInstanceSize;
1749 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
1750 std::string OffsetName = GetIVarOffsetVariableName(classDecl, IVD);
1751 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
1753 OffsetVar->setInitializer(OffsetValue);
1755 OffsetVar =
new llvm::GlobalVariable(TheModule, IntTy,
1757 OffsetValue, OffsetName);
1758 auto ivarVisibility =
1764 OffsetVar->setVisibility(ivarVisibility);
1765 ivarBuilder.add(OffsetVar);
1767 ivarBuilder.addInt(Int32Ty,
1778 ivarBuilder.addInt(Int32Ty,
1779 (align << 3) | (1<<2) |
1780 FlagsForOwnership(ivarTy.getQualifiers().getObjCLifetime()));
1781 ivarBuilder.finishAndAddTo(ivarArrayBuilder);
1783 ivarArrayBuilder.finishAndAddTo(ivarListBuilder);
1784 auto ivarList = ivarListBuilder.finishAndCreateGlobal(
".objc_ivar_list",
1786 llvm::GlobalValue::PrivateLinkage);
1787 classFields.add(ivarList);
1791 InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
1794 if (propImpl->getPropertyImplementation() ==
1799 InstanceMethods.push_back(OMD);
1805 if (InstanceMethods.size() == 0)
1806 classFields.addNullPointer(PtrTy);
1808 classFields.addBitCast(
1809 GenerateMethodList(className,
"", InstanceMethods,
false),
1812 classFields.addNullPointer(PtrTy);
1814 classFields.addNullPointer(PtrTy);
1816 classFields.addNullPointer(PtrTy);
1818 classFields.addNullPointer(PtrTy);
1820 classFields.addNullPointer(PtrTy);
1823 for (
const auto *I : classDecl->
protocols())
1824 Protocols.push_back(
1825 llvm::ConstantExpr::getBitCast(GenerateProtocolRef(I),
1827 if (Protocols.empty())
1828 classFields.addNullPointer(PtrTy);
1830 classFields.add(GenerateProtocolList(Protocols));
1832 classFields.addNullPointer(PtrTy);
1834 classFields.addInt(LongTy, 0);
1836 classFields.add(GeneratePropertyList(OID, classDecl));
1839 classFields.finishAndCreateGlobal(SymbolForClass(className),
1842 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1843 auto Storage = llvm::GlobalValue::DefaultStorageClass;
1845 Storage = llvm::GlobalValue::DLLImportStorageClass;
1847 Storage = llvm::GlobalValue::DLLExportStorageClass;
1848 cast<llvm::GlobalValue>(classStruct)->setDLLStorageClass(Storage);
1851 auto *classRefSymbol = GetClassVar(className);
1852 classRefSymbol->setSection(sectionName<ClassReferenceSection>());
1853 classRefSymbol->setInitializer(llvm::ConstantExpr::getBitCast(classStruct, IdTy));
1858 if (ClassPtrAlias) {
1859 ClassPtrAlias->replaceAllUsesWith(
1860 llvm::ConstantExpr::getBitCast(classStruct, IdTy));
1861 ClassPtrAlias->eraseFromParent();
1862 ClassPtrAlias =
nullptr;
1864 if (
auto Placeholder =
1865 TheModule.getNamedGlobal(SymbolForClass(className)))
1866 if (Placeholder != classStruct) {
1867 Placeholder->replaceAllUsesWith(
1868 llvm::ConstantExpr::getBitCast(classStruct, Placeholder->getType()));
1869 Placeholder->eraseFromParent();
1870 classStruct->setName(SymbolForClass(className));
1872 if (MetaClassPtrAlias) {
1873 MetaClassPtrAlias->replaceAllUsesWith(
1874 llvm::ConstantExpr::getBitCast(metaclass, IdTy));
1875 MetaClassPtrAlias->eraseFromParent();
1876 MetaClassPtrAlias =
nullptr;
1878 assert(classStruct->getName() == SymbolForClass(className));
1880 auto classInitRef =
new llvm::GlobalVariable(TheModule,
1882 classStruct,
"._OBJC_INIT_CLASS_" + className);
1883 classInitRef->setSection(sectionName<ClassSection>());
1886 EmittedClass =
true;
1889 CGObjCGNUstep2(
CodeGenModule &Mod) : CGObjCGNUstep(Mod, 10, 4, 2) {
1890 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
1891 PtrToObjCSuperTy, SelectorTy);
1900 PropertyMetadataTy =
1902 { PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty });
1907 const char *
const CGObjCGNUstep2::SectionsBaseNames[8] =
1911 "__objc_class_refs",
1914 "__objc_protocol_refs",
1915 "__objc_class_aliases",
1916 "__objc_constant_string" 1920 class CGObjCObjFW:
public CGObjCGNU {
1924 LazyRuntimeFunction MsgLookupFn;
1927 LazyRuntimeFunction MsgLookupFnSRet;
1931 LazyRuntimeFunction MsgLookupSuperFn, MsgLookupSuperFnSRet;
1935 MessageSendInfo &MSI)
override {
1938 EnforceType(Builder, Receiver, IdTy),
1939 EnforceType(Builder, cmd, SelectorTy) };
1947 imp->setMetadata(msgSendMDKind, node);
1948 return imp.getInstruction();
1952 llvm::Value *cmd, MessageSendInfo &MSI)
override {
1955 EnforceType(Builder, ObjCSuper.
getPointer(), PtrToObjCSuperTy), cmd,
1965 bool isWeak)
override {
1967 return CGObjCGNU::GetClassNamed(CGF, Name, isWeak);
1970 std::string SymbolName =
"_OBJC_CLASS_" + Name;
1971 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(SymbolName);
1973 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
1975 nullptr, SymbolName);
1982 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
1983 MsgLookupFnSRet.init(&CGM,
"objc_msg_lookup_stret", IMPTy, IdTy,
1986 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
1987 PtrToObjCSuperTy, SelectorTy);
1988 MsgLookupSuperFnSRet.init(&CGM,
"objc_msg_lookup_super_stret", IMPTy,
1989 PtrToObjCSuperTy, SelectorTy);
1997 void CGObjCGNU::EmitClassRef(
const std::string &className) {
1998 std::string symbolRef =
"__objc_class_ref_" + className;
2000 if (TheModule.getGlobalVariable(symbolRef))
2002 std::string symbolName =
"__objc_class_name_" + className;
2003 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
2005 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
2007 nullptr, symbolName);
2009 new llvm::GlobalVariable(TheModule, ClassSymbol->getType(),
true,
2010 llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef);
2013 CGObjCGNU::CGObjCGNU(
CodeGenModule &cgm,
unsigned runtimeABIVersion,
2014 unsigned protocolClassVersion,
unsigned classABI)
2016 VMContext(cgm.getLLVMContext()), ClassPtrAlias(nullptr),
2017 MetaClassPtrAlias(nullptr), RuntimeVersion(runtimeABIVersion),
2018 ProtocolVersion(protocolClassVersion), ClassABIVersion(classABI) {
2020 msgSendMDKind = VMContext.getMDKindID(
"GNUObjCMessageSend");
2025 IntTy = cast<llvm::IntegerType>(
2027 LongTy = cast<llvm::IntegerType>(
2029 SizeTy = cast<llvm::IntegerType>(
2031 PtrDiffTy = cast<llvm::IntegerType>(
2035 Int8Ty = llvm::Type::getInt8Ty(VMContext);
2037 PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
2038 ProtocolPtrTy = llvm::PointerType::getUnqual(
2041 Zeros[0] = llvm::ConstantInt::get(LongTy, 0);
2042 Zeros[1] = Zeros[0];
2043 NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty);
2047 SelectorTy = PtrToInt8Ty;
2052 PtrToIntTy = llvm::PointerType::getUnqual(IntTy);
2053 PtrTy = PtrToInt8Ty;
2055 Int32Ty = llvm::Type::getInt32Ty(VMContext);
2056 Int64Ty = llvm::Type::getInt64Ty(VMContext);
2059 CGM.
getDataLayout().getPointerSizeInBits() == 32 ? Int32Ty : Int64Ty;
2070 PtrToIdTy = llvm::PointerType::getUnqual(IdTy);
2071 ProtocolTy = llvm::StructType::get(IdTy,
2093 PropertyMetadataTy = llvm::StructType::get(CGM.
getLLVMContext(), {
2094 PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty,
2095 PtrToInt8Ty, PtrToInt8Ty });
2097 ObjCSuperTy = llvm::StructType::get(IdTy, IdTy);
2098 PtrToObjCSuperTy = llvm::PointerType::getUnqual(ObjCSuperTy);
2100 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
2103 ExceptionThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy);
2104 ExceptionReThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy);
2106 SyncEnterFn.init(&CGM,
"objc_sync_enter", IntTy, IdTy);
2108 SyncExitFn.init(&CGM,
"objc_sync_exit", IntTy, IdTy);
2111 EnumerationMutationFn.init(&CGM,
"objc_enumerationMutation", VoidTy, IdTy);
2114 GetPropertyFn.init(&CGM,
"objc_getProperty", IdTy, IdTy, SelectorTy,
2117 SetPropertyFn.init(&CGM,
"objc_setProperty", VoidTy, IdTy, SelectorTy,
2118 PtrDiffTy, IdTy, BoolTy, BoolTy);
2120 GetStructPropertyFn.init(&CGM,
"objc_getPropertyStruct", VoidTy, PtrTy, PtrTy,
2121 PtrDiffTy, BoolTy, BoolTy);
2123 SetStructPropertyFn.init(&CGM,
"objc_setPropertyStruct", VoidTy, PtrTy, PtrTy,
2124 PtrDiffTy, BoolTy, BoolTy);
2127 llvm::Type *IMPArgs[] = { IdTy, SelectorTy };
2128 IMPTy = llvm::PointerType::getUnqual(llvm::FunctionType::get(IdTy, IMPArgs,
2133 RuntimeVersion = 10;
2148 IvarAssignFn.init(&CGM,
"objc_assign_ivar", IdTy, IdTy, IdTy, PtrDiffTy);
2150 StrongCastAssignFn.init(&CGM,
"objc_assign_strongCast", IdTy, IdTy,
2153 GlobalAssignFn.init(&CGM,
"objc_assign_global", IdTy, IdTy, PtrToIdTy);
2155 WeakAssignFn.init(&CGM,
"objc_assign_weak", IdTy, IdTy, PtrToIdTy);
2157 WeakReadFn.init(&CGM,
"objc_read_weak", IdTy, PtrToIdTy);
2159 MemMoveFn.init(&CGM,
"objc_memmove_collectable", PtrTy, PtrTy, PtrTy,
2165 const std::string &Name,
bool isWeak) {
2166 llvm::Constant *ClassName = MakeConstantString(Name);
2177 llvm::Constant *ClassLookupFn =
2179 "objc_lookup_class");
2189 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value))
2195 auto *
Value = GetClassNamed(CGF,
"NSAutoreleasePool",
false);
2196 if (CGM.
getTriple().isOSBinFormatCOFF()) {
2197 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value)) {
2203 for (
const auto &Result : DC->
lookup(&II))
2204 if ((VD = dyn_cast<VarDecl>(Result)))
2214 const std::string &TypeEncoding) {
2216 llvm::GlobalAlias *SelValue =
nullptr;
2219 e = Types.end() ; i!=e ; i++) {
2220 if (i->first == TypeEncoding) {
2221 SelValue = i->second;
2227 SelectorTy->getElementType(), 0, llvm::GlobalValue::PrivateLinkage,
2228 ".objc_selector_" + Sel.
getAsString(), &TheModule);
2229 Types.emplace_back(TypeEncoding, SelValue);
2247 return GetTypedSelector(CGF, Sel, std::string());
2253 return GetTypedSelector(CGF, Method->
getSelector(), SelTypes);
2256 llvm::Constant *CGObjCGNU::GetEHType(
QualType T) {
2263 return MakeConstantString(
"@id");
2271 assert(OPT &&
"Invalid @catch type.");
2273 assert(IDecl &&
"Invalid @catch type.");
2277 llvm::Constant *CGObjCGNUstep::GetEHType(
QualType T) {
2278 if (usesSEHExceptions)
2282 return CGObjCGNU::GetEHType(T);
2290 llvm::Constant *IDEHType =
2291 CGM.
getModule().getGlobalVariable(
"__objc_id_type_info");
2294 new llvm::GlobalVariable(CGM.
getModule(), PtrToInt8Ty,
2297 nullptr,
"__objc_id_type_info");
2298 return llvm::ConstantExpr::getBitCast(IDEHType, PtrToInt8Ty);
2303 assert(PT &&
"Invalid @catch type.");
2305 assert(IT &&
"Invalid @catch type.");
2308 std::string typeinfoName =
"__objc_eh_typeinfo_" + className;
2311 llvm::Constant *typeinfo = TheModule.getGlobalVariable(typeinfoName);
2313 return llvm::ConstantExpr::getBitCast(typeinfo, PtrToInt8Ty);
2320 const char *vtableName =
"_ZTVN7gnustep7libobjc22__objc_class_type_infoE";
2321 auto *Vtable = TheModule.getGlobalVariable(vtableName);
2323 Vtable =
new llvm::GlobalVariable(TheModule, PtrToInt8Ty,
true,
2325 nullptr, vtableName);
2327 llvm::Constant *Two = llvm::ConstantInt::get(IntTy, 2);
2328 auto *BVtable = llvm::ConstantExpr::getBitCast(
2329 llvm::ConstantExpr::getGetElementPtr(Vtable->getValueType(), Vtable, Two),
2332 llvm::Constant *typeName =
2333 ExportUniqueString(className,
"__objc_eh_typename_");
2336 auto fields = builder.beginStruct();
2337 fields.add(BVtable);
2338 fields.add(typeName);
2339 llvm::Constant *TI =
2340 fields.finishAndCreateGlobal(
"__objc_eh_typeinfo_" + className,
2343 llvm::GlobalValue::LinkOnceODRLinkage);
2344 return llvm::ConstantExpr::getBitCast(TI, PtrToInt8Ty);
2350 std::string Str = SL->
getString().str();
2354 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
2355 if (old != ObjCStrings.end())
2360 if (StringClass.empty()) StringClass =
"NSConstantString";
2362 std::string Sym =
"_OBJC_CLASS_";
2365 llvm::Constant *isa = TheModule.getNamedGlobal(Sym);
2368 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
2369 llvm::GlobalValue::ExternalWeakLinkage,
nullptr, Sym);
2370 else if (isa->getType() != PtrToIdTy)
2371 isa = llvm::ConstantExpr::getBitCast(isa, PtrToIdTy);
2374 auto Fields = Builder.beginStruct();
2376 Fields.add(MakeConstantString(Str));
2377 Fields.addInt(IntTy, Str.size());
2378 llvm::Constant *ObjCStr =
2380 ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStr, PtrToInt8Ty);
2381 ObjCStrings[Str] = ObjCStr;
2382 ConstantStrings.push_back(ObjCStr);
2395 bool isCategoryImpl,
2397 bool IsClassMessage,
2402 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2406 if (Sel == ReleaseSel) {
2414 ActualArgs.
add(
RValue::get(EnforceType(Builder, Receiver, IdTy)), ASTIdTy);
2423 ReceiverClass = GetClassNamed(CGF,
2425 if (IsClassMessage) {
2428 llvm::PointerType::getUnqual(IdTy));
2432 ReceiverClass = EnforceType(Builder, ReceiverClass, IdTy);
2434 if (isCategoryImpl) {
2435 llvm::Constant *classLookupFunction =
nullptr;
2436 if (IsClassMessage) {
2438 IdTy, PtrTy,
true),
"objc_get_meta_class");
2441 IdTy, PtrTy,
true),
"objc_get_class");
2443 ReceiverClass = Builder.CreateCall(classLookupFunction,
2451 if (IsClassMessage) {
2452 if (!MetaClassPtrAlias) {
2457 ReceiverClass = MetaClassPtrAlias;
2459 if (!ClassPtrAlias) {
2464 ReceiverClass = ClassPtrAlias;
2468 llvm::Type *CastTy = llvm::StructType::get(IdTy, IdTy);
2470 llvm::PointerType::getUnqual(CastTy));
2478 llvm::StructType *ObjCSuperTy =
2479 llvm::StructType::get(Receiver->getType(), IdTy);
2489 ObjCSuper = EnforceType(Builder, ObjCSuper, PtrToObjCSuperTy);
2492 llvm::Value *imp = LookupIMPSuper(CGF, ObjCSuper, cmd, MSI);
2493 imp = EnforceType(Builder, imp, MSI.MessengerType);
2495 llvm::Metadata *impMD[] = {
2496 llvm::MDString::get(VMContext, Sel.
getAsString()),
2498 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2499 llvm::Type::getInt1Ty(VMContext), IsClassMessage))};
2500 llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD);
2504 llvm::Instruction *call;
2505 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2506 call->setMetadata(msgSendMDKind, node);
2524 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2528 if (Sel == ReleaseSel) {
2547 llvm::BasicBlock *startBB =
nullptr;
2548 llvm::BasicBlock *messageBB =
nullptr;
2549 llvm::BasicBlock *continueBB =
nullptr;
2551 if (!isPointerSizedReturn) {
2552 startBB = Builder.GetInsertBlock();
2556 llvm::Value *isNil = Builder.CreateICmpEQ(Receiver,
2557 llvm::Constant::getNullValue(Receiver->getType()));
2558 Builder.CreateCondBr(isNil, continueBB, messageBB);
2568 cmd = EnforceType(Builder, cmd, SelectorTy);
2569 Receiver = EnforceType(Builder, Receiver, IdTy);
2571 llvm::Metadata *impMD[] = {
2572 llvm::MDString::get(VMContext, Sel.
getAsString()),
2573 llvm::MDString::get(VMContext, Class ? Class->
getNameAsString() :
""),
2574 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2575 llvm::Type::getInt1Ty(VMContext), Class !=
nullptr))};
2576 llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD);
2593 imp = LookupIMP(CGF, Receiver, cmd, node, MSI);
2599 "objc_msgSend_fpret");
2604 "objc_msgSend_stret");
2614 imp = EnforceType(Builder, imp, MSI.MessengerType);
2616 llvm::Instruction *call;
2618 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2619 call->setMetadata(msgSendMDKind, node);
2622 if (!isPointerSizedReturn) {
2623 messageBB = CGF.
Builder.GetInsertBlock();
2624 CGF.
Builder.CreateBr(continueBB);
2628 llvm::PHINode *phi = Builder.CreatePHI(v->getType(), 2);
2629 phi->addIncoming(v, messageBB);
2630 phi->addIncoming(llvm::Constant::getNullValue(v->getType()), startBB);
2634 llvm::PHINode *phi = Builder.CreatePHI(v.
getType(), 2);
2637 CGF.
InitTempAlloca(NullVal, llvm::Constant::getNullValue(RetTy));
2639 phi->addIncoming(NullVal.
getPointer(), startBB);
2642 std::pair<llvm::Value*,llvm::Value*> v = msgRet.
getComplexVal();
2643 llvm::PHINode *phi = Builder.CreatePHI(v.first->getType(), 2);
2644 phi->addIncoming(v.first, messageBB);
2645 phi->addIncoming(llvm::Constant::getNullValue(v.first->getType()),
2647 llvm::PHINode *phi2 = Builder.CreatePHI(v.second->getType(), 2);
2648 phi2->addIncoming(v.second, messageBB);
2649 phi2->addIncoming(llvm::Constant::getNullValue(v.second->getType()),
2659 llvm::Constant *CGObjCGNU::
2660 GenerateMethodList(StringRef ClassName,
2661 StringRef CategoryName,
2663 bool isClassMethodList) {
2664 if (Methods.empty())
2669 auto MethodList = Builder.beginStruct();
2670 MethodList.addNullPointer(CGM.
Int8PtrTy);
2671 MethodList.addInt(Int32Ty, Methods.size());
2674 llvm::StructType *ObjCMethodTy =
2683 llvm::DataLayout td(&TheModule);
2684 MethodList.addInt(SizeTy, td.getTypeSizeInBits(ObjCMethodTy) /
2700 auto MethodArray = MethodList.beginArray();
2702 for (
const auto *OMD : Methods) {
2703 llvm::Constant *FnPtr =
2704 TheModule.getFunction(SymbolNameForMethod(ClassName, CategoryName,
2706 isClassMethodList));
2707 assert(FnPtr &&
"Can't generate metadata for method that doesn't exist");
2708 auto Method = MethodArray.beginStruct(ObjCMethodTy);
2710 Method.addBitCast(FnPtr, IMPTy);
2711 Method.
add(GetConstantSelector(OMD->getSelector(),
2715 Method.
add(MakeConstantString(OMD->getSelector().getAsString()));
2717 Method.addBitCast(FnPtr, IMPTy);
2719 Method.finishAndAddTo(MethodArray);
2721 MethodArray.finishAndAddTo(MethodList);
2724 return MethodList.finishAndCreateGlobal(
".objc_method_list",
2729 llvm::Constant *CGObjCGNU::
2735 if (IvarNames.empty())
2741 auto IvarList = Builder.beginStruct();
2742 IvarList.addInt(IntTy, (
int)IvarNames.size());
2745 llvm::StructType *ObjCIvarTy =
2746 llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, IntTy);
2749 auto Ivars = IvarList.beginArray(ObjCIvarTy);
2750 for (
unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {
2751 auto Ivar = Ivars.beginStruct(ObjCIvarTy);
2752 Ivar.
add(IvarNames[i]);
2753 Ivar.
add(IvarTypes[i]);
2754 Ivar.
add(IvarOffsets[i]);
2755 Ivar.finishAndAddTo(Ivars);
2757 Ivars.finishAndAddTo(IvarList);
2760 return IvarList.finishAndCreateGlobal(
".objc_ivar_list",
2765 llvm::Constant *CGObjCGNU::GenerateClassStructure(
2766 llvm::Constant *MetaClass,
2767 llvm::Constant *SuperClass,
2770 llvm::Constant *Version,
2771 llvm::Constant *InstanceSize,
2772 llvm::Constant *IVars,
2773 llvm::Constant *Methods,
2774 llvm::Constant *Protocols,
2775 llvm::Constant *IvarOffsets,
2776 llvm::Constant *Properties,
2777 llvm::Constant *StrongIvarBitmap,
2778 llvm::Constant *WeakIvarBitmap,
2787 llvm::StructType *ClassTy = llvm::StructType::get(
2804 IvarOffsets->getType(),
2805 Properties->getType(),
2811 auto Elements = Builder.beginStruct(ClassTy);
2816 Elements.addBitCast(MetaClass, PtrToInt8Ty);
2818 Elements.add(SuperClass);
2820 Elements.add(MakeConstantString(Name,
".class_name"));
2822 Elements.addInt(LongTy, 0);
2824 Elements.addInt(LongTy, info);
2827 llvm::DataLayout td(&TheModule);
2828 Elements.addInt(LongTy,
2829 td.getTypeSizeInBits(ClassTy) /
2832 Elements.add(InstanceSize);
2834 Elements.add(IVars);
2836 Elements.add(Methods);
2839 Elements.add(NULLPtr);
2841 Elements.add(NULLPtr);
2843 Elements.add(NULLPtr);
2845 Elements.addBitCast(Protocols, PtrTy);
2847 Elements.add(NULLPtr);
2849 Elements.addInt(LongTy, ClassABIVersion);
2851 Elements.add(IvarOffsets);
2853 Elements.add(Properties);
2855 Elements.add(StrongIvarBitmap);
2857 Elements.add(WeakIvarBitmap);
2862 std::string ClassSym((isMeta ?
"_OBJC_METACLASS_":
"_OBJC_CLASS_") +
2864 llvm::GlobalVariable *ClassRef = TheModule.getNamedGlobal(ClassSym);
2865 llvm::Constant *Class =
2866 Elements.finishAndCreateGlobal(ClassSym, CGM.
getPointerAlign(),
false,
2869 ClassRef->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(Class,
2870 ClassRef->getType()));
2871 ClassRef->removeFromParent();
2872 Class->setName(ClassSym);
2877 llvm::Constant *CGObjCGNU::
2880 llvm::StructType *ObjCMethodDescTy =
2881 llvm::StructType::get(CGM.
getLLVMContext(), { PtrToInt8Ty, PtrToInt8Ty });
2884 auto MethodList = Builder.beginStruct();
2885 MethodList.addInt(IntTy, Methods.size());
2886 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
2887 for (
auto *M : Methods) {
2888 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
2890 Method.
add(MakeConstantString(Context.getObjCEncodingForMethodDecl(M)));
2891 Method.finishAndAddTo(MethodArray);
2893 MethodArray.finishAndAddTo(MethodList);
2894 return MethodList.finishAndCreateGlobal(
".objc_method_list",
2903 auto ProtocolList = Builder.beginStruct();
2904 ProtocolList.add(NULLPtr);
2905 ProtocolList.addInt(LongTy, Protocols.size());
2907 auto Elements = ProtocolList.beginArray(PtrToInt8Ty);
2908 for (
const std::string *iter = Protocols.begin(), *endIter = Protocols.end();
2909 iter != endIter ; iter++) {
2910 llvm::Constant *protocol =
nullptr;
2911 llvm::StringMap<llvm::Constant*>::iterator value =
2912 ExistingProtocols.find(*iter);
2913 if (value == ExistingProtocols.end()) {
2914 protocol = GenerateEmptyProtocol(*iter);
2916 protocol = value->getValue();
2918 Elements.addBitCast(protocol, PtrToInt8Ty);
2920 Elements.finishAndAddTo(ProtocolList);
2921 return ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
2936 CGObjCGNU::GenerateEmptyProtocol(StringRef ProtocolName) {
2937 llvm::Constant *ProtocolList = GenerateProtocolList({});
2938 llvm::Constant *MethodList = GenerateProtocolMethodList({});
2939 MethodList = llvm::ConstantExpr::getBitCast(MethodList, PtrToInt8Ty);
2943 auto Elements = Builder.beginStruct();
2947 Elements.add(llvm::ConstantExpr::getIntToPtr(
2948 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
2950 Elements.add(MakeConstantString(ProtocolName,
".objc_protocol_name"));
2951 Elements.add(ProtocolList);
2952 Elements.add(MethodList);
2953 Elements.add(MethodList);
2954 Elements.add(MethodList);
2955 Elements.add(MethodList);
2956 Elements.add(NULLPtr);
2957 Elements.add(NULLPtr);
2958 return Elements.finishAndCreateGlobal(SymbolForProtocol(ProtocolName),
2971 Protocols.push_back(PI->getNameAsString());
2975 if (I->isOptional())
2976 OptionalInstanceMethods.push_back(I);
2978 InstanceMethods.push_back(I);
2983 if (I->isOptional())
2984 OptionalClassMethods.push_back(I);
2986 ClassMethods.push_back(I);
2988 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
2989 llvm::Constant *InstanceMethodList =
2990 GenerateProtocolMethodList(InstanceMethods);
2991 llvm::Constant *ClassMethodList =
2992 GenerateProtocolMethodList(ClassMethods);
2993 llvm::Constant *OptionalInstanceMethodList =
2994 GenerateProtocolMethodList(OptionalInstanceMethods);
2995 llvm::Constant *OptionalClassMethodList =
2996 GenerateProtocolMethodList(OptionalClassMethods);
3004 llvm::Constant *PropertyList =
3005 GeneratePropertyList(
nullptr, PD,
false,
false);
3006 llvm::Constant *OptionalPropertyList =
3007 GeneratePropertyList(
nullptr, PD,
false,
true);
3014 auto Elements = Builder.beginStruct();
3016 llvm::ConstantExpr::getIntToPtr(
3017 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3018 Elements.add(MakeConstantString(ProtocolName));
3019 Elements.add(ProtocolList);
3020 Elements.add(InstanceMethodList);
3021 Elements.add(ClassMethodList);
3022 Elements.add(OptionalInstanceMethodList);
3023 Elements.add(OptionalClassMethodList);
3024 Elements.add(PropertyList);
3025 Elements.add(OptionalPropertyList);
3026 ExistingProtocols[ProtocolName] =
3027 llvm::ConstantExpr::getBitCast(
3028 Elements.finishAndCreateGlobal(
".objc_protocol", CGM.
getPointerAlign()),
3031 void CGObjCGNU::GenerateProtocolHolderCategory() {
3035 auto Elements = Builder.beginStruct();
3037 const std::string ClassName =
"__ObjC_Protocol_Holder_Ugly_Hack";
3038 const std::string CategoryName =
"AnotherHack";
3039 Elements.add(MakeConstantString(CategoryName));
3040 Elements.add(MakeConstantString(ClassName));
3042 Elements.addBitCast(GenerateMethodList(
3043 ClassName, CategoryName, {},
false), PtrTy);
3045 Elements.addBitCast(GenerateMethodList(
3046 ClassName, CategoryName, {},
true), PtrTy);
3050 auto ProtocolList = ProtocolListBuilder.beginStruct();
3051 ProtocolList.add(NULLPtr);
3052 ProtocolList.addInt(LongTy, ExistingProtocols.size());
3053 auto ProtocolElements = ProtocolList.beginArray(PtrTy);
3054 for (
auto iter = ExistingProtocols.begin(), endIter = ExistingProtocols.end();
3055 iter != endIter ; iter++) {
3056 ProtocolElements.addBitCast(iter->getValue(), PtrTy);
3058 ProtocolElements.finishAndAddTo(ProtocolList);
3059 Elements.addBitCast(
3060 ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
3063 Categories.push_back(llvm::ConstantExpr::getBitCast(
3080 int bitCount = bits.size();
3082 if (bitCount < ptrBits) {
3084 for (
int i=0 ; i<bitCount ; ++i) {
3085 if (bits[i]) val |= 1ULL<<(i+1);
3087 return llvm::ConstantInt::get(IntPtrTy, val);
3091 while (v < bitCount) {
3093 for (
int i=0 ; (i<32) && (v<bitCount) ; ++i) {
3094 if (bits[v]) word |= 1<<i;
3097 values.push_back(llvm::ConstantInt::get(Int32Ty, word));
3101 auto fields = builder.beginStruct();
3102 fields.addInt(Int32Ty, values.size());
3103 auto array = fields.beginArray();
3104 for (
auto v : values) array.add(v);
3105 array.finishAndAddTo(fields);
3107 llvm::Constant *GS =
3109 llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy);
3113 llvm::Constant *CGObjCGNU::GenerateCategoryProtocolList(
const 3118 return GenerateProtocolList(Protocols);
3130 auto Elements = Builder.beginStruct();
3131 Elements.add(MakeConstantString(CategoryName));
3132 Elements.add(MakeConstantString(ClassName));
3135 InstanceMethods.insert(InstanceMethods.begin(), OCD->
instmeth_begin(),
3137 Elements.addBitCast(
3138 GenerateMethodList(ClassName, CategoryName, InstanceMethods,
false),
3145 Elements.addBitCast(
3146 GenerateMethodList(ClassName, CategoryName, ClassMethods,
true),
3149 Elements.addBitCast(GenerateCategoryProtocolList(CatDecl), PtrTy);
3155 Elements.addBitCast(GeneratePropertyList(OCD, Category,
false), PtrTy);
3157 Elements.addBitCast(GeneratePropertyList(OCD, Category,
true), PtrTy);
3159 Elements.addNullPointer(PtrTy);
3160 Elements.addNullPointer(PtrTy);
3164 Categories.push_back(llvm::ConstantExpr::getBitCast(
3165 Elements.finishAndCreateGlobal(
3166 std::string(
".objc_category_")+ClassName+CategoryName,
3171 llvm::Constant *CGObjCGNU::GeneratePropertyList(
const Decl *Container,
3173 bool isClassProperty,
3174 bool protocolOptionalProperties) {
3177 llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
3178 bool isProtocol = isa<ObjCProtocolDecl>(OCD);
3181 std::function<void(const ObjCProtocolDecl *Proto)> collectProtocolProperties
3183 for (
const auto *
P : Proto->protocols())
3184 collectProtocolProperties(
P);
3186 if (isClassProperty != PD->isClassProperty())
3190 if (!isProtocol && !Context.getObjCPropertyImplDeclForPropertyDecl(PD, Container))
3194 Properties.push_back(PD);
3201 if (isClassProperty != PD->isClassProperty())
3204 Properties.push_back(PD);
3208 if (isClassProperty != PD->isClassProperty())
3212 if (isProtocol && (protocolOptionalProperties != PD->isOptional()))
3219 Properties.push_back(PD);
3224 collectProtocolProperties(
P);
3226 for (
const auto *
P : CD->protocols())
3227 collectProtocolProperties(
P);
3229 auto numProperties = Properties.size();
3231 if (numProperties == 0)
3235 auto propertyList = builder.beginStruct();
3236 auto properties = PushPropertyListHeader(propertyList, numProperties);
3240 for (
auto *property : Properties) {
3241 bool isSynthesized =
false;
3244 auto *propertyImpl = Context.getObjCPropertyImplDeclForPropertyDecl(property, Container);
3246 isSynthesized = (propertyImpl->getPropertyImplementation() ==
3248 isDynamic = (propertyImpl->getPropertyImplementation() ==
3252 PushProperty(properties, property, Container, isSynthesized, isDynamic);
3254 properties.finishAndAddTo(propertyList);
3256 return propertyList.finishAndCreateGlobal(
".objc_property_list",
3274 std::string SuperClassName;
3275 if (SuperClassDecl) {
3277 EmitClassRef(SuperClassName);
3287 std::string classSymbolName =
"__objc_class_name_" + ClassName;
3288 if (
auto *symbol = TheModule.getGlobalVariable(classSymbolName)) {
3289 symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0));
3291 new llvm::GlobalVariable(TheModule, LongTy,
false,
3293 llvm::ConstantInt::get(LongTy, 0),
3309 auto IvarOffsetValues = IvarOffsetBuilder.beginArray(PtrToIntTy);
3313 int superInstanceSize = !SuperClassDecl ? 0 :
3318 instanceSize = 0 - (instanceSize - superInstanceSize);
3324 IvarNames.push_back(MakeConstantString(IVD->getNameAsString()));
3326 std::string TypeStr;
3328 IvarTypes.push_back(MakeConstantString(TypeStr));
3329 IvarAligns.push_back(llvm::ConstantInt::get(IntTy,
3333 uint64_t Offset = BaseOffset;
3335 Offset = BaseOffset - superInstanceSize;
3337 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
3339 std::string OffsetName =
"__objc_ivar_offset_value_" + ClassName +
"." +
3340 IVD->getNameAsString();
3342 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
3344 OffsetVar->setInitializer(OffsetValue);
3350 OffsetVar =
new llvm::GlobalVariable(TheModule, Int32Ty,
3352 OffsetValue, OffsetName);
3353 IvarOffsets.push_back(OffsetValue);
3354 IvarOffsetValues.add(OffsetVar);
3356 IvarOwnership.push_back(lt);
3359 StrongIvars.push_back(
true);
3360 WeakIvars.push_back(
false);
3363 StrongIvars.push_back(
false);
3364 WeakIvars.push_back(
true);
3367 StrongIvars.push_back(
false);
3368 WeakIvars.push_back(
false);
3371 llvm::Constant *StrongIvarBitmap = MakeBitField(StrongIvars);
3372 llvm::Constant *WeakIvarBitmap = MakeBitField(WeakIvars);
3373 llvm::GlobalVariable *IvarOffsetArray =
3374 IvarOffsetValues.finishAndCreateGlobal(
".ivar.offsets",
3379 InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
3389 if (propertyImpl->getPropertyImplementation() ==
3394 InstanceMethods.push_back(accessor);
3400 llvm::Constant *Properties = GeneratePropertyList(OID, ClassDecl);
3404 for (
const auto *I : ClassDecl->
protocols())
3405 Protocols.push_back(I->getNameAsString());
3408 llvm::Constant *SuperClass;
3409 if (!SuperClassName.empty()) {
3410 SuperClass = MakeConstantString(SuperClassName,
".super_class_name");
3412 SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty);
3417 llvm::Constant *MethodList = GenerateMethodList(ClassName,
"",
3418 InstanceMethods,
false);
3419 llvm::Constant *ClassMethodList = GenerateMethodList(ClassName,
"",
3420 ClassMethods,
true);
3421 llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
3422 IvarOffsets, IvarAligns, IvarOwnership);
3434 llvm::Constant *offsetPointerIndexes[] = {Zeros[0],
3435 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 2 : 1),
nullptr,
3436 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 3 : 2) };
3438 unsigned ivarIndex = 0;
3441 const std::string Name = GetIVarOffsetVariableName(ClassDecl, IVD);
3442 offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, ivarIndex);
3444 llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr(
3445 cast<llvm::GlobalVariable>(IvarList)->getValueType(), IvarList,
3446 offsetPointerIndexes);
3448 llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name);
3450 offset->setInitializer(offsetValue);
3457 new llvm::GlobalVariable(TheModule, offsetValue->getType(),
3461 llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0);
3464 llvm::Constant *MetaClassStruct = GenerateClassStructure(
3465 NULLPtr, NULLPtr, 0x12L, ClassName.c_str(),
nullptr, Zeros[0],
3466 NULLPtr, ClassMethodList, NULLPtr, NULLPtr,
3467 GeneratePropertyList(OID, ClassDecl,
true), ZeroPtr, ZeroPtr,
true);
3472 llvm::Constant *ClassStruct = GenerateClassStructure(
3473 MetaClassStruct, SuperClass, 0x11L, ClassName.c_str(),
nullptr,
3474 llvm::ConstantInt::get(LongTy, instanceSize), IvarList, MethodList,
3475 GenerateProtocolList(Protocols), IvarOffsetArray, Properties,
3476 StrongIvarBitmap, WeakIvarBitmap);
3481 if (ClassPtrAlias) {
3482 ClassPtrAlias->replaceAllUsesWith(
3483 llvm::ConstantExpr::getBitCast(ClassStruct, IdTy));
3484 ClassPtrAlias->eraseFromParent();
3485 ClassPtrAlias =
nullptr;
3487 if (MetaClassPtrAlias) {
3488 MetaClassPtrAlias->replaceAllUsesWith(
3489 llvm::ConstantExpr::getBitCast(MetaClassStruct, IdTy));
3490 MetaClassPtrAlias->eraseFromParent();
3491 MetaClassPtrAlias =
nullptr;
3495 ClassStruct = llvm::ConstantExpr::getBitCast(ClassStruct, PtrToInt8Ty);
3496 Classes.push_back(ClassStruct);
3499 llvm::Function *CGObjCGNU::ModuleInitFunction() {
3501 if (Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
3502 ExistingProtocols.empty() && SelectorTable.empty())
3506 GenerateProtocolHolderCategory();
3508 llvm::StructType *selStructTy =
3509 dyn_cast<llvm::StructType>(SelectorTy->getElementType());
3513 { PtrToInt8Ty, PtrToInt8Ty });
3514 selStructPtrTy = llvm::PointerType::getUnqual(selStructTy);
3518 llvm::Constant *statics = NULLPtr;
3519 if (!ConstantStrings.empty()) {
3520 llvm::GlobalVariable *fileStatics = [&] {
3522 auto staticsStruct = builder.beginStruct();
3525 if (stringClass.empty()) stringClass =
"NXConstantString";
3526 staticsStruct.add(MakeConstantString(stringClass,
3527 ".objc_static_class_name"));
3529 auto array = staticsStruct.beginArray();
3530 array.addAll(ConstantStrings);
3532 array.finishAndAddTo(staticsStruct);
3534 return staticsStruct.finishAndCreateGlobal(
".objc_statics",
3539 auto allStaticsArray = builder.beginArray(fileStatics->getType());
3540 allStaticsArray.add(fileStatics);
3541 allStaticsArray.addNullPointer(fileStatics->getType());
3543 statics = allStaticsArray.finishAndCreateGlobal(
".objc_statics_ptr",
3545 statics = llvm::ConstantExpr::getBitCast(statics, PtrTy);
3551 unsigned selectorCount;
3554 llvm::GlobalVariable *selectorList = [&] {
3556 auto selectors = builder.beginArray(selStructTy);
3557 auto &table = SelectorTable;
3558 std::vector<Selector> allSelectors;
3559 for (
auto &entry : table)
3560 allSelectors.push_back(entry.first);
3561 llvm::sort(allSelectors);
3563 for (
auto &untypedSel : allSelectors) {
3564 std::string selNameStr = untypedSel.getAsString();
3565 llvm::Constant *selName = ExportUniqueString(selNameStr,
".objc_sel_name");
3567 for (TypedSelector &sel : table[untypedSel]) {
3568 llvm::Constant *selectorTypeEncoding = NULLPtr;
3569 if (!sel.first.empty())
3570 selectorTypeEncoding =
3571 MakeConstantString(sel.first,
".objc_sel_types");
3573 auto selStruct = selectors.beginStruct(selStructTy);
3574 selStruct.add(selName);
3575 selStruct.add(selectorTypeEncoding);
3576 selStruct.finishAndAddTo(selectors);
3579 selectorAliases.push_back(sel.second);
3584 selectorCount = selectors.size();
3590 auto selStruct = selectors.beginStruct(selStructTy);
3591 selStruct.add(NULLPtr);
3592 selStruct.add(NULLPtr);
3593 selStruct.finishAndAddTo(selectors);
3595 return selectors.finishAndCreateGlobal(
".objc_selector_list",
3600 for (
unsigned i = 0; i < selectorCount; ++i) {
3601 llvm::Constant *idxs[] = {
3603 llvm::ConstantInt::get(Int32Ty, i)
3606 llvm::Constant *selPtr = llvm::ConstantExpr::getGetElementPtr(
3607 selectorList->getValueType(), selectorList, idxs);
3610 selPtr = llvm::ConstantExpr::getBitCast(selPtr, SelectorTy);
3611 selectorAliases[i]->replaceAllUsesWith(selPtr);
3612 selectorAliases[i]->eraseFromParent();
3615 llvm::GlobalVariable *symtab = [&] {
3617 auto symtab = builder.beginStruct();
3620 symtab.addInt(LongTy, selectorCount);
3622 symtab.addBitCast(selectorList, selStructPtrTy);
3625 symtab.addInt(CGM.
Int16Ty, Classes.size());
3627 symtab.addInt(CGM.
Int16Ty, Categories.size());
3630 auto classList = symtab.beginArray(PtrToInt8Ty);
3631 classList.addAll(Classes);
3632 classList.addAll(Categories);
3634 classList.add(statics);
3635 classList.add(NULLPtr);
3636 classList.finishAndAddTo(symtab);
3644 llvm::Constant *module = [&] {
3646 LongTy, LongTy, PtrToInt8Ty, symtab->getType(), IntTy
3648 llvm::StructType *moduleTy =
3650 makeArrayRef(moduleEltTys).drop_back(
unsigned(RuntimeVersion < 10)));
3653 auto module = builder.beginStruct(moduleTy);
3655 module.addInt(LongTy, RuntimeVersion);
3657 module.addInt(LongTy, CGM.
getDataLayout().getTypeStoreSize(moduleTy));
3664 module.add(MakeConstantString(path,
".objc_source_file_name"));
3667 if (RuntimeVersion >= 10) {
3670 module.addInt(IntTy, 2);
3674 module.addInt(IntTy, 1);
3676 module.addInt(IntTy, 0);
3679 module.addInt(IntTy, 1);
3690 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
3693 llvm::BasicBlock *EntryBB =
3696 Builder.SetInsertPoint(EntryBB);
3698 llvm::FunctionType *FT =
3699 llvm::FunctionType::get(Builder.getVoidTy(), module->getType(),
true);
3701 Builder.CreateCall(Register, module);
3703 if (!ClassAliases.empty()) {
3704 llvm::Type *ArgTypes[2] = {PtrTy, PtrToInt8Ty};
3705 llvm::FunctionType *RegisterAliasTy =
3706 llvm::FunctionType::get(Builder.getVoidTy(),
3710 llvm::GlobalValue::ExternalWeakLinkage,
"class_registerAlias_np",
3712 llvm::BasicBlock *AliasBB =
3714 llvm::BasicBlock *NoAliasBB =
3718 llvm::Value *HasRegisterAlias = Builder.CreateICmpNE(RegisterAlias,
3719 llvm::Constant::getNullValue(RegisterAlias->getType()));
3720 Builder.CreateCondBr(HasRegisterAlias, AliasBB, NoAliasBB);
3723 Builder.SetInsertPoint(AliasBB);
3725 for (std::vector<ClassAliasPair>::iterator iter = ClassAliases.begin();
3726 iter != ClassAliases.end(); ++iter) {
3727 llvm::Constant *TheClass =
3728 TheModule.getGlobalVariable(
"_OBJC_CLASS_" + iter->first,
true);
3730 TheClass = llvm::ConstantExpr::getBitCast(TheClass, PtrTy);
3731 Builder.CreateCall(RegisterAlias,
3732 {TheClass, MakeConstantString(iter->second)});
3736 Builder.CreateBr(NoAliasBB);
3739 Builder.SetInsertPoint(NoAliasBB);
3741 Builder.CreateRetVoid();
3743 return LoadFunction;
3746 llvm::Function *CGObjCGNU::GenerateMethod(
const ObjCMethodDecl *OMD,
3750 StringRef CategoryName = OCD ? OCD->
getName() :
"";
3751 StringRef ClassName = CD->
getName();
3756 llvm::FunctionType *MethodTy =
3758 std::string FunctionName = SymbolNameForMethod(ClassName, CategoryName,
3759 MethodName, isClassMethod);
3761 llvm::Function *Method
3769 llvm::Constant *CGObjCGNU::GetPropertyGetFunction() {
3770 return GetPropertyFn;
3773 llvm::Constant *CGObjCGNU::GetPropertySetFunction() {
3774 return SetPropertyFn;
3777 llvm::Constant *CGObjCGNU::GetOptimizedPropertySetFunction(
bool atomic,
3782 llvm::Constant *CGObjCGNU::GetGetStructFunction() {
3783 return GetStructPropertyFn;
3786 llvm::Constant *CGObjCGNU::GetSetStructFunction() {
3787 return SetStructPropertyFn;
3790 llvm::Constant *CGObjCGNU::GetCppAtomicObjectGetFunction() {
3794 llvm::Constant *CGObjCGNU::GetCppAtomicObjectSetFunction() {
3798 llvm::Constant *CGObjCGNU::EnumerationMutationFunction() {
3799 return EnumerationMutationFn;
3826 bool ClearInsertionPoint) {
3828 bool isRethrow =
false;
3832 ExceptionAsObject = Exception;
3835 "Unexpected rethrow outside @catch block.");
3839 if (isRethrow && usesSEHExceptions) {
3851 llvm::CallSite Throw =
3853 Throw.setDoesNotReturn();
3855 CGF.
Builder.CreateUnreachable();
3856 if (ClearInsertionPoint)
3857 CGF.
Builder.ClearInsertionPoint();
3863 AddrWeakObj = EnforceType(B, AddrWeakObj, PtrToIdTy);
3864 return B.CreateCall(WeakReadFn.getType(), WeakReadFn,
3871 src = EnforceType(B, src, IdTy);
3872 dst = EnforceType(B, dst, PtrToIdTy);
3873 B.CreateCall(WeakAssignFn.getType(), WeakAssignFn,
3881 src = EnforceType(B, src, IdTy);
3882 dst = EnforceType(B, dst, PtrToIdTy);
3884 assert(!threadlocal &&
"EmitObjCGlobalAssign - Threal Local API NYI");
3885 B.CreateCall(GlobalAssignFn.getType(), GlobalAssignFn,
3893 src = EnforceType(B, src, IdTy);
3894 dst = EnforceType(B, dst, IdTy);
3895 B.CreateCall(IvarAssignFn.getType(), IvarAssignFn,
3902 src = EnforceType(B, src, IdTy);
3903 dst = EnforceType(B, dst, PtrToIdTy);
3904 B.CreateCall(StrongCastAssignFn.getType(), StrongCastAssignFn,
3913 DestPtr = EnforceType(B, DestPtr, PtrTy);
3914 SrcPtr = EnforceType(B, SrcPtr, PtrTy);
3916 B.CreateCall(MemMoveFn.getType(), MemMoveFn,
3920 llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
3923 const std::string Name = GetIVarOffsetVariableName(ID, Ivar);
3927 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
3928 if (!IvarOffsetPointer)
3929 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule,
3930 llvm::Type::getInt32PtrTy(VMContext),
false,
3932 return IvarOffsetPointer;
3939 unsigned CVRQualifiers) {
3971 if (RuntimeVersion < 10 ||
3973 return CGF.
Builder.CreateZExtOrBitCast(
3976 ObjCIvarOffsetVariable(Interface, Ivar),
3980 std::string name =
"__objc_ivar_offset_value_" +
3983 llvm::Value *Offset = TheModule.getGlobalVariable(name);
3985 auto GV =
new llvm::GlobalVariable(TheModule, IntTy,
3986 false, llvm::GlobalValue::LinkOnceAnyLinkage,
3987 llvm::Constant::getNullValue(IntTy), name);
3992 if (Offset->getType() != PtrDiffTy)
3993 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
3997 return llvm::ConstantInt::get(PtrDiffTy, Offset,
true);
4003 switch (Runtime.getKind()) {
4005 if (Runtime.getVersion() >= VersionTuple(2, 0))
4006 return new CGObjCGNUstep2(CGM);
4007 return new CGObjCGNUstep(CGM);
4010 return new CGObjCGCC(CGM);
4013 return new CGObjCObjFW(CGM);
4019 llvm_unreachable(
"these runtimes are not GNU runtimes");
4021 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.
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.
CharUnits getPointerSize() const
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
Represents Objective-C's @throw statement.
const TargetInfo & getTargetInfo() const
instmeth_iterator instmeth_end() const
constexpr XRayInstrMask Function
'gcc' is the Objective-C runtime shipped with GCC, implementing a fragile Objective-C ABI ...
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::Instruction **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.
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...
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
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
const ASTRecordLayout & getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const
Get or compute information about the layout of the specified Objective-C interface.
void InitTempAlloca(Address Alloca, llvm::Value *Value)
InitTempAlloca - Provide an initial value for the given alloca which will be observable at all locati...
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Objects with "default" visibility are seen by the dynamic linker and act like normal objects...
virtual llvm::Value * EmitIvarOffset(CodeGen::CodeGenFunction &CGF, const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar)=0
MessageSendInfo getMessageSendInfo(const ObjCMethodDecl *method, QualType resultType, CallArgList &callArgs)
Compute the pointer-to-function type to which a message send should be casted in order to correctly c...
unsigned getLength() const
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
ObjCContainerDecl - Represents a container for method declarations.
const Expr * getThrowExpr() const
CharUnits - This is an opaque type for sizes expressed in character units.
CharUnits getAlignment() const
Return the alignment of this pointer.
Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void addCompilerUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.compiler.used metadata.
Represents an Objective-C protocol declaration.
CharUnits getPointerAlign() const
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
Represents an ObjC class declaration.
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface...
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
QualType getObjCProtoType() const
Retrieve the type of the Objective-C Protocol class.
std::string getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, bool Extended=false) const
Emit the encoded type for the method declaration Decl into S.
This object can be modified without requiring retains or releases.
llvm::Constant * CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false)
Create a new runtime function with the specified type and name.
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
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
ArrayBuilder beginArray(llvm::Type *eltTy=nullptr)
CGBlockInfo - Information to generate a block literal.
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
This represents one expression.
known_extensions_range known_extensions() const
'macosx' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the non-fragile AB...
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
std::string getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD, const Decl *Container) const
getObjCEncodingForPropertyDecl - Return the encoded type for this method declaration.
virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD)=0
Register an class alias.
llvm::PointerType * getType() const
Return the type of the pointer value.
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
DeclContext * getDeclContext()
uint32_t getCodeUnit(size_t i) const
Represents Objective-C's @synchronized statement.
ObjCInterfaceDecl * getSuperClass() const
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
void EmitAtSynchronizedStmt(CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S, llvm::Function *syncEnterFn, llvm::Function *syncExitFn)
Emits an @synchronize() statement, using the syncEnterFn and syncExitFn arguments as the functions ca...
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
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...
llvm::CallSite EmitRuntimeCallOrInvoke(llvm::Value *callee, ArrayRef< llvm::Value *> args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
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)
The basic abstraction for the target Objective-C runtime.
Address CreateStructGEP(Address Addr, unsigned Index, CharUnits Offset, const llvm::Twine &Name="")
llvm::LoadInst * CreateAlignedLoad(llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
FileID getMainFileID() const
Returns the FileID of the main source file.
llvm::Constant * getPointer() const
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
const ObjCInterfaceDecl * getContainingInterface() const
Return the class interface that this ivar is logically contained in; this is either the interface whe...
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::Module & getModule() const
const ObjCInterfaceDecl * getClassInterface() const
'ios' is the Apple-provided NeXT-derived runtime on iOS or the iOS simulator; it is always non-fragil...
Represents a pointer to an Objective C object.
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
virtual llvm::Constant * getAddrOfRTTIDescriptor(QualType Ty)=0
llvm::Type * getElementType() const
Return the type of the values stored in this address.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
This class organizes the cross-module state that is used while lowering AST types to LLVM types...
void getObjCEncodingForType(QualType T, std::string &S, const FieldDecl *Field=nullptr, QualType *NotEncodedT=nullptr) const
Emit the Objective-CC type encoding for the given type T into S.
llvm::PointerType * Int8PtrTy
bool isObjCQualifiedIdType() const
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
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.
void EmitTryCatchStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S, llvm::Constant *beginCatchFn, llvm::Constant *endCatchFn, llvm::Constant *exceptionRethrowFn)
Emits a try / catch statement.
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)
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.
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