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);
283 Fields.addInt(IntTy, count);
286 llvm::DataLayout td(&TheModule);
287 Fields.addInt(IntTy, td.getTypeSizeInBits(PropertyMetadataTy) /
298 bool isSynthesized=
true,
bool 300 auto Fields = PropertiesArray.
beginStruct(PropertyMetadataTy);
302 Fields.add(MakePropertyEncodingString(property, OCD));
303 PushPropertyAttributes(Fields, property, isSynthesized,
isDynamic);
307 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
308 Fields.add(MakeConstantString(accessor->getSelector().getAsString()));
309 Fields.add(TypeEncoding);
324 if (V->getType() == Ty)
return V;
328 if (V.
getType() == Ty)
return V;
333 llvm::Constant *Zeros[2];
335 llvm::Constant *NULLPtr;
337 llvm::LLVMContext &VMContext;
345 llvm::GlobalAlias *ClassPtrAlias;
350 llvm::GlobalAlias *MetaClassPtrAlias;
352 std::vector<llvm::Constant*> Classes;
354 std::vector<llvm::Constant*> Categories;
357 std::vector<llvm::Constant*> ConstantStrings;
361 llvm::StringMap<llvm::Constant*> ObjCStrings;
363 llvm::StringMap<llvm::Constant*> ExistingProtocols;
369 typedef std::pair<std::string, llvm::GlobalAlias*> TypedSelector;
373 typedef llvm::DenseMap<Selector, SmallVector<TypedSelector, 2> >
381 Selector RetainSel, ReleaseSel, AutoreleaseSel;
385 LazyRuntimeFunction IvarAssignFn, StrongCastAssignFn, MemMoveFn, WeakReadFn,
386 WeakAssignFn, GlobalAssignFn;
388 typedef std::pair<std::string, std::string> ClassAliasPair;
390 std::vector<ClassAliasPair> ClassAliases;
394 LazyRuntimeFunction ExceptionThrowFn;
397 LazyRuntimeFunction ExceptionReThrowFn;
400 LazyRuntimeFunction EnterCatchFn;
403 LazyRuntimeFunction ExitCatchFn;
405 LazyRuntimeFunction SyncEnterFn;
407 LazyRuntimeFunction SyncExitFn;
412 LazyRuntimeFunction EnumerationMutationFn;
415 LazyRuntimeFunction GetPropertyFn;
418 LazyRuntimeFunction SetPropertyFn;
420 LazyRuntimeFunction GetStructPropertyFn;
422 LazyRuntimeFunction SetStructPropertyFn;
434 const int ProtocolVersion;
437 const int ClassABIVersion;
453 llvm::Constant *GenerateMethodList(StringRef ClassName,
454 StringRef CategoryName,
456 bool isClassMethodList);
461 virtual llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName);
465 llvm::Constant *GeneratePropertyList(
const Decl *Container,
467 bool isClassProperty=
false,
468 bool protocolOptionalProperties=
false);
478 void GenerateProtocolHolderCategory();
481 llvm::Constant *GenerateClassStructure(
482 llvm::Constant *MetaClass,
483 llvm::Constant *SuperClass,
486 llvm::Constant *Version,
487 llvm::Constant *InstanceSize,
488 llvm::Constant *IVars,
489 llvm::Constant *Methods,
490 llvm::Constant *Protocols,
491 llvm::Constant *IvarOffsets,
492 llvm::Constant *Properties,
493 llvm::Constant *StrongIvarBitmap,
494 llvm::Constant *WeakIvarBitmap,
499 virtual llvm::Constant *GenerateProtocolMethodList(
503 void EmitProtocolMethodList(T &&Methods, llvm::Constant *&Required,
507 for (
const auto *I : Methods)
509 OptionalMethods.push_back(I);
511 RequiredMethods.push_back(I);
512 Required = GenerateProtocolMethodList(RequiredMethods);
513 Optional = GenerateProtocolMethodList(OptionalMethods);
519 const std::string &TypeEncoding);
535 void EmitClassRef(
const std::string &className);
539 const std::string &Name,
bool isWeak);
548 MessageSendInfo &MSI) = 0;
556 MessageSendInfo &MSI) = 0;
573 unsigned protocolClassVersion,
unsigned classABI=1);
596 virtual llvm::Constant *GetConstantSelector(
Selector Sel,
597 const std::string &TypeEncoding) {
598 llvm_unreachable(
"Runtime unable to generate constant selector");
604 llvm::Constant *GetEHType(
QualType T)
override;
614 llvm::Function *ModuleInitFunction()
override;
615 llvm::Constant *GetPropertyGetFunction()
override;
616 llvm::Constant *GetPropertySetFunction()
override;
617 llvm::Constant *GetOptimizedPropertySetFunction(
bool atomic,
619 llvm::Constant *GetSetStructFunction()
override;
620 llvm::Constant *GetGetStructFunction()
override;
621 llvm::Constant *GetCppAtomicObjectGetFunction()
override;
622 llvm::Constant *GetCppAtomicObjectSetFunction()
override;
623 llvm::Constant *EnumerationMutationFunction()
override;
631 bool ClearInsertionPoint=
true)
override;
638 bool threadlocal=
false)
override;
648 unsigned CVRQualifiers)
override;
675 class CGObjCGCC :
public CGObjCGNU {
678 LazyRuntimeFunction MsgLookupFn;
682 LazyRuntimeFunction MsgLookupSuperFn;
687 MessageSendInfo &MSI)
override {
690 EnforceType(Builder, Receiver, IdTy),
691 EnforceType(Builder, cmd, SelectorTy) };
693 imp->setMetadata(msgSendMDKind, node);
694 return imp.getInstruction();
700 llvm::Value *lookupArgs[] = {EnforceType(Builder, ObjCSuper,
701 PtrToObjCSuperTy).getPointer(), cmd};
708 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
710 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
711 PtrToObjCSuperTy, SelectorTy);
716 class CGObjCGNUstep :
public CGObjCGNU {
719 LazyRuntimeFunction SlotLookupFn;
724 LazyRuntimeFunction SlotLookupSuperFn;
726 LazyRuntimeFunction SetPropertyAtomic;
728 LazyRuntimeFunction SetPropertyAtomicCopy;
730 LazyRuntimeFunction SetPropertyNonAtomic;
732 LazyRuntimeFunction SetPropertyNonAtomicCopy;
735 LazyRuntimeFunction CxxAtomicObjectGetFn;
738 LazyRuntimeFunction CxxAtomicObjectSetFn;
744 llvm::Constant *GetEHType(
QualType T)
override;
749 MessageSendInfo &MSI)
override {
751 llvm::Function *LookupFn = SlotLookupFn;
763 self = llvm::ConstantPointerNull::get(IdTy);
767 LookupFn->addParamAttr(0, llvm::Attribute::NoCapture);
770 EnforceType(Builder, ReceiverPtr.
getPointer(), PtrToIdTy),
771 EnforceType(Builder, cmd, SelectorTy),
772 EnforceType(Builder,
self, IdTy) };
774 slot.setOnlyReadsMemory();
775 slot->setMetadata(msgSendMDKind, node);
784 Receiver = Builder.
CreateLoad(ReceiverPtr,
true);
790 MessageSendInfo &MSI)
override {
794 llvm::CallInst *slot =
796 slot->setOnlyReadsMemory();
803 CGObjCGNUstep(
CodeGenModule &Mod) : CGObjCGNUstep(Mod, 9, 3, 1) {}
804 CGObjCGNUstep(
CodeGenModule &Mod,
unsigned ABI,
unsigned ProtocolABI,
806 CGObjCGNU(Mod, ABI, ProtocolABI, ClassABI) {
809 llvm::StructType *SlotStructTy =
810 llvm::StructType::get(PtrTy, PtrTy, PtrTy, IntTy, IMPTy);
811 SlotTy = llvm::PointerType::getUnqual(SlotStructTy);
813 SlotLookupFn.init(&CGM,
"objc_msg_lookup_sender", SlotTy, PtrToIdTy,
816 SlotLookupSuperFn.init(&CGM,
"objc_slot_lookup_super", SlotTy,
817 PtrToObjCSuperTy, SelectorTy);
819 if (usesSEHExceptions) {
820 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
822 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy);
824 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
826 EnterCatchFn.init(&CGM,
"__cxa_begin_catch", PtrTy, PtrTy);
828 ExitCatchFn.init(&CGM,
"__cxa_end_catch", VoidTy);
830 ExceptionReThrowFn.init(&CGM,
"_Unwind_Resume_or_Rethrow", VoidTy,
832 }
else if (R.
getVersion() >= VersionTuple(1, 7)) {
833 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
835 EnterCatchFn.init(&CGM,
"objc_begin_catch", IdTy, PtrTy);
837 ExitCatchFn.init(&CGM,
"objc_end_catch", VoidTy);
839 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy, PtrTy);
841 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
842 SetPropertyAtomic.init(&CGM,
"objc_setProperty_atomic", VoidTy, IdTy,
843 SelectorTy, IdTy, PtrDiffTy);
844 SetPropertyAtomicCopy.init(&CGM,
"objc_setProperty_atomic_copy", VoidTy,
845 IdTy, SelectorTy, IdTy, PtrDiffTy);
846 SetPropertyNonAtomic.init(&CGM,
"objc_setProperty_nonatomic", VoidTy,
847 IdTy, SelectorTy, IdTy, PtrDiffTy);
848 SetPropertyNonAtomicCopy.init(&CGM,
"objc_setProperty_nonatomic_copy",
849 VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy);
852 CxxAtomicObjectSetFn.init(&CGM,
"objc_setCppObjectAtomic", VoidTy, PtrTy,
856 CxxAtomicObjectGetFn.init(&CGM,
"objc_getCppObjectAtomic", VoidTy, PtrTy,
860 llvm::Constant *GetCppAtomicObjectGetFunction()
override {
865 return CxxAtomicObjectGetFn;
868 llvm::Constant *GetCppAtomicObjectSetFunction()
override {
873 return CxxAtomicObjectSetFn;
876 llvm::Constant *GetOptimizedPropertySetFunction(
bool atomic,
877 bool copy)
override {
888 if (copy)
return SetPropertyAtomicCopy;
889 return SetPropertyAtomic;
892 return copy ? SetPropertyNonAtomicCopy : SetPropertyNonAtomic;
899 class CGObjCGNUstep2 :
public CGObjCGNUstep {
904 ClassReferenceSection,
907 ProtocolReferenceSection,
909 ConstantStringSection
911 static const char *
const SectionsBaseNames[8];
912 template<SectionKind K>
913 std::string sectionName() {
914 std::string name(SectionsBaseNames[K]);
922 LazyRuntimeFunction MsgLookupSuperFn;
926 bool EmittedProtocol =
false;
931 bool EmittedProtocolRef =
false;
935 bool EmittedClass =
false;
938 std::string SymbolForClassRef(StringRef Name,
bool isWeak) {
940 return (StringRef(
"._OBJC_WEAK_REF_CLASS_") + Name).str();
942 return (StringRef(
"._OBJC_REF_CLASS_") + Name).str();
945 std::string SymbolForClass(StringRef Name) {
946 return (StringRef(
"._OBJC_CLASS_") + Name).str();
948 void CallRuntimeFunction(
CGBuilderTy &B, StringRef FunctionName,
951 for (
auto *Arg : Args)
952 Types.push_back(Arg->getType());
953 llvm::FunctionType *FT = llvm::FunctionType::get(B.getVoidTy(), Types,
956 B.CreateCall(Fn, Args);
965 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
966 if (old != ObjCStrings.end())
974 (LiteralLength < 9) && !isNonASCII) {
980 for (
unsigned i=0 ; i<LiteralLength ; i++)
981 str |= ((uint64_t)SL->
getCodeUnit(i)) << ((64 - 4 - 3) - (i*7));
983 str |= LiteralLength << 3;
986 auto *ObjCStr = llvm::ConstantExpr::getIntToPtr(
987 llvm::ConstantInt::get(Int64Ty, str), IdTy);
988 ObjCStrings[Str] = ObjCStr;
994 if (StringClass.empty()) StringClass =
"NSConstantString";
996 std::string Sym = SymbolForClass(StringClass);
998 llvm::Constant *
isa = TheModule.getNamedGlobal(Sym);
1001 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
1003 else if (isa->getType() != PtrToIdTy)
1004 isa = llvm::ConstantExpr::getBitCast(isa, PtrToIdTy);
1017 auto Fields = Builder.beginStruct();
1024 unsigned NumU8CodeUnits = Str.size();
1029 const llvm::UTF8 *FromPtr = (
const llvm::UTF8 *)Str.data();
1030 llvm::UTF16 *ToPtr = &ToBuf[0];
1031 (void)llvm::ConvertUTF8toUTF16(&FromPtr, FromPtr + NumU8CodeUnits,
1032 &ToPtr, ToPtr + NumU8CodeUnits, llvm::strictConversion);
1033 uint32_t StringLength = ToPtr - &ToBuf[0];
1037 Fields.addInt(Int32Ty, 2);
1039 Fields.addInt(Int32Ty, StringLength);
1041 Fields.addInt(Int32Ty, StringLength * 2);
1043 Fields.addInt(Int32Ty, 0);
1045 auto Arr = llvm::makeArrayRef(&ToBuf[0], ToPtr+1);
1046 auto *
C = llvm::ConstantDataArray::get(VMContext, Arr);
1047 auto *Buffer =
new llvm::GlobalVariable(TheModule,
C->getType(),
1048 true, llvm::GlobalValue::PrivateLinkage,
C,
".str");
1049 Buffer->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1053 Fields.addInt(Int32Ty, 0);
1055 Fields.addInt(Int32Ty, Str.size());
1057 Fields.addInt(Int32Ty, Str.size());
1059 Fields.addInt(Int32Ty, 0);
1061 Fields.add(MakeConstantString(Str));
1063 std::string StringName;
1066 StringName =
".objc_str_";
1067 for (
int i=0,e=Str.size() ; i<e ; ++i) {
1068 unsigned char c = Str[i];
1081 isNamed ? StringRef(StringName) :
".objc_string",
1082 Align,
false, isNamed ? llvm::GlobalValue::LinkOnceODRLinkage
1083 : llvm::GlobalValue::PrivateLinkage);
1084 ObjCStrGV->setSection(sectionName<ConstantStringSection>());
1086 ObjCStrGV->setComdat(TheModule.getOrInsertComdat(StringName));
1089 llvm::Constant *ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStrGV, IdTy);
1090 ObjCStrings[Str] = ObjCStr;
1091 ConstantStrings.push_back(ObjCStr);
1098 bool isSynthesized=
true,
bool 1108 auto Fields = PropertiesArray.
beginStruct(PropertyMetadataTy);
1111 std::string TypeStr =
1113 Fields.add(MakeConstantString(TypeStr));
1114 std::string typeStr;
1116 Fields.add(MakeConstantString(typeStr));
1120 Fields.add(GetConstantSelector(accessor->getSelector(), TypeStr));
1122 Fields.add(NULLPtr);
1137 llvm::StructType *ObjCMethodDescTy =
1139 { PtrToInt8Ty, PtrToInt8Ty });
1148 auto MethodList = Builder.beginStruct();
1150 MethodList.addInt(IntTy, Methods.size());
1152 llvm::DataLayout td(&TheModule);
1153 MethodList.addInt(IntTy, td.getTypeSizeInBits(ObjCMethodDescTy) /
1156 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
1157 for (
auto *M : Methods) {
1158 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
1159 Method.add(CGObjCGNU::GetConstantSelector(M));
1160 Method.add(GetTypeString(Context.getObjCEncodingForMethodDecl(M,
true)));
1161 Method.finishAndAddTo(MethodArray);
1163 MethodArray.finishAndAddTo(MethodList);
1164 return MethodList.finishAndCreateGlobal(
".objc_protocol_method_list",
1169 llvm::Value *cmd, MessageSendInfo &MSI)
override {
1172 llvm::Value *lookupArgs[] = {CGObjCGNU::EnforceType(Builder, ObjCSuper,
1173 PtrToObjCSuperTy).getPointer(), cmd};
1177 llvm::GlobalVariable *GetClassVar(StringRef Name,
bool isWeak=
false) {
1178 std::string SymbolName = SymbolForClassRef(Name, isWeak);
1179 auto *ClassSymbol = TheModule.getNamedGlobal(SymbolName);
1182 ClassSymbol =
new llvm::GlobalVariable(TheModule,
1184 nullptr, SymbolName);
1190 ClassSymbol->setInitializer(
new llvm::GlobalVariable(TheModule,
1191 Int8Ty,
false, llvm::GlobalValue::ExternalWeakLinkage,
1192 nullptr, SymbolForClass(Name)));
1193 assert(ClassSymbol->getName() == SymbolName);
1197 const std::string &Name,
1198 bool isWeak)
override {
1210 switch (Ownership) {
1232 llvm_unreachable(
"Method should not be called!");
1235 llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName)
override {
1236 std::string Name = SymbolForProtocol(ProtocolName);
1237 auto *GV = TheModule.getGlobalVariable(Name);
1240 GV =
new llvm::GlobalVariable(TheModule, ProtocolTy,
false,
1244 return llvm::ConstantExpr::getBitCast(GV, ProtocolPtrTy);
1248 llvm::StringMap<llvm::Constant*> ExistingProtocolRefs;
1253 auto *&Ref = ExistingProtocolRefs[Name];
1255 auto *&
Protocol = ExistingProtocols[Name];
1257 Protocol = GenerateProtocolRef(PD);
1258 std::string RefName = SymbolForProtocolRef(Name);
1259 assert(!TheModule.getGlobalVariable(RefName));
1261 auto GV =
new llvm::GlobalVariable(TheModule, ProtocolPtrTy,
1262 false, llvm::GlobalValue::LinkOnceODRLinkage,
1263 llvm::ConstantExpr::getBitCast(Protocol, ProtocolPtrTy), RefName);
1264 GV->setComdat(TheModule.getOrInsertComdat(RefName));
1265 GV->setSection(sectionName<ProtocolReferenceSection>());
1269 EmittedProtocolRef =
true;
1274 llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(ProtocolPtrTy,
1276 llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
1279 auto ProtocolBuilder = builder.beginStruct();
1280 ProtocolBuilder.addNullPointer(PtrTy);
1281 ProtocolBuilder.addInt(SizeTy, Protocols.size());
1282 ProtocolBuilder.add(ProtocolArray);
1283 return ProtocolBuilder.finishAndCreateGlobal(
".objc_protocol_list",
1292 auto *&
Protocol = ExistingProtocols[ProtocolName];
1296 EmittedProtocol =
true;
1298 auto SymName = SymbolForProtocol(ProtocolName);
1299 auto *OldGV = TheModule.getGlobalVariable(SymName);
1309 Protocol =
new llvm::GlobalVariable(TheModule, ProtocolTy,
1317 Protocols.push_back(
1318 llvm::ConstantExpr::getBitCast(GenerateProtocolRef(PI),
1320 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
1323 llvm::Constant *InstanceMethodList, *OptionalInstanceMethodList;
1324 llvm::Constant *ClassMethodList, *OptionalClassMethodList;
1326 OptionalInstanceMethodList);
1327 EmitProtocolMethodList(PD->
class_methods(), ClassMethodList,
1328 OptionalClassMethodList);
1333 auto ProtocolBuilder = builder.beginStruct();
1334 ProtocolBuilder.add(llvm::ConstantExpr::getIntToPtr(
1335 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
1336 ProtocolBuilder.add(MakeConstantString(ProtocolName));
1337 ProtocolBuilder.add(ProtocolList);
1338 ProtocolBuilder.add(InstanceMethodList);
1339 ProtocolBuilder.add(ClassMethodList);
1340 ProtocolBuilder.add(OptionalInstanceMethodList);
1341 ProtocolBuilder.add(OptionalClassMethodList);
1343 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
false,
false));
1345 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
false,
true));
1347 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
true,
false));
1349 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
true,
true));
1351 auto *GV = ProtocolBuilder.finishAndCreateGlobal(SymName,
1353 GV->setSection(sectionName<ProtocolSection>());
1354 GV->setComdat(TheModule.getOrInsertComdat(SymName));
1356 OldGV->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(GV,
1358 OldGV->removeFromParent();
1359 GV->setName(SymName);
1364 llvm::Constant *EnforceType(llvm::Constant *Val,
llvm::Type *Ty) {
1365 if (Val->getType() == Ty)
1367 return llvm::ConstantExpr::getBitCast(Val, Ty);
1370 const std::string &TypeEncoding)
override {
1371 return GetConstantSelector(Sel, TypeEncoding);
1373 llvm::Constant *GetTypeString(llvm::StringRef TypeEncoding) {
1374 if (TypeEncoding.empty())
1376 std::string MangledTypes = TypeEncoding;
1377 std::replace(MangledTypes.begin(), MangledTypes.end(),
1379 std::string TypesVarName =
".objc_sel_types_" + MangledTypes;
1380 auto *TypesGlobal = TheModule.getGlobalVariable(TypesVarName);
1382 llvm::Constant *Init = llvm::ConstantDataArray::getString(VMContext,
1384 auto *GV =
new llvm::GlobalVariable(TheModule, Init->getType(),
1385 true, llvm::GlobalValue::LinkOnceODRLinkage, Init, TypesVarName);
1386 GV->setComdat(TheModule.getOrInsertComdat(TypesVarName));
1390 return llvm::ConstantExpr::getGetElementPtr(TypesGlobal->getValueType(),
1391 TypesGlobal, Zeros);
1393 llvm::Constant *GetConstantSelector(
Selector Sel,
1394 const std::string &TypeEncoding)
override {
1399 std::string MangledTypes = TypeEncoding;
1400 std::replace(MangledTypes.begin(), MangledTypes.end(),
1402 auto SelVarName = (StringRef(
".objc_selector_") + Sel.
getAsString() +
"_" +
1403 MangledTypes).str();
1404 if (
auto *GV = TheModule.getNamedGlobal(SelVarName))
1405 return EnforceType(GV, SelectorTy);
1407 auto SelBuilder = builder.beginStruct();
1408 SelBuilder.add(ExportUniqueString(Sel.
getAsString(),
".objc_sel_name_",
1410 SelBuilder.add(GetTypeString(TypeEncoding));
1411 auto *GV = SelBuilder.finishAndCreateGlobal(SelVarName,
1413 GV->setComdat(TheModule.getOrInsertComdat(SelVarName));
1415 GV->setSection(sectionName<SelectorSection>());
1416 auto *SelVal = EnforceType(GV, SelectorTy);
1419 llvm::StructType *emptyStruct =
nullptr;
1428 std::pair<llvm::Constant*,llvm::Constant*>
1429 GetSectionBounds(StringRef Section) {
1430 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1431 if (emptyStruct ==
nullptr) {
1433 emptyStruct->setBody({},
true);
1435 auto ZeroInit = llvm::Constant::getNullValue(emptyStruct);
1436 auto Sym = [&](StringRef Prefix, StringRef SecSuffix) {
1437 auto *Sym =
new llvm::GlobalVariable(TheModule, emptyStruct,
1439 llvm::GlobalValue::LinkOnceODRLinkage, ZeroInit, Prefix +
1442 Sym->setSection((Section + SecSuffix).str());
1443 Sym->setComdat(TheModule.getOrInsertComdat((Prefix +
1445 Sym->setAlignment(1);
1448 return { Sym(
"__start_",
"$a"), Sym(
"__stop",
"$z") };
1450 auto *Start =
new llvm::GlobalVariable(TheModule, PtrTy,
1455 auto *Stop =
new llvm::GlobalVariable(TheModule, PtrTy,
1460 return { Start, Stop };
1465 llvm::Function *ModuleInitFunction()
override {
1467 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
1468 llvm::GlobalValue::LinkOnceODRLinkage,
".objcv2_load_function",
1471 LoadFunction->setComdat(TheModule.getOrInsertComdat(
".objcv2_load_function"));
1473 llvm::BasicBlock *EntryBB =
1476 B.SetInsertPoint(EntryBB);
1478 auto InitStructBuilder = builder.beginStruct();
1479 InitStructBuilder.addInt(Int64Ty, 0);
1480 for (
auto *s : SectionsBaseNames) {
1481 auto bounds = GetSectionBounds(s);
1482 InitStructBuilder.add(bounds.first);
1483 InitStructBuilder.add(bounds.second);
1485 auto *InitStruct = InitStructBuilder.finishAndCreateGlobal(
".objc_init",
1488 InitStruct->setComdat(TheModule.getOrInsertComdat(
".objc_init"));
1490 CallRuntimeFunction(B,
"__objc_load", {InitStruct});;
1497 auto *InitVar =
new llvm::GlobalVariable(TheModule, LoadFunction->getType(),
1498 true, llvm::GlobalValue::LinkOnceAnyLinkage,
1499 LoadFunction,
".objc_ctor");
1502 assert(InitVar->getName() ==
".objc_ctor");
1508 if (CGM.
getTriple().isOSBinFormatCOFF())
1509 InitVar->setSection(
".CRT$XCLz");
1511 InitVar->setSection(
".ctors");
1513 InitVar->setComdat(TheModule.getOrInsertComdat(
".objc_ctor"));
1515 for (
auto *C : Categories) {
1516 auto *Cat = cast<llvm::GlobalVariable>(C->stripPointerCasts());
1517 Cat->setSection(sectionName<CategorySection>());
1521 StringRef Section) {
1522 auto nullBuilder = builder.beginStruct();
1523 for (
auto *F : Init)
1525 auto GV = nullBuilder.finishAndCreateGlobal(Name, CGM.
getPointerAlign(),
1526 false, llvm::GlobalValue::LinkOnceODRLinkage);
1527 GV->setSection(Section);
1528 GV->setComdat(TheModule.getOrInsertComdat(Name));
1533 for (
auto clsAlias : ClassAliases)
1534 createNullGlobal(std::string(
".objc_class_alias") +
1535 clsAlias.second, { MakeConstantString(clsAlias.second),
1536 GetClassVar(clsAlias.first) }, sectionName<ClassAliasSection>());
1541 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
1542 createNullGlobal(
".objc_null_selector", {NULLPtr, NULLPtr},
1543 sectionName<SelectorSection>());
1544 if (Categories.empty())
1545 createNullGlobal(
".objc_null_category", {NULLPtr, NULLPtr,
1546 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr},
1547 sectionName<CategorySection>());
1548 if (!EmittedClass) {
1549 createNullGlobal(
".objc_null_cls_init_ref", NULLPtr,
1550 sectionName<ClassReferenceSection>());
1551 createNullGlobal(
".objc_null_class_ref", { NULLPtr, NULLPtr },
1552 sectionName<ClassReferenceSection>());
1554 if (!EmittedProtocol)
1555 createNullGlobal(
".objc_null_protocol", {NULLPtr, NULLPtr, NULLPtr,
1556 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr,
1557 NULLPtr}, sectionName<ProtocolSection>());
1558 if (!EmittedProtocolRef)
1559 createNullGlobal(
".objc_null_protocol_ref", {NULLPtr},
1560 sectionName<ProtocolReferenceSection>());
1561 if (ClassAliases.empty())
1562 createNullGlobal(
".objc_null_class_alias", { NULLPtr, NULLPtr },
1563 sectionName<ClassAliasSection>());
1564 if (ConstantStrings.empty()) {
1565 auto i32Zero = llvm::ConstantInt::get(Int32Ty, 0);
1566 createNullGlobal(
".objc_null_constant_string", { NULLPtr, i32Zero,
1567 i32Zero, i32Zero, i32Zero, NULLPtr },
1568 sectionName<ConstantStringSection>());
1571 ConstantStrings.clear();
1580 std::string TypeEncoding;
1583 std::replace(TypeEncoding.begin(), TypeEncoding.end(),
1585 const std::string Name =
"__objc_ivar_offset_" + ID->
getNameAsString()
1593 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
1594 if (!IvarOffsetPointer)
1595 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule, IntTy,
false,
1599 if (Offset->getType() != PtrDiffTy)
1600 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
1610 auto *classNameConstant = MakeConstantString(className);
1613 auto metaclassFields = builder.beginStruct();
1615 metaclassFields.addNullPointer(PtrTy);
1617 metaclassFields.addNullPointer(PtrTy);
1619 metaclassFields.add(classNameConstant);
1621 metaclassFields.addInt(LongTy, 0);
1624 metaclassFields.addInt(LongTy, 1);
1628 metaclassFields.addInt(LongTy, 0);
1630 metaclassFields.addNullPointer(PtrTy);
1635 metaclassFields.addNullPointer(PtrTy);
1640 metaclassFields.addBitCast(
1641 GenerateMethodList(className,
"", ClassMethods,
true),
1645 metaclassFields.addNullPointer(PtrTy);
1647 metaclassFields.addNullPointer(PtrTy);
1649 metaclassFields.addNullPointer(PtrTy);
1651 metaclassFields.addNullPointer(PtrTy);
1653 metaclassFields.addNullPointer(PtrTy);
1655 metaclassFields.addNullPointer(PtrTy);
1657 metaclassFields.addNullPointer(PtrTy);
1659 metaclassFields.addInt(LongTy, 0);
1661 metaclassFields.add(GeneratePropertyList(OID, classDecl,
true));
1663 auto *metaclass = metaclassFields.finishAndCreateGlobal(
"._OBJC_METACLASS_" 1666 auto classFields = builder.beginStruct();
1668 classFields.add(metaclass);
1673 if (SuperClassDecl) {
1674 auto SuperClassName = SymbolForClass(SuperClassDecl->
getNameAsString());
1675 llvm::Constant *SuperClass = TheModule.getNamedGlobal(SuperClassName);
1678 SuperClass =
new llvm::GlobalVariable(TheModule, PtrTy,
false,
1681 classFields.add(llvm::ConstantExpr::getBitCast(SuperClass, PtrTy));
1683 classFields.addNullPointer(PtrTy);
1685 classFields.add(classNameConstant);
1687 classFields.addInt(LongTy, 0);
1690 classFields.addInt(LongTy, 0);
1692 int superInstanceSize = !SuperClassDecl ? 0 :
1696 classFields.addInt(LongTy,
1698 superInstanceSize));
1701 classFields.addNullPointer(PtrTy);
1706 llvm::DataLayout td(&TheModule);
1709 auto ivarListBuilder = b.beginStruct();
1711 ivarListBuilder.addInt(IntTy, ivar_count);
1713 llvm::StructType *ObjCIvarTy = llvm::StructType::get(
1719 ivarListBuilder.addInt(SizeTy, td.getTypeSizeInBits(ObjCIvarTy) /
1722 auto ivarArrayBuilder = ivarListBuilder.beginArray();
1726 auto ivarTy = IVD->getType();
1727 auto ivarBuilder = ivarArrayBuilder.beginStruct();
1729 ivarBuilder.add(MakeConstantString(IVD->getNameAsString()));
1731 std::string TypeStr;
1734 ivarBuilder.add(MakeConstantString(TypeStr));
1736 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
1737 uint64_t Offset = BaseOffset - superInstanceSize;
1738 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
1739 std::string OffsetName = GetIVarOffsetVariableName(classDecl, IVD);
1740 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
1742 OffsetVar->setInitializer(OffsetValue);
1744 OffsetVar =
new llvm::GlobalVariable(TheModule, IntTy,
1746 OffsetValue, OffsetName);
1747 auto ivarVisibility =
1753 OffsetVar->setVisibility(ivarVisibility);
1754 ivarBuilder.add(OffsetVar);
1756 ivarBuilder.addInt(Int32Ty,
1767 ivarBuilder.addInt(Int32Ty,
1768 (align << 3) | (1<<2) |
1769 FlagsForOwnership(ivarTy.getQualifiers().getObjCLifetime()));
1770 ivarBuilder.finishAndAddTo(ivarArrayBuilder);
1772 ivarArrayBuilder.finishAndAddTo(ivarListBuilder);
1773 auto ivarList = ivarListBuilder.finishAndCreateGlobal(
".objc_ivar_list",
1775 llvm::GlobalValue::PrivateLinkage);
1776 classFields.add(ivarList);
1780 InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
1783 if (propImpl->getPropertyImplementation() ==
1788 InstanceMethods.push_back(OMD);
1794 if (InstanceMethods.size() == 0)
1795 classFields.addNullPointer(PtrTy);
1797 classFields.addBitCast(
1798 GenerateMethodList(className,
"", InstanceMethods,
false),
1801 classFields.addNullPointer(PtrTy);
1803 classFields.addNullPointer(PtrTy);
1805 classFields.addNullPointer(PtrTy);
1807 classFields.addNullPointer(PtrTy);
1809 classFields.addNullPointer(PtrTy);
1812 for (
const auto *I : classDecl->
protocols())
1813 Protocols.push_back(
1814 llvm::ConstantExpr::getBitCast(GenerateProtocolRef(I),
1816 if (Protocols.empty())
1817 classFields.addNullPointer(PtrTy);
1819 classFields.add(GenerateProtocolList(Protocols));
1821 classFields.addNullPointer(PtrTy);
1823 classFields.addInt(LongTy, 0);
1825 classFields.add(GeneratePropertyList(OID, classDecl));
1828 classFields.finishAndCreateGlobal(SymbolForClass(className),
1831 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1832 auto Storage = llvm::GlobalValue::DefaultStorageClass;
1834 Storage = llvm::GlobalValue::DLLImportStorageClass;
1836 Storage = llvm::GlobalValue::DLLExportStorageClass;
1837 cast<llvm::GlobalValue>(classStruct)->setDLLStorageClass(Storage);
1840 auto *classRefSymbol = GetClassVar(className);
1841 classRefSymbol->setSection(sectionName<ClassReferenceSection>());
1842 classRefSymbol->setInitializer(llvm::ConstantExpr::getBitCast(classStruct, IdTy));
1847 if (ClassPtrAlias) {
1848 ClassPtrAlias->replaceAllUsesWith(
1849 llvm::ConstantExpr::getBitCast(classStruct, IdTy));
1850 ClassPtrAlias->eraseFromParent();
1851 ClassPtrAlias =
nullptr;
1853 if (
auto Placeholder =
1854 TheModule.getNamedGlobal(SymbolForClass(className)))
1855 if (Placeholder != classStruct) {
1856 Placeholder->replaceAllUsesWith(
1857 llvm::ConstantExpr::getBitCast(classStruct, Placeholder->getType()));
1858 Placeholder->eraseFromParent();
1859 classStruct->setName(SymbolForClass(className));
1861 if (MetaClassPtrAlias) {
1862 MetaClassPtrAlias->replaceAllUsesWith(
1863 llvm::ConstantExpr::getBitCast(metaclass, IdTy));
1864 MetaClassPtrAlias->eraseFromParent();
1865 MetaClassPtrAlias =
nullptr;
1867 assert(classStruct->getName() == SymbolForClass(className));
1869 auto classInitRef =
new llvm::GlobalVariable(TheModule,
1871 classStruct,
"._OBJC_INIT_CLASS_" + className);
1872 classInitRef->setSection(sectionName<ClassSection>());
1875 EmittedClass =
true;
1878 CGObjCGNUstep2(
CodeGenModule &Mod) : CGObjCGNUstep(Mod, 10, 4, 2) {
1879 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
1880 PtrToObjCSuperTy, SelectorTy);
1889 PropertyMetadataTy =
1891 { PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty });
1896 const char *
const CGObjCGNUstep2::SectionsBaseNames[8] =
1900 "__objc_class_refs",
1903 "__objc_protocol_refs",
1904 "__objc_class_aliases",
1905 "__objc_constant_string" 1909 class CGObjCObjFW:
public CGObjCGNU {
1913 LazyRuntimeFunction MsgLookupFn;
1916 LazyRuntimeFunction MsgLookupFnSRet;
1920 LazyRuntimeFunction MsgLookupSuperFn, MsgLookupSuperFnSRet;
1924 MessageSendInfo &MSI)
override {
1927 EnforceType(Builder, Receiver, IdTy),
1928 EnforceType(Builder, cmd, SelectorTy) };
1936 imp->setMetadata(msgSendMDKind, node);
1937 return imp.getInstruction();
1941 llvm::Value *cmd, MessageSendInfo &MSI)
override {
1944 EnforceType(Builder, ObjCSuper.
getPointer(), PtrToObjCSuperTy), cmd,
1954 bool isWeak)
override {
1956 return CGObjCGNU::GetClassNamed(CGF, Name, isWeak);
1959 std::string SymbolName =
"_OBJC_CLASS_" + Name;
1960 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(SymbolName);
1962 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
1964 nullptr, SymbolName);
1971 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
1972 MsgLookupFnSRet.init(&CGM,
"objc_msg_lookup_stret", IMPTy, IdTy,
1975 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
1976 PtrToObjCSuperTy, SelectorTy);
1977 MsgLookupSuperFnSRet.init(&CGM,
"objc_msg_lookup_super_stret", IMPTy,
1978 PtrToObjCSuperTy, SelectorTy);
1986 void CGObjCGNU::EmitClassRef(
const std::string &className) {
1987 std::string symbolRef =
"__objc_class_ref_" + className;
1989 if (TheModule.getGlobalVariable(symbolRef))
1991 std::string symbolName =
"__objc_class_name_" + className;
1992 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
1994 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
1996 nullptr, symbolName);
1998 new llvm::GlobalVariable(TheModule, ClassSymbol->getType(),
true,
1999 llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef);
2002 CGObjCGNU::CGObjCGNU(
CodeGenModule &cgm,
unsigned runtimeABIVersion,
2003 unsigned protocolClassVersion,
unsigned classABI)
2005 VMContext(cgm.getLLVMContext()), ClassPtrAlias(nullptr),
2006 MetaClassPtrAlias(nullptr), RuntimeVersion(runtimeABIVersion),
2007 ProtocolVersion(protocolClassVersion), ClassABIVersion(classABI) {
2009 msgSendMDKind = VMContext.getMDKindID(
"GNUObjCMessageSend");
2014 IntTy = cast<llvm::IntegerType>(
2016 LongTy = cast<llvm::IntegerType>(
2018 SizeTy = cast<llvm::IntegerType>(
2020 PtrDiffTy = cast<llvm::IntegerType>(
2024 Int8Ty = llvm::Type::getInt8Ty(VMContext);
2026 PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
2027 ProtocolPtrTy = llvm::PointerType::getUnqual(
2030 Zeros[0] = llvm::ConstantInt::get(LongTy, 0);
2031 Zeros[1] = Zeros[0];
2032 NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty);
2036 SelectorTy = PtrToInt8Ty;
2041 PtrToIntTy = llvm::PointerType::getUnqual(IntTy);
2042 PtrTy = PtrToInt8Ty;
2044 Int32Ty = llvm::Type::getInt32Ty(VMContext);
2045 Int64Ty = llvm::Type::getInt64Ty(VMContext);
2048 CGM.
getDataLayout().getPointerSizeInBits() == 32 ? Int32Ty : Int64Ty;
2059 PtrToIdTy = llvm::PointerType::getUnqual(IdTy);
2060 ProtocolTy = llvm::StructType::get(IdTy,
2082 PropertyMetadataTy = llvm::StructType::get(CGM.
getLLVMContext(), {
2083 PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty,
2084 PtrToInt8Ty, PtrToInt8Ty });
2086 ObjCSuperTy = llvm::StructType::get(IdTy, IdTy);
2087 PtrToObjCSuperTy = llvm::PointerType::getUnqual(ObjCSuperTy);
2089 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
2092 ExceptionThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy);
2093 ExceptionReThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy);
2095 SyncEnterFn.init(&CGM,
"objc_sync_enter", IntTy, IdTy);
2097 SyncExitFn.init(&CGM,
"objc_sync_exit", IntTy, IdTy);
2100 EnumerationMutationFn.init(&CGM,
"objc_enumerationMutation", VoidTy, IdTy);
2103 GetPropertyFn.init(&CGM,
"objc_getProperty", IdTy, IdTy, SelectorTy,
2106 SetPropertyFn.init(&CGM,
"objc_setProperty", VoidTy, IdTy, SelectorTy,
2107 PtrDiffTy, IdTy, BoolTy, BoolTy);
2109 GetStructPropertyFn.init(&CGM,
"objc_getPropertyStruct", VoidTy, PtrTy, PtrTy,
2110 PtrDiffTy, BoolTy, BoolTy);
2112 SetStructPropertyFn.init(&CGM,
"objc_setPropertyStruct", VoidTy, PtrTy, PtrTy,
2113 PtrDiffTy, BoolTy, BoolTy);
2116 llvm::Type *IMPArgs[] = { IdTy, SelectorTy };
2117 IMPTy = llvm::PointerType::getUnqual(llvm::FunctionType::get(IdTy, IMPArgs,
2122 RuntimeVersion = 10;
2137 IvarAssignFn.init(&CGM,
"objc_assign_ivar", IdTy, IdTy, IdTy, PtrDiffTy);
2139 StrongCastAssignFn.init(&CGM,
"objc_assign_strongCast", IdTy, IdTy,
2142 GlobalAssignFn.init(&CGM,
"objc_assign_global", IdTy, IdTy, PtrToIdTy);
2144 WeakAssignFn.init(&CGM,
"objc_assign_weak", IdTy, IdTy, PtrToIdTy);
2146 WeakReadFn.init(&CGM,
"objc_read_weak", IdTy, PtrToIdTy);
2148 MemMoveFn.init(&CGM,
"objc_memmove_collectable", PtrTy, PtrTy, PtrTy,
2154 const std::string &Name,
bool isWeak) {
2155 llvm::Constant *ClassName = MakeConstantString(Name);
2166 llvm::Constant *ClassLookupFn =
2168 "objc_lookup_class");
2178 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value))
2184 auto *
Value = GetClassNamed(CGF,
"NSAutoreleasePool",
false);
2185 if (CGM.
getTriple().isOSBinFormatCOFF()) {
2186 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value)) {
2192 for (
const auto &Result : DC->
lookup(&II))
2193 if ((VD = dyn_cast<VarDecl>(Result)))
2203 const std::string &TypeEncoding) {
2205 llvm::GlobalAlias *SelValue =
nullptr;
2208 e = Types.end() ; i!=e ; i++) {
2209 if (i->first == TypeEncoding) {
2210 SelValue = i->second;
2216 SelectorTy->getElementType(), 0, llvm::GlobalValue::PrivateLinkage,
2217 ".objc_selector_" + Sel.
getAsString(), &TheModule);
2218 Types.emplace_back(TypeEncoding, SelValue);
2236 return GetTypedSelector(CGF, Sel, std::string());
2242 return GetTypedSelector(CGF, Method->
getSelector(), SelTypes);
2245 llvm::Constant *CGObjCGNU::GetEHType(
QualType T) {
2252 return MakeConstantString(
"@id");
2260 assert(OPT &&
"Invalid @catch type.");
2262 assert(IDecl &&
"Invalid @catch type.");
2266 llvm::Constant *CGObjCGNUstep::GetEHType(
QualType T) {
2267 if (usesSEHExceptions)
2271 return CGObjCGNU::GetEHType(T);
2279 llvm::Constant *IDEHType =
2280 CGM.
getModule().getGlobalVariable(
"__objc_id_type_info");
2283 new llvm::GlobalVariable(CGM.
getModule(), PtrToInt8Ty,
2286 nullptr,
"__objc_id_type_info");
2287 return llvm::ConstantExpr::getBitCast(IDEHType, PtrToInt8Ty);
2292 assert(PT &&
"Invalid @catch type.");
2294 assert(IT &&
"Invalid @catch type.");
2297 std::string typeinfoName =
"__objc_eh_typeinfo_" + className;
2300 llvm::Constant *typeinfo = TheModule.getGlobalVariable(typeinfoName);
2302 return llvm::ConstantExpr::getBitCast(typeinfo, PtrToInt8Ty);
2309 const char *vtableName =
"_ZTVN7gnustep7libobjc22__objc_class_type_infoE";
2310 auto *Vtable = TheModule.getGlobalVariable(vtableName);
2312 Vtable =
new llvm::GlobalVariable(TheModule, PtrToInt8Ty,
true,
2314 nullptr, vtableName);
2316 llvm::Constant *Two = llvm::ConstantInt::get(IntTy, 2);
2317 auto *BVtable = llvm::ConstantExpr::getBitCast(
2318 llvm::ConstantExpr::getGetElementPtr(Vtable->getValueType(), Vtable, Two),
2321 llvm::Constant *typeName =
2322 ExportUniqueString(className,
"__objc_eh_typename_");
2325 auto fields = builder.beginStruct();
2326 fields.add(BVtable);
2327 fields.add(typeName);
2328 llvm::Constant *TI =
2329 fields.finishAndCreateGlobal(
"__objc_eh_typeinfo_" + className,
2332 llvm::GlobalValue::LinkOnceODRLinkage);
2333 return llvm::ConstantExpr::getBitCast(TI, PtrToInt8Ty);
2339 std::string Str = SL->
getString().str();
2343 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
2344 if (old != ObjCStrings.end())
2349 if (StringClass.empty()) StringClass =
"NSConstantString";
2351 std::string Sym =
"_OBJC_CLASS_";
2354 llvm::Constant *isa = TheModule.getNamedGlobal(Sym);
2357 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
2358 llvm::GlobalValue::ExternalWeakLinkage,
nullptr, Sym);
2359 else if (isa->getType() != PtrToIdTy)
2360 isa = llvm::ConstantExpr::getBitCast(isa, PtrToIdTy);
2363 auto Fields = Builder.beginStruct();
2365 Fields.add(MakeConstantString(Str));
2366 Fields.addInt(IntTy, Str.size());
2367 llvm::Constant *ObjCStr =
2369 ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStr, PtrToInt8Ty);
2370 ObjCStrings[Str] = ObjCStr;
2371 ConstantStrings.push_back(ObjCStr);
2384 bool isCategoryImpl,
2386 bool IsClassMessage,
2391 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2395 if (Sel == ReleaseSel) {
2403 ActualArgs.
add(
RValue::get(EnforceType(Builder, Receiver, IdTy)), ASTIdTy);
2412 ReceiverClass = GetClassNamed(CGF,
2414 if (IsClassMessage) {
2417 llvm::PointerType::getUnqual(IdTy));
2421 ReceiverClass = EnforceType(Builder, ReceiverClass, IdTy);
2423 if (isCategoryImpl) {
2424 llvm::Constant *classLookupFunction =
nullptr;
2425 if (IsClassMessage) {
2427 IdTy, PtrTy,
true),
"objc_get_meta_class");
2430 IdTy, PtrTy,
true),
"objc_get_class");
2432 ReceiverClass = Builder.CreateCall(classLookupFunction,
2440 if (IsClassMessage) {
2441 if (!MetaClassPtrAlias) {
2446 ReceiverClass = MetaClassPtrAlias;
2448 if (!ClassPtrAlias) {
2453 ReceiverClass = ClassPtrAlias;
2457 llvm::Type *CastTy = llvm::StructType::get(IdTy, IdTy);
2459 llvm::PointerType::getUnqual(CastTy));
2467 llvm::StructType *ObjCSuperTy =
2468 llvm::StructType::get(Receiver->getType(), IdTy);
2478 ObjCSuper = EnforceType(Builder, ObjCSuper, PtrToObjCSuperTy);
2481 llvm::Value *imp = LookupIMPSuper(CGF, ObjCSuper, cmd, MSI);
2482 imp = EnforceType(Builder, imp, MSI.MessengerType);
2484 llvm::Metadata *impMD[] = {
2485 llvm::MDString::get(VMContext, Sel.
getAsString()),
2487 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2488 llvm::Type::getInt1Ty(VMContext), IsClassMessage))};
2489 llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD);
2493 llvm::Instruction *call;
2494 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2495 call->setMetadata(msgSendMDKind, node);
2513 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2517 if (Sel == ReleaseSel) {
2536 llvm::BasicBlock *startBB =
nullptr;
2537 llvm::BasicBlock *messageBB =
nullptr;
2538 llvm::BasicBlock *continueBB =
nullptr;
2540 if (!isPointerSizedReturn) {
2541 startBB = Builder.GetInsertBlock();
2545 llvm::Value *isNil = Builder.CreateICmpEQ(Receiver,
2546 llvm::Constant::getNullValue(Receiver->getType()));
2547 Builder.CreateCondBr(isNil, continueBB, messageBB);
2557 cmd = EnforceType(Builder, cmd, SelectorTy);
2558 Receiver = EnforceType(Builder, Receiver, IdTy);
2560 llvm::Metadata *impMD[] = {
2561 llvm::MDString::get(VMContext, Sel.
getAsString()),
2562 llvm::MDString::get(VMContext, Class ? Class->
getNameAsString() :
""),
2563 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2564 llvm::Type::getInt1Ty(VMContext), Class !=
nullptr))};
2565 llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD);
2582 imp = LookupIMP(CGF, Receiver, cmd, node, MSI);
2588 "objc_msgSend_fpret");
2593 "objc_msgSend_stret");
2603 imp = EnforceType(Builder, imp, MSI.MessengerType);
2605 llvm::Instruction *call;
2607 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2608 call->setMetadata(msgSendMDKind, node);
2611 if (!isPointerSizedReturn) {
2612 messageBB = CGF.
Builder.GetInsertBlock();
2613 CGF.
Builder.CreateBr(continueBB);
2617 llvm::PHINode *phi = Builder.CreatePHI(v->getType(), 2);
2618 phi->addIncoming(v, messageBB);
2619 phi->addIncoming(llvm::Constant::getNullValue(v->getType()), startBB);
2623 llvm::PHINode *phi = Builder.CreatePHI(v.
getType(), 2);
2626 CGF.
InitTempAlloca(NullVal, llvm::Constant::getNullValue(RetTy));
2628 phi->addIncoming(NullVal.
getPointer(), startBB);
2631 std::pair<llvm::Value*,llvm::Value*> v = msgRet.
getComplexVal();
2632 llvm::PHINode *phi = Builder.CreatePHI(v.first->getType(), 2);
2633 phi->addIncoming(v.first, messageBB);
2634 phi->addIncoming(llvm::Constant::getNullValue(v.first->getType()),
2636 llvm::PHINode *phi2 = Builder.CreatePHI(v.second->getType(), 2);
2637 phi2->addIncoming(v.second, messageBB);
2638 phi2->addIncoming(llvm::Constant::getNullValue(v.second->getType()),
2648 llvm::Constant *CGObjCGNU::
2649 GenerateMethodList(StringRef ClassName,
2650 StringRef CategoryName,
2652 bool isClassMethodList) {
2653 if (Methods.empty())
2658 auto MethodList = Builder.beginStruct();
2659 MethodList.addNullPointer(CGM.
Int8PtrTy);
2660 MethodList.addInt(Int32Ty, Methods.size());
2663 llvm::StructType *ObjCMethodTy =
2672 llvm::DataLayout td(&TheModule);
2673 MethodList.addInt(SizeTy, td.getTypeSizeInBits(ObjCMethodTy) /
2689 auto MethodArray = MethodList.beginArray();
2691 for (
const auto *OMD : Methods) {
2692 llvm::Constant *FnPtr =
2693 TheModule.getFunction(SymbolNameForMethod(ClassName, CategoryName,
2695 isClassMethodList));
2696 assert(FnPtr &&
"Can't generate metadata for method that doesn't exist");
2697 auto Method = MethodArray.beginStruct(ObjCMethodTy);
2699 Method.addBitCast(FnPtr, IMPTy);
2700 Method.
add(GetConstantSelector(OMD->getSelector(),
2704 Method.
add(MakeConstantString(OMD->getSelector().getAsString()));
2706 Method.addBitCast(FnPtr, IMPTy);
2708 Method.finishAndAddTo(MethodArray);
2710 MethodArray.finishAndAddTo(MethodList);
2713 return MethodList.finishAndCreateGlobal(
".objc_method_list",
2718 llvm::Constant *CGObjCGNU::
2724 if (IvarNames.empty())
2730 auto IvarList = Builder.beginStruct();
2731 IvarList.addInt(IntTy, (
int)IvarNames.size());
2734 llvm::StructType *ObjCIvarTy =
2735 llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, IntTy);
2738 auto Ivars = IvarList.beginArray(ObjCIvarTy);
2739 for (
unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {
2740 auto Ivar = Ivars.beginStruct(ObjCIvarTy);
2741 Ivar.
add(IvarNames[i]);
2742 Ivar.
add(IvarTypes[i]);
2743 Ivar.
add(IvarOffsets[i]);
2744 Ivar.finishAndAddTo(Ivars);
2746 Ivars.finishAndAddTo(IvarList);
2749 return IvarList.finishAndCreateGlobal(
".objc_ivar_list",
2754 llvm::Constant *CGObjCGNU::GenerateClassStructure(
2755 llvm::Constant *MetaClass,
2756 llvm::Constant *SuperClass,
2759 llvm::Constant *Version,
2760 llvm::Constant *InstanceSize,
2761 llvm::Constant *IVars,
2762 llvm::Constant *Methods,
2763 llvm::Constant *Protocols,
2764 llvm::Constant *IvarOffsets,
2765 llvm::Constant *Properties,
2766 llvm::Constant *StrongIvarBitmap,
2767 llvm::Constant *WeakIvarBitmap,
2776 llvm::StructType *ClassTy = llvm::StructType::get(
2793 IvarOffsets->getType(),
2794 Properties->getType(),
2800 auto Elements = Builder.beginStruct(ClassTy);
2805 Elements.addBitCast(MetaClass, PtrToInt8Ty);
2807 Elements.add(SuperClass);
2809 Elements.add(MakeConstantString(Name,
".class_name"));
2811 Elements.addInt(LongTy, 0);
2813 Elements.addInt(LongTy, info);
2816 llvm::DataLayout td(&TheModule);
2817 Elements.addInt(LongTy,
2818 td.getTypeSizeInBits(ClassTy) /
2821 Elements.add(InstanceSize);
2823 Elements.add(IVars);
2825 Elements.add(Methods);
2828 Elements.add(NULLPtr);
2830 Elements.add(NULLPtr);
2832 Elements.add(NULLPtr);
2834 Elements.addBitCast(Protocols, PtrTy);
2836 Elements.add(NULLPtr);
2838 Elements.addInt(LongTy, ClassABIVersion);
2840 Elements.add(IvarOffsets);
2842 Elements.add(Properties);
2844 Elements.add(StrongIvarBitmap);
2846 Elements.add(WeakIvarBitmap);
2851 std::string ClassSym((isMeta ?
"_OBJC_METACLASS_":
"_OBJC_CLASS_") +
2853 llvm::GlobalVariable *ClassRef = TheModule.getNamedGlobal(ClassSym);
2854 llvm::Constant *Class =
2855 Elements.finishAndCreateGlobal(ClassSym, CGM.
getPointerAlign(),
false,
2858 ClassRef->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(Class,
2859 ClassRef->getType()));
2860 ClassRef->removeFromParent();
2861 Class->setName(ClassSym);
2866 llvm::Constant *CGObjCGNU::
2869 llvm::StructType *ObjCMethodDescTy =
2870 llvm::StructType::get(CGM.
getLLVMContext(), { PtrToInt8Ty, PtrToInt8Ty });
2873 auto MethodList = Builder.beginStruct();
2874 MethodList.addInt(IntTy, Methods.size());
2875 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
2876 for (
auto *M : Methods) {
2877 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
2879 Method.
add(MakeConstantString(Context.getObjCEncodingForMethodDecl(M)));
2880 Method.finishAndAddTo(MethodArray);
2882 MethodArray.finishAndAddTo(MethodList);
2883 return MethodList.finishAndCreateGlobal(
".objc_method_list",
2892 auto ProtocolList = Builder.beginStruct();
2893 ProtocolList.add(NULLPtr);
2894 ProtocolList.addInt(LongTy, Protocols.size());
2896 auto Elements = ProtocolList.beginArray(PtrToInt8Ty);
2897 for (
const std::string *iter = Protocols.begin(), *endIter = Protocols.end();
2898 iter != endIter ; iter++) {
2899 llvm::Constant *protocol =
nullptr;
2900 llvm::StringMap<llvm::Constant*>::iterator value =
2901 ExistingProtocols.find(*iter);
2902 if (value == ExistingProtocols.end()) {
2903 protocol = GenerateEmptyProtocol(*iter);
2905 protocol = value->getValue();
2907 Elements.addBitCast(protocol, PtrToInt8Ty);
2909 Elements.finishAndAddTo(ProtocolList);
2910 return ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
2925 CGObjCGNU::GenerateEmptyProtocol(StringRef ProtocolName) {
2926 llvm::Constant *ProtocolList = GenerateProtocolList({});
2927 llvm::Constant *MethodList = GenerateProtocolMethodList({});
2928 MethodList = llvm::ConstantExpr::getBitCast(MethodList, PtrToInt8Ty);
2932 auto Elements = Builder.beginStruct();
2936 Elements.add(llvm::ConstantExpr::getIntToPtr(
2937 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
2939 Elements.add(MakeConstantString(ProtocolName,
".objc_protocol_name"));
2940 Elements.add(ProtocolList);
2941 Elements.add(MethodList);
2942 Elements.add(MethodList);
2943 Elements.add(MethodList);
2944 Elements.add(MethodList);
2945 Elements.add(NULLPtr);
2946 Elements.add(NULLPtr);
2947 return Elements.finishAndCreateGlobal(SymbolForProtocol(ProtocolName),
2960 Protocols.push_back(PI->getNameAsString());
2964 if (I->isOptional())
2965 OptionalInstanceMethods.push_back(I);
2967 InstanceMethods.push_back(I);
2972 if (I->isOptional())
2973 OptionalClassMethods.push_back(I);
2975 ClassMethods.push_back(I);
2977 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
2978 llvm::Constant *InstanceMethodList =
2979 GenerateProtocolMethodList(InstanceMethods);
2980 llvm::Constant *ClassMethodList =
2981 GenerateProtocolMethodList(ClassMethods);
2982 llvm::Constant *OptionalInstanceMethodList =
2983 GenerateProtocolMethodList(OptionalInstanceMethods);
2984 llvm::Constant *OptionalClassMethodList =
2985 GenerateProtocolMethodList(OptionalClassMethods);
2993 llvm::Constant *PropertyList =
2994 GeneratePropertyList(
nullptr, PD,
false,
false);
2995 llvm::Constant *OptionalPropertyList =
2996 GeneratePropertyList(
nullptr, PD,
false,
true);
3003 auto Elements = Builder.beginStruct();
3005 llvm::ConstantExpr::getIntToPtr(
3006 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3007 Elements.add(MakeConstantString(ProtocolName));
3008 Elements.add(ProtocolList);
3009 Elements.add(InstanceMethodList);
3010 Elements.add(ClassMethodList);
3011 Elements.add(OptionalInstanceMethodList);
3012 Elements.add(OptionalClassMethodList);
3013 Elements.add(PropertyList);
3014 Elements.add(OptionalPropertyList);
3015 ExistingProtocols[ProtocolName] =
3016 llvm::ConstantExpr::getBitCast(
3017 Elements.finishAndCreateGlobal(
".objc_protocol", CGM.
getPointerAlign()),
3020 void CGObjCGNU::GenerateProtocolHolderCategory() {
3024 auto Elements = Builder.beginStruct();
3026 const std::string ClassName =
"__ObjC_Protocol_Holder_Ugly_Hack";
3027 const std::string CategoryName =
"AnotherHack";
3028 Elements.add(MakeConstantString(CategoryName));
3029 Elements.add(MakeConstantString(ClassName));
3031 Elements.addBitCast(GenerateMethodList(
3032 ClassName, CategoryName, {},
false), PtrTy);
3034 Elements.addBitCast(GenerateMethodList(
3035 ClassName, CategoryName, {},
true), PtrTy);
3039 auto ProtocolList = ProtocolListBuilder.beginStruct();
3040 ProtocolList.add(NULLPtr);
3041 ProtocolList.addInt(LongTy, ExistingProtocols.size());
3042 auto ProtocolElements = ProtocolList.beginArray(PtrTy);
3043 for (
auto iter = ExistingProtocols.begin(), endIter = ExistingProtocols.end();
3044 iter != endIter ; iter++) {
3045 ProtocolElements.addBitCast(iter->getValue(), PtrTy);
3047 ProtocolElements.finishAndAddTo(ProtocolList);
3048 Elements.addBitCast(
3049 ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
3052 Categories.push_back(llvm::ConstantExpr::getBitCast(
3069 int bitCount = bits.size();
3071 if (bitCount < ptrBits) {
3073 for (
int i=0 ; i<bitCount ; ++i) {
3074 if (bits[i]) val |= 1ULL<<(i+1);
3076 return llvm::ConstantInt::get(IntPtrTy, val);
3080 while (v < bitCount) {
3082 for (
int i=0 ; (i<32) && (v<bitCount) ; ++i) {
3083 if (bits[v]) word |= 1<<i;
3086 values.push_back(llvm::ConstantInt::get(Int32Ty, word));
3090 auto fields = builder.beginStruct();
3091 fields.addInt(Int32Ty, values.size());
3092 auto array = fields.beginArray();
3093 for (
auto v : values) array.add(v);
3094 array.finishAndAddTo(fields);
3096 llvm::Constant *GS =
3098 llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy);
3112 E = Protos.
end(); I != E; ++I)
3113 Protocols.push_back((*I)->getNameAsString());
3116 auto Elements = Builder.beginStruct();
3117 Elements.add(MakeConstantString(CategoryName));
3118 Elements.add(MakeConstantString(ClassName));
3121 InstanceMethods.insert(InstanceMethods.begin(), OCD->
instmeth_begin(),
3123 Elements.addBitCast(
3124 GenerateMethodList(ClassName, CategoryName, InstanceMethods,
false),
3131 Elements.addBitCast(
3132 GenerateMethodList(ClassName, CategoryName, ClassMethods,
true),
3135 Elements.addBitCast(GenerateProtocolList(Protocols), PtrTy);
3141 Elements.addBitCast(GeneratePropertyList(OCD, Category,
false), PtrTy);
3143 Elements.addBitCast(GeneratePropertyList(OCD, Category,
true), PtrTy);
3145 Elements.addNullPointer(PtrTy);
3146 Elements.addNullPointer(PtrTy);
3150 Categories.push_back(llvm::ConstantExpr::getBitCast(
3151 Elements.finishAndCreateGlobal(
3152 std::string(
".objc_category_")+ClassName+CategoryName,
3157 llvm::Constant *CGObjCGNU::GeneratePropertyList(
const Decl *Container,
3159 bool isClassProperty,
3160 bool protocolOptionalProperties) {
3163 llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
3164 bool isProtocol = isa<ObjCProtocolDecl>(OCD);
3167 std::function<void(const ObjCProtocolDecl *Proto)> collectProtocolProperties
3169 for (
const auto *
P : Proto->protocols())
3170 collectProtocolProperties(
P);
3172 if (isClassProperty != PD->isClassProperty())
3176 if (!isProtocol && !Context.getObjCPropertyImplDeclForPropertyDecl(PD, Container))
3180 Properties.push_back(PD);
3187 if (isClassProperty != PD->isClassProperty())
3190 Properties.push_back(PD);
3194 if (isClassProperty != PD->isClassProperty())
3198 if (isProtocol && (protocolOptionalProperties != PD->isOptional()))
3205 Properties.push_back(PD);
3210 collectProtocolProperties(
P);
3212 for (
const auto *
P : CD->protocols())
3213 collectProtocolProperties(
P);
3215 auto numProperties = Properties.size();
3217 if (numProperties == 0)
3221 auto propertyList = builder.beginStruct();
3222 auto properties = PushPropertyListHeader(propertyList, numProperties);
3226 for (
auto *property : Properties) {
3227 bool isSynthesized =
false;
3230 auto *propertyImpl = Context.getObjCPropertyImplDeclForPropertyDecl(property, Container);
3232 isSynthesized = (propertyImpl->getPropertyImplementation() ==
3234 isDynamic = (propertyImpl->getPropertyImplementation() ==
3238 PushProperty(properties, property, Container, isSynthesized, isDynamic);
3240 properties.finishAndAddTo(propertyList);
3242 return propertyList.finishAndCreateGlobal(
".objc_property_list",
3260 std::string SuperClassName;
3261 if (SuperClassDecl) {
3263 EmitClassRef(SuperClassName);
3273 std::string classSymbolName =
"__objc_class_name_" + ClassName;
3274 if (
auto *symbol = TheModule.getGlobalVariable(classSymbolName)) {
3275 symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0));
3277 new llvm::GlobalVariable(TheModule, LongTy,
false,
3279 llvm::ConstantInt::get(LongTy, 0),
3295 auto IvarOffsetValues = IvarOffsetBuilder.beginArray(PtrToIntTy);
3299 int superInstanceSize = !SuperClassDecl ? 0 :
3304 instanceSize = 0 - (instanceSize - superInstanceSize);
3310 IvarNames.push_back(MakeConstantString(IVD->getNameAsString()));
3312 std::string TypeStr;
3314 IvarTypes.push_back(MakeConstantString(TypeStr));
3315 IvarAligns.push_back(llvm::ConstantInt::get(IntTy,
3319 uint64_t Offset = BaseOffset;
3321 Offset = BaseOffset - superInstanceSize;
3323 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
3325 std::string OffsetName =
"__objc_ivar_offset_value_" + ClassName +
"." +
3326 IVD->getNameAsString();
3328 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
3330 OffsetVar->setInitializer(OffsetValue);
3336 OffsetVar =
new llvm::GlobalVariable(TheModule, Int32Ty,
3338 OffsetValue, OffsetName);
3339 IvarOffsets.push_back(OffsetValue);
3340 IvarOffsetValues.add(OffsetVar);
3342 IvarOwnership.push_back(lt);
3345 StrongIvars.push_back(
true);
3346 WeakIvars.push_back(
false);
3349 StrongIvars.push_back(
false);
3350 WeakIvars.push_back(
true);
3353 StrongIvars.push_back(
false);
3354 WeakIvars.push_back(
false);
3357 llvm::Constant *StrongIvarBitmap = MakeBitField(StrongIvars);
3358 llvm::Constant *WeakIvarBitmap = MakeBitField(WeakIvars);
3359 llvm::GlobalVariable *IvarOffsetArray =
3360 IvarOffsetValues.finishAndCreateGlobal(
".ivar.offsets",
3365 InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
3375 if (propertyImpl->getPropertyImplementation() ==
3380 InstanceMethods.push_back(accessor);
3386 llvm::Constant *Properties = GeneratePropertyList(OID, ClassDecl);
3390 for (
const auto *I : ClassDecl->
protocols())
3391 Protocols.push_back(I->getNameAsString());
3394 llvm::Constant *SuperClass;
3395 if (!SuperClassName.empty()) {
3396 SuperClass = MakeConstantString(SuperClassName,
".super_class_name");
3398 SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty);
3403 llvm::Constant *MethodList = GenerateMethodList(ClassName,
"",
3404 InstanceMethods,
false);
3405 llvm::Constant *ClassMethodList = GenerateMethodList(ClassName,
"",
3406 ClassMethods,
true);
3407 llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
3408 IvarOffsets, IvarAligns, IvarOwnership);
3420 llvm::Constant *offsetPointerIndexes[] = {Zeros[0],
3421 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 2 : 1),
nullptr,
3422 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 3 : 2) };
3424 unsigned ivarIndex = 0;
3427 const std::string Name = GetIVarOffsetVariableName(ClassDecl, IVD);
3428 offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, ivarIndex);
3430 llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr(
3431 cast<llvm::GlobalVariable>(IvarList)->getValueType(), IvarList,
3432 offsetPointerIndexes);
3434 llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name);
3436 offset->setInitializer(offsetValue);
3443 new llvm::GlobalVariable(TheModule, offsetValue->getType(),
3447 llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0);
3450 llvm::Constant *MetaClassStruct = GenerateClassStructure(
3451 NULLPtr, NULLPtr, 0x12L, ClassName.c_str(),
nullptr, Zeros[0],
3452 NULLPtr, ClassMethodList, NULLPtr, NULLPtr,
3453 GeneratePropertyList(OID, ClassDecl,
true), ZeroPtr, ZeroPtr,
true);
3458 llvm::Constant *ClassStruct = GenerateClassStructure(
3459 MetaClassStruct, SuperClass, 0x11L, ClassName.c_str(),
nullptr,
3460 llvm::ConstantInt::get(LongTy, instanceSize), IvarList, MethodList,
3461 GenerateProtocolList(Protocols), IvarOffsetArray, Properties,
3462 StrongIvarBitmap, WeakIvarBitmap);
3467 if (ClassPtrAlias) {
3468 ClassPtrAlias->replaceAllUsesWith(
3469 llvm::ConstantExpr::getBitCast(ClassStruct, IdTy));
3470 ClassPtrAlias->eraseFromParent();
3471 ClassPtrAlias =
nullptr;
3473 if (MetaClassPtrAlias) {
3474 MetaClassPtrAlias->replaceAllUsesWith(
3475 llvm::ConstantExpr::getBitCast(MetaClassStruct, IdTy));
3476 MetaClassPtrAlias->eraseFromParent();
3477 MetaClassPtrAlias =
nullptr;
3481 ClassStruct = llvm::ConstantExpr::getBitCast(ClassStruct, PtrToInt8Ty);
3482 Classes.push_back(ClassStruct);
3485 llvm::Function *CGObjCGNU::ModuleInitFunction() {
3487 if (Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
3488 ExistingProtocols.empty() && SelectorTable.empty())
3492 GenerateProtocolHolderCategory();
3494 llvm::StructType *selStructTy =
3495 dyn_cast<llvm::StructType>(SelectorTy->getElementType());
3499 { PtrToInt8Ty, PtrToInt8Ty });
3500 selStructPtrTy = llvm::PointerType::getUnqual(selStructTy);
3504 llvm::Constant *statics = NULLPtr;
3505 if (!ConstantStrings.empty()) {
3506 llvm::GlobalVariable *fileStatics = [&] {
3508 auto staticsStruct = builder.beginStruct();
3511 if (stringClass.empty()) stringClass =
"NXConstantString";
3512 staticsStruct.add(MakeConstantString(stringClass,
3513 ".objc_static_class_name"));
3515 auto array = staticsStruct.beginArray();
3516 array.addAll(ConstantStrings);
3518 array.finishAndAddTo(staticsStruct);
3520 return staticsStruct.finishAndCreateGlobal(
".objc_statics",
3525 auto allStaticsArray = builder.beginArray(fileStatics->getType());
3526 allStaticsArray.add(fileStatics);
3527 allStaticsArray.addNullPointer(fileStatics->getType());
3529 statics = allStaticsArray.finishAndCreateGlobal(
".objc_statics_ptr",
3531 statics = llvm::ConstantExpr::getBitCast(statics, PtrTy);
3537 unsigned selectorCount;
3540 llvm::GlobalVariable *selectorList = [&] {
3542 auto selectors = builder.beginArray(selStructTy);
3543 auto &table = SelectorTable;
3544 for (
auto &entry : table) {
3546 std::string selNameStr = entry.first.getAsString();
3547 llvm::Constant *selName = ExportUniqueString(selNameStr,
".objc_sel_name");
3549 for (TypedSelector &sel : entry.second) {
3550 llvm::Constant *selectorTypeEncoding = NULLPtr;
3551 if (!sel.first.empty())
3552 selectorTypeEncoding =
3553 MakeConstantString(sel.first,
".objc_sel_types");
3555 auto selStruct = selectors.beginStruct(selStructTy);
3556 selStruct.add(selName);
3557 selStruct.add(selectorTypeEncoding);
3558 selStruct.finishAndAddTo(selectors);
3561 selectorAliases.push_back(sel.second);
3566 selectorCount = selectors.size();
3572 auto selStruct = selectors.beginStruct(selStructTy);
3573 selStruct.add(NULLPtr);
3574 selStruct.add(NULLPtr);
3575 selStruct.finishAndAddTo(selectors);
3577 return selectors.finishAndCreateGlobal(
".objc_selector_list",
3582 for (
unsigned i = 0; i < selectorCount; ++i) {
3583 llvm::Constant *idxs[] = {
3585 llvm::ConstantInt::get(Int32Ty, i)
3588 llvm::Constant *selPtr = llvm::ConstantExpr::getGetElementPtr(
3589 selectorList->getValueType(), selectorList, idxs);
3592 selPtr = llvm::ConstantExpr::getBitCast(selPtr, SelectorTy);
3593 selectorAliases[i]->replaceAllUsesWith(selPtr);
3594 selectorAliases[i]->eraseFromParent();
3597 llvm::GlobalVariable *symtab = [&] {
3599 auto symtab = builder.beginStruct();
3602 symtab.addInt(LongTy, selectorCount);
3604 symtab.addBitCast(selectorList, selStructPtrTy);
3607 symtab.addInt(CGM.
Int16Ty, Classes.size());
3609 symtab.addInt(CGM.
Int16Ty, Categories.size());
3612 auto classList = symtab.beginArray(PtrToInt8Ty);
3613 classList.addAll(Classes);
3614 classList.addAll(Categories);
3616 classList.add(statics);
3617 classList.add(NULLPtr);
3618 classList.finishAndAddTo(symtab);
3626 llvm::Constant *module = [&] {
3628 LongTy, LongTy, PtrToInt8Ty, symtab->getType(), IntTy
3630 llvm::StructType *moduleTy =
3632 makeArrayRef(moduleEltTys).drop_back(
unsigned(RuntimeVersion < 10)));
3635 auto module = builder.beginStruct(moduleTy);
3637 module.addInt(LongTy, RuntimeVersion);
3639 module.addInt(LongTy, CGM.
getDataLayout().getTypeStoreSize(moduleTy));
3646 module.add(MakeConstantString(path,
".objc_source_file_name"));
3649 if (RuntimeVersion >= 10) {
3652 module.addInt(IntTy, 2);
3656 module.addInt(IntTy, 1);
3658 module.addInt(IntTy, 0);
3661 module.addInt(IntTy, 1);
3672 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
3675 llvm::BasicBlock *EntryBB =
3678 Builder.SetInsertPoint(EntryBB);
3680 llvm::FunctionType *FT =
3681 llvm::FunctionType::get(Builder.getVoidTy(), module->getType(),
true);
3683 Builder.CreateCall(Register, module);
3685 if (!ClassAliases.empty()) {
3686 llvm::Type *ArgTypes[2] = {PtrTy, PtrToInt8Ty};
3687 llvm::FunctionType *RegisterAliasTy =
3688 llvm::FunctionType::get(Builder.getVoidTy(),
3692 llvm::GlobalValue::ExternalWeakLinkage,
"class_registerAlias_np",
3694 llvm::BasicBlock *AliasBB =
3696 llvm::BasicBlock *NoAliasBB =
3700 llvm::Value *HasRegisterAlias = Builder.CreateICmpNE(RegisterAlias,
3701 llvm::Constant::getNullValue(RegisterAlias->getType()));
3702 Builder.CreateCondBr(HasRegisterAlias, AliasBB, NoAliasBB);
3705 Builder.SetInsertPoint(AliasBB);
3707 for (std::vector<ClassAliasPair>::iterator iter = ClassAliases.begin();
3708 iter != ClassAliases.end(); ++iter) {
3709 llvm::Constant *TheClass =
3710 TheModule.getGlobalVariable(
"_OBJC_CLASS_" + iter->first,
true);
3712 TheClass = llvm::ConstantExpr::getBitCast(TheClass, PtrTy);
3713 Builder.CreateCall(RegisterAlias,
3714 {TheClass, MakeConstantString(iter->second)});
3718 Builder.CreateBr(NoAliasBB);
3721 Builder.SetInsertPoint(NoAliasBB);
3723 Builder.CreateRetVoid();
3725 return LoadFunction;
3728 llvm::Function *CGObjCGNU::GenerateMethod(
const ObjCMethodDecl *OMD,
3732 StringRef CategoryName = OCD ? OCD->
getName() :
"";
3733 StringRef ClassName = CD->
getName();
3738 llvm::FunctionType *MethodTy =
3740 std::string FunctionName = SymbolNameForMethod(ClassName, CategoryName,
3741 MethodName, isClassMethod);
3743 llvm::Function *Method
3751 llvm::Constant *CGObjCGNU::GetPropertyGetFunction() {
3752 return GetPropertyFn;
3755 llvm::Constant *CGObjCGNU::GetPropertySetFunction() {
3756 return SetPropertyFn;
3759 llvm::Constant *CGObjCGNU::GetOptimizedPropertySetFunction(
bool atomic,
3764 llvm::Constant *CGObjCGNU::GetGetStructFunction() {
3765 return GetStructPropertyFn;
3768 llvm::Constant *CGObjCGNU::GetSetStructFunction() {
3769 return SetStructPropertyFn;
3772 llvm::Constant *CGObjCGNU::GetCppAtomicObjectGetFunction() {
3776 llvm::Constant *CGObjCGNU::GetCppAtomicObjectSetFunction() {
3780 llvm::Constant *CGObjCGNU::EnumerationMutationFunction() {
3781 return EnumerationMutationFn;
3808 bool ClearInsertionPoint) {
3810 bool isRethrow =
false;
3814 ExceptionAsObject = Exception;
3817 "Unexpected rethrow outside @catch block.");
3821 if (isRethrow && usesSEHExceptions) {
3833 llvm::CallSite Throw =
3835 Throw.setDoesNotReturn();
3837 CGF.
Builder.CreateUnreachable();
3838 if (ClearInsertionPoint)
3839 CGF.
Builder.ClearInsertionPoint();
3845 AddrWeakObj = EnforceType(B, AddrWeakObj, PtrToIdTy);
3846 return B.CreateCall(WeakReadFn.getType(), WeakReadFn,
3853 src = EnforceType(B, src, IdTy);
3854 dst = EnforceType(B, dst, PtrToIdTy);
3855 B.CreateCall(WeakAssignFn.getType(), WeakAssignFn,
3863 src = EnforceType(B, src, IdTy);
3864 dst = EnforceType(B, dst, PtrToIdTy);
3866 assert(!threadlocal &&
"EmitObjCGlobalAssign - Threal Local API NYI");
3867 B.CreateCall(GlobalAssignFn.getType(), GlobalAssignFn,
3875 src = EnforceType(B, src, IdTy);
3876 dst = EnforceType(B, dst, IdTy);
3877 B.CreateCall(IvarAssignFn.getType(), IvarAssignFn,
3884 src = EnforceType(B, src, IdTy);
3885 dst = EnforceType(B, dst, PtrToIdTy);
3886 B.CreateCall(StrongCastAssignFn.getType(), StrongCastAssignFn,
3895 DestPtr = EnforceType(B, DestPtr, PtrTy);
3896 SrcPtr = EnforceType(B, SrcPtr, PtrTy);
3898 B.CreateCall(MemMoveFn.getType(), MemMoveFn,
3902 llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
3905 const std::string Name = GetIVarOffsetVariableName(ID, Ivar);
3909 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
3910 if (!IvarOffsetPointer)
3911 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule,
3912 llvm::Type::getInt32PtrTy(VMContext),
false,
3914 return IvarOffsetPointer;
3921 unsigned CVRQualifiers) {
3953 if (RuntimeVersion < 10 ||
3955 return CGF.
Builder.CreateZExtOrBitCast(
3958 ObjCIvarOffsetVariable(Interface, Ivar),
3962 std::string name =
"__objc_ivar_offset_value_" +
3965 llvm::Value *Offset = TheModule.getGlobalVariable(name);
3967 auto GV =
new llvm::GlobalVariable(TheModule, IntTy,
3968 false, llvm::GlobalValue::LinkOnceAnyLinkage,
3969 llvm::Constant::getNullValue(IntTy), name);
3974 if (Offset->getType() != PtrDiffTy)
3975 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
3979 return llvm::ConstantInt::get(PtrDiffTy, Offset,
true);
3985 switch (Runtime.getKind()) {
3987 if (Runtime.getVersion() >= VersionTuple(2, 0))
3988 return new CGObjCGNUstep2(CGM);
3989 return new CGObjCGNUstep(CGM);
3992 return new CGObjCGCC(CGM);
3995 return new CGObjCObjFW(CGM);
4001 llvm_unreachable(
"these runtimes are not GNU runtimes");
4003 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.
Expr - 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