;
42using namespaceCodeGen;
49classLazyRuntimeFunction {
51llvm::FunctionType *FTy =
nullptr;
52 const char*FunctionName =
nullptr;
53llvm::FunctionCallee
Function=
nullptr;
56LazyRuntimeFunction() =
default;
60 template<
typename... Tys>
61 voidinit(
CodeGenModule*Mod,
const char*name, llvm::Type *RetTy,
66 if(
sizeof...(Tys)) {
68FTy = llvm::FunctionType::get(RetTy, ArgTys,
false);
71FTy = llvm::FunctionType::get(RetTy, {},
false);
75llvm::FunctionType *getType() {
returnFTy; }
79 operatorllvm::FunctionCallee() {
96llvm::Module &TheModule;
99llvm::StructType *ObjCSuperTy;
102llvm::PointerType *PtrToObjCSuperTy;
106llvm::PointerType *SelectorTy;
108llvm::Type *SelectorElemTy;
111llvm::IntegerType *Int8Ty;
114llvm::PointerType *PtrToInt8Ty;
116llvm::StructType *ProtocolTy;
118llvm::PointerType *ProtocolPtrTy;
124llvm::PointerType *IMPTy;
129llvm::PointerType *IdTy;
131llvm::Type *IdElemTy;
134llvm::PointerType *PtrToIdTy;
139llvm::IntegerType *IntTy;
143llvm::PointerType *PtrTy;
147llvm::IntegerType *LongTy;
149llvm::IntegerType *SizeTy;
151llvm::IntegerType *IntPtrTy;
153llvm::IntegerType *PtrDiffTy;
156llvm::PointerType *PtrToIntTy;
160llvm::IntegerType *Int32Ty;
162llvm::IntegerType *Int64Ty;
164llvm::StructType *PropertyMetadataTy;
168 unsignedmsgSendMDKind;
171 boolusesSEHExceptions;
173 boolusesCxxExceptions;
178 return(R.
getKind() == kind) &&
179(R.
getVersion() >= VersionTuple(major, minor));
182std::string ManglePublicSymbol(StringRef Name) {
183 return(StringRef(CGM.
getTriple().isOSBinFormatCOFF() ?
"$_":
"._") + Name).str();
186std::string SymbolForProtocol(Twine Name) {
187 return(ManglePublicSymbol(
"OBJC_PROTOCOL_") + Name).str();
190std::string SymbolForProtocolRef(StringRef Name) {
191 return(ManglePublicSymbol(
"OBJC_REF_PROTOCOL_") + Name).str();
198llvm::Constant *MakeConstantString(StringRef Str,
const char*Name =
"") {
201 returnArray.getPointer();
208llvm::Constant *ExportUniqueString(
conststd::string &Str,
209 conststd::string &prefix,
210 boolPrivate=
false) {
211std::string
name= prefix + Str;
212 auto*ConstStr = TheModule.getGlobalVariable(name);
214llvm::Constant *value = llvm::ConstantDataArray::getString(VMContext,Str);
215 auto*GV =
newllvm::GlobalVariable(TheModule, value->getType(),
true,
216llvm::GlobalValue::LinkOnceODRLinkage, value, name);
217GV->setComdat(TheModule.getOrInsertComdat(name));
219GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
227 const Decl*Container) {
230std::string NameAndAttributes;
231std::string TypeStr =
233NameAndAttributes +=
'\0';
234NameAndAttributes += TypeStr.length() + 3;
235NameAndAttributes += TypeStr;
236NameAndAttributes +=
'\0';
238 returnMakeConstantString(NameAndAttributes);
247 intattrs =
property->getPropertyAttributes();
250attrs &= ~ObjCPropertyAttribute::kind_copy;
251attrs &= ~ObjCPropertyAttribute::kind_retain;
252attrs &= ~ObjCPropertyAttribute::kind_weak;
253attrs &= ~ObjCPropertyAttribute::kind_strong;
256Fields.addInt(Int8Ty, attrs & 0xff);
262attrs |= isSynthesized ? (1<<0) : 0;
263attrs |= isDynamic ? (1<<1) : 0;
266Fields.addInt(Int8Ty, attrs & 0xff);
268Fields.addInt(Int8Ty, 0);
269Fields.addInt(Int8Ty, 0);
272 virtualllvm::Constant *GenerateCategoryProtocolList(
const 277Fields.addInt(IntTy, count);
280 constllvm::DataLayout &DL = TheModule.getDataLayout();
281Fields.addInt(IntTy, DL.getTypeSizeInBits(PropertyMetadataTy) /
287 returnFields.
beginArray(PropertyMetadataTy);
292 boolisSynthesized=
true,
bool 294 autoFields = PropertiesArray.
beginStruct(PropertyMetadataTy);
296Fields.add(MakePropertyEncodingString(property, OCD));
297PushPropertyAttributes(Fields, property, isSynthesized, isDynamic);
301llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
302Fields.add(MakeConstantString(accessor->getSelector().getAsString()));
303Fields.add(TypeEncoding);
317llvm::Value *EnforceType(
CGBuilderTy&B, llvm::Value *
V, llvm::Type *Ty) {
318 if(
V->getType() == Ty)
320 returnB.CreateBitCast(
V, Ty);
324llvm::Constant *Zeros[2];
326llvm::Constant *NULLPtr;
328llvm::LLVMContext &VMContext;
336llvm::GlobalAlias *ClassPtrAlias;
341llvm::GlobalAlias *MetaClassPtrAlias;
343std::vector<llvm::Constant*> Classes;
345std::vector<llvm::Constant*> Categories;
348std::vector<llvm::Constant*> ConstantStrings;
352llvm::StringMap<llvm::Constant*> ObjCStrings;
354llvm::StringMap<llvm::Constant*> ExistingProtocols;
360 typedefstd::pair<std::string, llvm::GlobalAlias*> TypedSelector;
364 typedefllvm::DenseMap<Selector, SmallVector<TypedSelector, 2> >
372 SelectorRetainSel, ReleaseSel, AutoreleaseSel;
376LazyRuntimeFunction IvarAssignFn, StrongCastAssignFn, MemMoveFn, WeakReadFn,
377WeakAssignFn, GlobalAssignFn;
379 typedefstd::pair<std::string, std::string> ClassAliasPair;
381std::vector<ClassAliasPair> ClassAliases;
385LazyRuntimeFunction ExceptionThrowFn;
388LazyRuntimeFunction ExceptionReThrowFn;
391LazyRuntimeFunction EnterCatchFn;
394LazyRuntimeFunction ExitCatchFn;
396LazyRuntimeFunction SyncEnterFn;
398LazyRuntimeFunction SyncExitFn;
403LazyRuntimeFunction EnumerationMutationFn;
406LazyRuntimeFunction GetPropertyFn;
409LazyRuntimeFunction SetPropertyFn;
411LazyRuntimeFunction GetStructPropertyFn;
413LazyRuntimeFunction SetStructPropertyFn;
425 const intProtocolVersion;
428 const intClassABIVersion;
444llvm::Constant *GenerateMethodList(StringRef ClassName,
445StringRef CategoryName,
447 boolisClassMethodList);
452 virtualllvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName);
456llvm::Constant *GeneratePropertyList(
const Decl*Container,
458 boolisClassProperty=
false,
459 boolprotocolOptionalProperties=
false);
469 voidGenerateProtocolHolderCategory();
472llvm::Constant *GenerateClassStructure(
473llvm::Constant *MetaClass,
474llvm::Constant *SuperClass,
477llvm::Constant *Version,
478llvm::Constant *InstanceSize,
479llvm::Constant *IVars,
480llvm::Constant *Methods,
481llvm::Constant *Protocols,
482llvm::Constant *IvarOffsets,
483llvm::Constant *Properties,
484llvm::Constant *StrongIvarBitmap,
485llvm::Constant *WeakIvarBitmap,
486 boolisMeta=
false);
490 virtualllvm::Constant *GenerateProtocolMethodList(
494 voidEmitProtocolMethodList(
T&&Methods, llvm::Constant *&
Required,
498 for(
const auto*I : Methods)
500OptionalMethods.push_back(I);
502RequiredMethods.push_back(I);
503 Required= GenerateProtocolMethodList(RequiredMethods);
504 Optional= GenerateProtocolMethodList(OptionalMethods);
510 conststd::string &TypeEncoding);
517 conststd::string Name =
"__objc_ivar_offset_"+
ID->getNameAsString()
526 voidEmitClassRef(
conststd::string &className);
530 conststd::string &Name,
boolisWeak);
536llvm::Value *&Receiver,
539MessageSendInfo &MSI) = 0;
547MessageSendInfo &MSI) = 0;
564 unsignedprotocolClassVersion,
unsignedclassABI=1);
571llvm::Value *Receiver,
const CallArgList&CallArgs,
578 boolisCategoryImpl, llvm::Value *Receiver,
587 virtualllvm::Constant *GetConstantSelector(
SelectorSel,
588 conststd::string &TypeEncoding) {
589llvm_unreachable(
"Runtime unable to generate constant selector");
601llvm::DenseMap<const ObjCMethodDecl *, llvm::Function *>
602DirectMethodDefinitions;
623 boolcopy)
override;
636 boolClearInsertionPoint=
true)
override;
638 AddressAddrWeakObj)
override;
640llvm::Value *src,
Addressdst)
override;
642llvm::Value *src,
Addressdest,
643 boolthreadlocal=
false)
override;
645 Addressdest, llvm::Value *ivarOffset)
override;
647llvm::Value *src,
Addressdest)
override;
650llvm::Value *Size)
override;
653 unsignedCVRQualifiers)
override;
680classCGObjCGCC :
publicCGObjCGNU {
683LazyRuntimeFunction MsgLookupFn;
687LazyRuntimeFunction MsgLookupSuperFn;
691llvm::Value *cmd, llvm::MDNode *node,
692MessageSendInfo &MSI)
override{
694llvm::Value *args[] = {
695EnforceType(Builder, Receiver, IdTy),
696EnforceType(Builder, cmd, SelectorTy) };
698imp->setMetadata(msgSendMDKind, node);
703llvm::Value *cmd, MessageSendInfo &MSI)
override{
705llvm::Value *lookupArgs[] = {
706EnforceType(Builder, ObjCSuper.
emitRawPointer(CGF), PtrToObjCSuperTy),
714MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
716MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
717PtrToObjCSuperTy, SelectorTy);
722classCGObjCGNUstep :
publicCGObjCGNU {
725LazyRuntimeFunction SlotLookupFn;
730LazyRuntimeFunction SlotLookupSuperFn;
732LazyRuntimeFunction SetPropertyAtomic;
734LazyRuntimeFunction SetPropertyAtomicCopy;
736LazyRuntimeFunction SetPropertyNonAtomic;
738LazyRuntimeFunction SetPropertyNonAtomicCopy;
741LazyRuntimeFunction CxxAtomicObjectGetFn;
744LazyRuntimeFunction CxxAtomicObjectSetFn;
749llvm::Type *SlotStructTy;
752llvm::Constant *GetEHType(
QualType T)
override;
756llvm::Value *cmd, llvm::MDNode *node,
757MessageSendInfo &MSI)
override{
759llvm::FunctionCallee LookupFn = SlotLookupFn;
764Builder.CreateStore(Receiver, ReceiverPtr);
771self = llvm::ConstantPointerNull::get(IdTy);
775 if(
auto*LookupFn2 = dyn_cast<llvm::Function>(LookupFn.getCallee()))
776LookupFn2->addParamAttr(
778llvm::CaptureInfo::none()));
780llvm::Value *args[] = {
781EnforceType(Builder, ReceiverPtr.
getPointer(), PtrToIdTy),
782EnforceType(Builder, cmd, SelectorTy),
783EnforceType(Builder, self, IdTy)};
785slot->setOnlyReadsMemory();
786slot->setMetadata(msgSendMDKind, node);
789llvm::Value *imp = Builder.CreateAlignedLoad(
790IMPTy, Builder.CreateStructGEP(SlotStructTy, slot, 4),
795Receiver = Builder.CreateLoad(ReceiverPtr,
true);
801MessageSendInfo &MSI)
override{
803llvm::Value *lookupArgs[] = {ObjCSuper.
emitRawPointer(CGF), cmd};
805llvm::CallInst *slot =
807slot->setOnlyReadsMemory();
809 returnBuilder.CreateAlignedLoad(
810IMPTy, Builder.CreateStructGEP(SlotStructTy, slot, 4),
815CGObjCGNUstep(
CodeGenModule&Mod) : CGObjCGNUstep(Mod, 9, 3, 1) {}
816CGObjCGNUstep(
CodeGenModule&Mod,
unsignedABI,
unsignedProtocolABI,
818CGObjCGNU(Mod, ABI, ProtocolABI, ClassABI) {
821SlotStructTy = llvm::StructType::get(PtrTy, PtrTy, PtrTy, IntTy, IMPTy);
822SlotTy = llvm::PointerType::getUnqual(SlotStructTy);
824SlotLookupFn.init(&CGM,
"objc_msg_lookup_sender", SlotTy, PtrToIdTy,
827SlotLookupSuperFn.init(&CGM,
"objc_slot_lookup_super", SlotTy,
828PtrToObjCSuperTy, SelectorTy);
830llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
831 if(usesCxxExceptions) {
833EnterCatchFn.init(&CGM,
"__cxa_begin_catch", PtrTy, PtrTy);
835ExitCatchFn.init(&CGM,
"__cxa_end_catch", VoidTy);
837ExceptionReThrowFn.init(&CGM,
"__cxa_rethrow", PtrTy);
838}
else if(usesSEHExceptions) {
840ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy);
843EnterCatchFn.init(&CGM,
"__cxa_begin_catch", PtrTy, PtrTy);
845ExitCatchFn.init(&CGM,
"__cxa_end_catch", VoidTy);
847ExceptionReThrowFn.init(&CGM,
"_Unwind_Resume_or_Rethrow", VoidTy,
849}
else if(R.
getVersion() >= VersionTuple(1, 7)) {
851EnterCatchFn.init(&CGM,
"objc_begin_catch", IdTy, PtrTy);
853ExitCatchFn.init(&CGM,
"objc_end_catch", VoidTy);
855ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy, PtrTy);
857SetPropertyAtomic.init(&CGM,
"objc_setProperty_atomic", VoidTy, IdTy,
858SelectorTy, IdTy, PtrDiffTy);
859SetPropertyAtomicCopy.init(&CGM,
"objc_setProperty_atomic_copy", VoidTy,
860IdTy, SelectorTy, IdTy, PtrDiffTy);
861SetPropertyNonAtomic.init(&CGM,
"objc_setProperty_nonatomic", VoidTy,
862IdTy, SelectorTy, IdTy, PtrDiffTy);
863SetPropertyNonAtomicCopy.init(&CGM,
"objc_setProperty_nonatomic_copy",
864VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy);
867CxxAtomicObjectSetFn.init(&CGM,
"objc_setCppObjectAtomic", VoidTy, PtrTy,
871CxxAtomicObjectGetFn.init(&CGM,
"objc_getCppObjectAtomic", VoidTy, PtrTy,
875llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override{
880 returnCxxAtomicObjectGetFn;
883llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override{
888 returnCxxAtomicObjectSetFn;
891llvm::FunctionCallee GetOptimizedPropertySetFunction(
boolatomic,
892 boolcopy)
override{
896assert ((CGM.
getLangOpts().getGC() == LangOptions::NonGC));
903 if(copy)
returnSetPropertyAtomicCopy;
904 returnSetPropertyAtomic;
907 returncopy ? SetPropertyNonAtomicCopy : SetPropertyNonAtomic;
914classCGObjCGNUstep2 :
publicCGObjCGNUstep {
919ClassReferenceSection,
922ProtocolReferenceSection,
924ConstantStringSection
929ClassFlagMeta = (1 << 0),
932ClassFlagInitialized = (1 << 8),
934 static const char*
constSectionsBaseNames[8];
935 static const char*
constPECOFFSectionsBaseNames[8];
936 template<SectionKind K>
937std::string sectionName() {
938 if(CGM.
getTriple().isOSBinFormatCOFF()) {
939std::string
name(PECOFFSectionsBaseNames[K]);
943 returnSectionsBaseNames[K];
948LazyRuntimeFunction MsgLookupSuperFn;
950LazyRuntimeFunction SentInitializeFn;
954 boolEmittedProtocol =
false;
959 boolEmittedProtocolRef =
false;
963 boolEmittedClass =
false;
967 typedefstd::pair<std::string, std::pair<llvm::GlobalVariable*, int>>
969std::vector<EarlyInitPair> EarlyInitList;
971std::string SymbolForClassRef(StringRef Name,
boolisWeak) {
973 return(ManglePublicSymbol(
"OBJC_WEAK_REF_CLASS_") + Name).str();
975 return(ManglePublicSymbol(
"OBJC_REF_CLASS_") + Name).str();
978std::string SymbolForClass(StringRef Name) {
979 return(ManglePublicSymbol(
"OBJC_CLASS_") + Name).str();
981 voidCallRuntimeFunction(
CGBuilderTy&B, StringRef FunctionName,
984 for(
auto*Arg : Args)
985Types.push_back(Arg->getType());
986llvm::FunctionType *FT = llvm::FunctionType::get(B.getVoidTy(), Types,
989B.CreateCall(Fn, Args);
998llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
999 if(old != ObjCStrings.end())
1007(LiteralLength < 9) && !isNonASCII) {
1013 for(
unsignedi=0 ; i<LiteralLength ; i++)
1014str |= ((uint64_t)SL->
getCodeUnit(i)) << ((64 - 4 - 3) - (i*7));
1016str |= LiteralLength << 3;
1019 auto*ObjCStr = llvm::ConstantExpr::getIntToPtr(
1020llvm::ConstantInt::get(Int64Ty, str), IdTy);
1021ObjCStrings[Str] = ObjCStr;
1027 if(StringClass.empty()) StringClass =
"NSConstantString";
1029std::string Sym = SymbolForClass(StringClass);
1031llvm::Constant *
isa= TheModule.getNamedGlobal(Sym);
1034 isa=
newllvm::GlobalVariable(TheModule, IdTy,
false,
1035llvm::GlobalValue::ExternalLinkage,
nullptr, Sym);
1036 if(CGM.
getTriple().isOSBinFormatCOFF()) {
1037cast<llvm::GlobalValue>(isa)->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
1052 autoFields = Builder.beginStruct();
1053 if(!CGM.
getTriple().isOSBinFormatCOFF()) {
1056Fields.addNullPointer(PtrTy);
1063 unsignedNumU8CodeUnits = Str.size();
1068 constllvm::UTF8 *FromPtr = (
constllvm::UTF8 *)Str.data();
1069llvm::UTF16 *ToPtr = &ToBuf[0];
1070(void)llvm::ConvertUTF8toUTF16(&FromPtr, FromPtr + NumU8CodeUnits,
1071&ToPtr, ToPtr + NumU8CodeUnits, llvm::strictConversion);
1072 uint32_tStringLength = ToPtr - &ToBuf[0];
1076Fields.addInt(Int32Ty, 2);
1078Fields.addInt(Int32Ty, StringLength);
1080Fields.addInt(Int32Ty, StringLength * 2);
1082Fields.addInt(Int32Ty, 0);
1085 auto*
C= llvm::ConstantDataArray::get(VMContext, Arr);
1086 auto*Buffer =
newllvm::GlobalVariable(TheModule,
C->getType(),
1087 true, llvm::GlobalValue::PrivateLinkage,
C,
".str");
1088Buffer->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1092Fields.addInt(Int32Ty, 0);
1094Fields.addInt(Int32Ty, Str.size());
1096Fields.addInt(Int32Ty, Str.size());
1098Fields.addInt(Int32Ty, 0);
1100Fields.add(MakeConstantString(Str));
1102std::string StringName;
1105StringName =
".objc_str_";
1106 for(
inti=0,e=Str.size() ; i<e ; ++i) {
1107 unsigned char c= Str[i];
1110 else if(
c==
' ')
1118llvm::GlobalVariable *ObjCStrGV =
1120 isNamed? StringRef(StringName) :
".objc_string",
1121Align,
false,
isNamed? llvm::GlobalValue::LinkOnceODRLinkage
1122: llvm::GlobalValue::PrivateLinkage);
1123ObjCStrGV->setSection(sectionName<ConstantStringSection>());
1125ObjCStrGV->setComdat(TheModule.getOrInsertComdat(StringName));
1126ObjCStrGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1128 if(CGM.
getTriple().isOSBinFormatCOFF()) {
1129std::pair<llvm::GlobalVariable*, int>
v{ObjCStrGV, 0};
1130EarlyInitList.emplace_back(Sym,
v);
1132ObjCStrings[Str] = ObjCStrGV;
1133ConstantStrings.push_back(ObjCStrGV);
1140 boolisSynthesized=
true,
bool 1141isDynamic=
true)
override{
1150 autoFields = PropertiesArray.
beginStruct(PropertyMetadataTy);
1153std::string TypeStr =
1155Fields.add(MakeConstantString(TypeStr));
1156std::string typeStr;
1158Fields.add(MakeConstantString(typeStr));
1162Fields.add(GetConstantSelector(accessor->getSelector(), TypeStr));
1164Fields.add(NULLPtr);
1179llvm::StructType *ObjCMethodDescTy =
1181{ PtrToInt8Ty, PtrToInt8Ty });
1190 autoMethodList = Builder.beginStruct();
1192MethodList.addInt(IntTy, Methods.size());
1194 constllvm::DataLayout &DL = TheModule.getDataLayout();
1195MethodList.addInt(IntTy, DL.getTypeSizeInBits(ObjCMethodDescTy) /
1198 autoMethodArray = MethodList.beginArray(ObjCMethodDescTy);
1199 for(
auto*M : Methods) {
1200 autoMethod = MethodArray.beginStruct(ObjCMethodDescTy);
1201Method.add(CGObjCGNU::GetConstantSelector(M));
1203Method.finishAndAddTo(MethodArray);
1205MethodArray.finishAndAddTo(MethodList);
1206 returnMethodList.finishAndCreateGlobal(
".objc_protocol_method_list",
1212 autoRuntimeProtocols = GetRuntimeProtocolList(ReferencedProtocols.begin(),
1213ReferencedProtocols.end());
1215 for(
const auto*PI : RuntimeProtocols)
1216Protocols.push_back(GenerateProtocolRef(PI));
1217 returnGenerateProtocolList(Protocols);
1221llvm::Value *cmd, MessageSendInfo &MSI)
override{
1224llvm::Value *lookupArgs[] = {
1231llvm::GlobalVariable *GetClassVar(StringRef Name,
boolisWeak=
false) {
1232std::string SymbolName = SymbolForClassRef(Name, isWeak);
1233 auto*ClassSymbol = TheModule.getNamedGlobal(SymbolName);
1236ClassSymbol =
newllvm::GlobalVariable(TheModule,
1237IdTy,
false, llvm::GlobalValue::ExternalLinkage,
1238 nullptr, SymbolName);
1244ClassSymbol->setInitializer(
newllvm::GlobalVariable(TheModule,
1245Int8Ty,
false, llvm::GlobalValue::ExternalWeakLinkage,
1246 nullptr, SymbolForClass(Name)));
1248 if(CGM.
getTriple().isOSBinFormatCOFF()) {
1254 for(
const auto*Result : DC->
lookup(&II))
1255 if((OID = dyn_cast<ObjCInterfaceDecl>(Result)))
1261assert(OID &&
"Failed to find ObjCInterfaceDecl");
1263 if(OIDDef !=
nullptr)
1266 auto Storage= llvm::GlobalValue::DefaultStorageClass;
1267 if(OID->
hasAttr<DLLImportAttr>())
1268 Storage= llvm::GlobalValue::DLLImportStorageClass;
1269 else if(OID->
hasAttr<DLLExportAttr>())
1270 Storage= llvm::GlobalValue::DLLExportStorageClass;
1272cast<llvm::GlobalValue>(ClassSymbol)->setDLLStorageClass(Storage);
1275assert(ClassSymbol->getName() == SymbolName);
1279 conststd::string &Name,
1280 boolisWeak)
override{
1292 switch(Ownership) {
1314llvm_unreachable(
"Method should not be called!");
1317llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName)
override{
1318std::string Name = SymbolForProtocol(ProtocolName);
1319 auto*GV = TheModule.getGlobalVariable(Name);
1322GV =
newllvm::GlobalVariable(TheModule, ProtocolTy,
false,
1323llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
1330llvm::StringMap<llvm::Constant*> ExistingProtocolRefs;
1335 auto*&Ref = ExistingProtocolRefs[Name];
1337 auto*&
Protocol= ExistingProtocols[Name];
1339 Protocol= GenerateProtocolRef(PD);
1340std::string RefName = SymbolForProtocolRef(Name);
1341assert(!TheModule.getGlobalVariable(RefName));
1343 autoGV =
newllvm::GlobalVariable(TheModule, ProtocolPtrTy,
false,
1344llvm::GlobalValue::LinkOnceODRLinkage,
1346GV->setComdat(TheModule.getOrInsertComdat(RefName));
1347GV->setSection(sectionName<ProtocolReferenceSection>());
1351EmittedProtocolRef =
true;
1357llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(ProtocolPtrTy,
1359llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
1362 autoProtocolBuilder = builder.beginStruct();
1363ProtocolBuilder.addNullPointer(PtrTy);
1364ProtocolBuilder.addInt(SizeTy, Protocols.size());
1365ProtocolBuilder.add(ProtocolArray);
1366 returnProtocolBuilder.finishAndCreateGlobal(
".objc_protocol_list",
1373llvm::Constant *GenerateProtocolRef(
const ObjCProtocolDecl*PD)
override{
1375 auto*&
Protocol= ExistingProtocols[ProtocolName];
1379EmittedProtocol =
true;
1381 autoSymName = SymbolForProtocol(ProtocolName);
1382 auto*OldGV = TheModule.getGlobalVariable(SymName);
1392 Protocol=
newllvm::GlobalVariable(TheModule, ProtocolTy,
1394llvm::GlobalValue::ExternalLinkage,
nullptr, SymName);
1399 autoRuntimeProtocols =
1401 for(
const auto*PI : RuntimeProtocols)
1402Protocols.push_back(GenerateProtocolRef(PI));
1403llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
1406llvm::Constant *InstanceMethodList, *OptionalInstanceMethodList;
1407llvm::Constant *ClassMethodList, *OptionalClassMethodList;
1409OptionalInstanceMethodList);
1410EmitProtocolMethodList(PD->
class_methods(), ClassMethodList,
1411OptionalClassMethodList);
1416 autoProtocolBuilder = builder.beginStruct();
1417ProtocolBuilder.add(llvm::ConstantExpr::getIntToPtr(
1418llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
1419ProtocolBuilder.add(MakeConstantString(ProtocolName));
1420ProtocolBuilder.add(ProtocolList);
1421ProtocolBuilder.add(InstanceMethodList);
1422ProtocolBuilder.add(ClassMethodList);
1423ProtocolBuilder.add(OptionalInstanceMethodList);
1424ProtocolBuilder.add(OptionalClassMethodList);
1426ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
false,
false));
1428ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
false,
true));
1430ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
true,
false));
1432ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
true,
true));
1434 auto*GV = ProtocolBuilder.finishAndCreateGlobal(SymName,
1436GV->setSection(sectionName<ProtocolSection>());
1437GV->setComdat(TheModule.getOrInsertComdat(SymName));
1439OldGV->replaceAllUsesWith(GV);
1440OldGV->removeFromParent();
1441GV->setName(SymName);
1447 conststd::string &TypeEncoding)
override{
1448 returnGetConstantSelector(Sel, TypeEncoding);
1450std::string GetSymbolNameForTypeEncoding(
conststd::string &TypeEncoding) {
1451std::string MangledTypes = std::string(TypeEncoding);
1456 if(CGM.
getTriple().isOSBinFormatELF())
1457std::replace(MangledTypes.begin(), MangledTypes.end(),
'@',
'\1');
1460std::replace(MangledTypes.begin(), MangledTypes.end(),
'=',
'\2');
1461 returnMangledTypes;
1463llvm::Constant *GetTypeString(llvm::StringRef TypeEncoding) {
1464 if(TypeEncoding.empty())
1466std::string MangledTypes =
1467GetSymbolNameForTypeEncoding(std::string(TypeEncoding));
1468std::string TypesVarName =
".objc_sel_types_"+ MangledTypes;
1469 auto*TypesGlobal = TheModule.getGlobalVariable(TypesVarName);
1471llvm::Constant *
Init= llvm::ConstantDataArray::getString(VMContext,
1473 auto*GV =
newllvm::GlobalVariable(TheModule,
Init->getType(),
1474 true, llvm::GlobalValue::LinkOnceODRLinkage,
Init, TypesVarName);
1475GV->setComdat(TheModule.getOrInsertComdat(TypesVarName));
1476GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1481llvm::Constant *GetConstantSelector(
SelectorSel,
1482 conststd::string &TypeEncoding)
override{
1483std::string MangledTypes = GetSymbolNameForTypeEncoding(TypeEncoding);
1484 autoSelVarName = (StringRef(
".objc_selector_") + Sel.
getAsString() +
"_"+
1485MangledTypes).str();
1486 if(
auto*GV = TheModule.getNamedGlobal(SelVarName))
1489 autoSelBuilder = builder.beginStruct();
1490SelBuilder.add(ExportUniqueString(Sel.
getAsString(),
".objc_sel_name_",
1492SelBuilder.add(GetTypeString(TypeEncoding));
1493 auto*GV = SelBuilder.finishAndCreateGlobal(SelVarName,
1494CGM.
getPointerAlign(),
false, llvm::GlobalValue::LinkOnceODRLinkage);
1495GV->setComdat(TheModule.getOrInsertComdat(SelVarName));
1496GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1497GV->setSection(sectionName<SelectorSection>());
1500llvm::StructType *emptyStruct =
nullptr;
1509std::pair<llvm::Constant*,llvm::Constant*>
1510GetSectionBounds(StringRef Section) {
1511 if(CGM.
getTriple().isOSBinFormatCOFF()) {
1512 if(emptyStruct ==
nullptr) {
1513emptyStruct = llvm::StructType::create(
1514VMContext, {},
".objc_section_sentinel",
true);
1516 autoZeroInit = llvm::Constant::getNullValue(emptyStruct);
1517 autoSym = [&](StringRef Prefix, StringRef SecSuffix) {
1518 auto*Sym =
newllvm::GlobalVariable(TheModule, emptyStruct,
1520llvm::GlobalValue::LinkOnceODRLinkage, ZeroInit, Prefix +
1522Sym->setVisibility(llvm::GlobalValue::HiddenVisibility);
1523Sym->setSection((Section + SecSuffix).str());
1524Sym->setComdat(TheModule.getOrInsertComdat((Prefix +
1529 return{ Sym(
"__start_",
"$a"), Sym(
"__stop",
"$z") };
1531 auto*Start =
newllvm::GlobalVariable(TheModule, PtrTy,
1533llvm::GlobalValue::ExternalLinkage,
nullptr, StringRef(
"__start_") +
1535Start->setVisibility(llvm::GlobalValue::HiddenVisibility);
1536 auto*Stop =
newllvm::GlobalVariable(TheModule, PtrTy,
1538llvm::GlobalValue::ExternalLinkage,
nullptr, StringRef(
"__stop_") +
1540Stop->setVisibility(llvm::GlobalValue::HiddenVisibility);
1541 return{ Start, Stop };
1546llvm::Function *ModuleInitFunction()
override{
1547llvm::Function *LoadFunction = llvm::Function::Create(
1548llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
1549llvm::GlobalValue::LinkOnceODRLinkage,
".objcv2_load_function",
1551LoadFunction->setVisibility(llvm::GlobalValue::HiddenVisibility);
1552LoadFunction->setComdat(TheModule.getOrInsertComdat(
".objcv2_load_function"));
1554llvm::BasicBlock *EntryBB =
1555llvm::BasicBlock::Create(VMContext,
"entry", LoadFunction);
1557B.SetInsertPoint(EntryBB);
1559 autoInitStructBuilder = builder.beginStruct();
1560InitStructBuilder.addInt(Int64Ty, 0);
1561 auto§ionVec = CGM.
getTriple().isOSBinFormatCOFF() ? PECOFFSectionsBaseNames : SectionsBaseNames;
1562 for(
auto*
s: sectionVec) {
1563 autobounds = GetSectionBounds(
s);
1564InitStructBuilder.add(bounds.first);
1565InitStructBuilder.add(bounds.second);
1567 auto*InitStruct = InitStructBuilder.finishAndCreateGlobal(
".objc_init",
1568CGM.
getPointerAlign(),
false, llvm::GlobalValue::LinkOnceODRLinkage);
1569InitStruct->setVisibility(llvm::GlobalValue::HiddenVisibility);
1570InitStruct->setComdat(TheModule.getOrInsertComdat(
".objc_init"));
1572CallRuntimeFunction(B,
"__objc_load", {InitStruct});;
1579 auto*InitVar =
newllvm::GlobalVariable(TheModule, LoadFunction->getType(),
1580 false, llvm::GlobalValue::LinkOnceAnyLinkage,
1581LoadFunction,
".objc_ctor");
1584assert(InitVar->getName() ==
".objc_ctor");
1590 if(CGM.
getTriple().isOSBinFormatCOFF())
1591InitVar->setSection(
".CRT$XCLz");
1595InitVar->setSection(
".init_array");
1597InitVar->setSection(
".ctors");
1599InitVar->setVisibility(llvm::GlobalValue::HiddenVisibility);
1600InitVar->setComdat(TheModule.getOrInsertComdat(
".objc_ctor"));
1602 for(
auto*
C: Categories) {
1603 auto*Cat = cast<llvm::GlobalVariable>(
C->stripPointerCasts());
1604Cat->setSection(sectionName<CategorySection>());
1608StringRef Section) {
1609 autonullBuilder = builder.beginStruct();
1610 for(
auto*F :
Init)
1612 autoGV = nullBuilder.finishAndCreateGlobal(Name, CGM.
getPointerAlign(),
1613 false, llvm::GlobalValue::LinkOnceODRLinkage);
1614GV->setSection(Section);
1615GV->setComdat(TheModule.getOrInsertComdat(Name));
1616GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1620 for(
autoclsAlias : ClassAliases)
1621createNullGlobal(std::string(
".objc_class_alias") +
1622clsAlias.second, { MakeConstantString(clsAlias.second),
1623GetClassVar(clsAlias.first) }, sectionName<ClassAliasSection>());
1628 if(!CGM.
getTriple().isOSBinFormatCOFF()) {
1629createNullGlobal(
".objc_null_selector", {NULLPtr, NULLPtr},
1630sectionName<SelectorSection>());
1631 if(Categories.empty())
1632createNullGlobal(
".objc_null_category", {NULLPtr, NULLPtr,
1633NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr},
1634sectionName<CategorySection>());
1635 if(!EmittedClass) {
1636createNullGlobal(
".objc_null_cls_init_ref", NULLPtr,
1637sectionName<ClassSection>());
1638createNullGlobal(
".objc_null_class_ref", { NULLPtr, NULLPtr },
1639sectionName<ClassReferenceSection>());
1641 if(!EmittedProtocol)
1642createNullGlobal(
".objc_null_protocol", {NULLPtr, NULLPtr, NULLPtr,
1643NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr,
1644NULLPtr}, sectionName<ProtocolSection>());
1645 if(!EmittedProtocolRef)
1646createNullGlobal(
".objc_null_protocol_ref", {NULLPtr},
1647sectionName<ProtocolReferenceSection>());
1648 if(ClassAliases.empty())
1649createNullGlobal(
".objc_null_class_alias", { NULLPtr, NULLPtr },
1650sectionName<ClassAliasSection>());
1651 if(ConstantStrings.empty()) {
1652 autoi32Zero = llvm::ConstantInt::get(Int32Ty, 0);
1653createNullGlobal(
".objc_null_constant_string", { NULLPtr, i32Zero,
1654i32Zero, i32Zero, i32Zero, NULLPtr },
1655sectionName<ConstantStringSection>());
1658ConstantStrings.clear();
1662 if(EarlyInitList.size() > 0) {
1663 auto*
Init= llvm::Function::Create(llvm::FunctionType::get(CGM.
VoidTy,
1664{}), llvm::GlobalValue::InternalLinkage,
".objc_early_init",
1666llvm::IRBuilder<>
b(llvm::BasicBlock::Create(CGM.
getLLVMContext(),
"entry",
1668 for(
const auto&lateInit : EarlyInitList) {
1669 auto*global = TheModule.getGlobalVariable(lateInit.first);
1671llvm::GlobalVariable *GV = lateInit.second.first;
1672 b.CreateAlignedStore(
1674 b.CreateStructGEP(GV->getValueType(), GV, lateInit.second.second),
1681 auto*InitVar =
newllvm::GlobalVariable(CGM.
getModule(),
Init->getType(),
1682 true, llvm::GlobalValue::InternalLinkage,
1683 Init,
".objc_early_init_ptr");
1684InitVar->setSection(
".CRT$XCLb");
1693std::string TypeEncoding;
1695TypeEncoding = GetSymbolNameForTypeEncoding(TypeEncoding);
1696 conststd::string Name =
"__objc_ivar_offset_"+
ID->getNameAsString()
1705 conststd::string Name =
1706GetIVarOffsetVariableName(ContainingInterface, Ivar);
1707llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
1708 if(!IvarOffsetPointer) {
1709IvarOffsetPointer =
newllvm::GlobalVariable(TheModule, IntTy,
false,
1710llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
1716llvm::Value *Offset =
1718 if(Offset->getType() != PtrDiffTy)
1719Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
1724 boolIsCOFF = CGM.
getTriple().isOSBinFormatCOFF();
1730 auto*classNameConstant = MakeConstantString(className);
1733 autometaclassFields = builder.beginStruct();
1735metaclassFields.addNullPointer(PtrTy);
1737metaclassFields.addNullPointer(PtrTy);
1739metaclassFields.add(classNameConstant);
1741metaclassFields.addInt(LongTy, 0);
1744metaclassFields.addInt(LongTy, ClassFlags::ClassFlagMeta);
1748metaclassFields.addInt(LongTy, 0);
1750metaclassFields.addNullPointer(PtrTy);
1755metaclassFields.addNullPointer(PtrTy);
1760metaclassFields.add(
1761GenerateMethodList(className,
"", ClassMethods,
true));
1764metaclassFields.addNullPointer(PtrTy);
1766metaclassFields.addNullPointer(PtrTy);
1768metaclassFields.addNullPointer(PtrTy);
1770metaclassFields.addNullPointer(PtrTy);
1772metaclassFields.addNullPointer(PtrTy);
1774metaclassFields.addNullPointer(PtrTy);
1776metaclassFields.addNullPointer(PtrTy);
1778metaclassFields.addInt(LongTy, 0);
1780metaclassFields.add(GeneratePropertyList(OID, classDecl,
true));
1782 auto*metaclass = metaclassFields.finishAndCreateGlobal(
1783ManglePublicSymbol(
"OBJC_METACLASS_") + className,
1786 autoclassFields = builder.beginStruct();
1788classFields.add(metaclass);
1793llvm::Constant *SuperClass =
nullptr;
1794 if(SuperClassDecl) {
1795 autoSuperClassName = SymbolForClass(SuperClassDecl->
getNameAsString());
1796SuperClass = TheModule.getNamedGlobal(SuperClassName);
1799SuperClass =
newllvm::GlobalVariable(TheModule, PtrTy,
false,
1800llvm::GlobalValue::ExternalLinkage,
nullptr, SuperClassName);
1802 auto Storage= llvm::GlobalValue::DefaultStorageClass;
1803 if(SuperClassDecl->
hasAttr<DLLImportAttr>())
1804 Storage= llvm::GlobalValue::DLLImportStorageClass;
1805 else if(SuperClassDecl->
hasAttr<DLLExportAttr>())
1806 Storage= llvm::GlobalValue::DLLExportStorageClass;
1808cast<llvm::GlobalValue>(SuperClass)->setDLLStorageClass(Storage);
1812classFields.add(SuperClass);
1814classFields.addNullPointer(PtrTy);
1816classFields.addNullPointer(PtrTy);
1818classFields.add(classNameConstant);
1820classFields.addInt(LongTy, 0);
1823classFields.addInt(LongTy, 0);
1825 intsuperInstanceSize = !SuperClassDecl ? 0 :
1829classFields.addInt(LongTy,
1831superInstanceSize));
1834classFields.addNullPointer(PtrTy);
1839 constllvm::DataLayout &DL = TheModule.getDataLayout();
1842 autoivarListBuilder =
b.beginStruct();
1844ivarListBuilder.addInt(IntTy, ivar_count);
1846llvm::StructType *ObjCIvarTy = llvm::StructType::get(
1852ivarListBuilder.addInt(SizeTy, DL.getTypeSizeInBits(ObjCIvarTy) /
1855 autoivarArrayBuilder = ivarListBuilder.beginArray();
1858 autoivarTy = IVD->getType();
1859 autoivarBuilder = ivarArrayBuilder.beginStruct();
1861ivarBuilder.add(MakeConstantString(IVD->getNameAsString()));
1863std::string TypeStr;
1866ivarBuilder.add(MakeConstantString(TypeStr));
1868 uint64_tBaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
1869 uint64_tOffset = BaseOffset - superInstanceSize;
1870llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
1871std::string OffsetName = GetIVarOffsetVariableName(classDecl, IVD);
1872llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
1874OffsetVar->setInitializer(OffsetValue);
1876OffsetVar =
newllvm::GlobalVariable(TheModule, IntTy,
1877 false, llvm::GlobalValue::ExternalLinkage,
1878OffsetValue, OffsetName);
1879 autoivarVisibility =
1883llvm::GlobalValue::HiddenVisibility :
1884llvm::GlobalValue::DefaultVisibility;
1885OffsetVar->setVisibility(ivarVisibility);
1886 if(ivarVisibility != llvm::GlobalValue::HiddenVisibility)
1888ivarBuilder.add(OffsetVar);
1890ivarBuilder.addInt(Int32Ty,
1901ivarBuilder.addInt(Int32Ty,
1902(align << 3) | (1<<2) |
1903FlagsForOwnership(ivarTy.getQualifiers().getObjCLifetime()));
1904ivarBuilder.finishAndAddTo(ivarArrayBuilder);
1906ivarArrayBuilder.finishAndAddTo(ivarListBuilder);
1907 autoivarList = ivarListBuilder.finishAndCreateGlobal(
".objc_ivar_list",
1909llvm::GlobalValue::PrivateLinkage);
1910classFields.add(ivarList);
1914InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
1917 if(propImpl->getPropertyImplementation() ==
1920 if(OMD && OMD->hasBody())
1921InstanceMethods.push_back(OMD);
1923addIfExists(propImpl->getGetterMethodDecl());
1924addIfExists(propImpl->getSetterMethodDecl());
1927 if(InstanceMethods.size() == 0)
1928classFields.addNullPointer(PtrTy);
1931GenerateMethodList(className,
"", InstanceMethods,
false));
1934classFields.addNullPointer(PtrTy);
1936classFields.addNullPointer(PtrTy);
1938classFields.addNullPointer(PtrTy);
1940classFields.addNullPointer(PtrTy);
1942classFields.addNullPointer(PtrTy);
1944 autoRuntimeProtocols = GetRuntimeProtocolList(classDecl->
protocol_begin(),
1947 for(
const auto*I : RuntimeProtocols)
1948Protocols.push_back(GenerateProtocolRef(I));
1950 if(Protocols.empty())
1951classFields.addNullPointer(PtrTy);
1953classFields.add(GenerateProtocolList(Protocols));
1955classFields.addNullPointer(PtrTy);
1957classFields.addInt(LongTy, 0);
1959classFields.add(GeneratePropertyList(OID, classDecl));
1961llvm::GlobalVariable *classStruct =
1962classFields.finishAndCreateGlobal(SymbolForClass(className),
1965 auto*classRefSymbol = GetClassVar(className);
1966classRefSymbol->setSection(sectionName<ClassReferenceSection>());
1967classRefSymbol->setInitializer(classStruct);
1972classStruct->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1973cast<llvm::GlobalValue>(classRefSymbol)->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1977std::pair<llvm::GlobalVariable*, int>
v{classStruct, 1};
1978EarlyInitList.emplace_back(std::string(SuperClass->getName()),
1987 if(ClassPtrAlias) {
1988ClassPtrAlias->replaceAllUsesWith(classStruct);
1989ClassPtrAlias->eraseFromParent();
1990ClassPtrAlias =
nullptr;
1992 if(
autoPlaceholder =
1993TheModule.getNamedGlobal(SymbolForClass(className)))
1994 if(Placeholder != classStruct) {
1995Placeholder->replaceAllUsesWith(classStruct);
1996Placeholder->eraseFromParent();
1997classStruct->setName(SymbolForClass(className));
1999 if(MetaClassPtrAlias) {
2000MetaClassPtrAlias->replaceAllUsesWith(metaclass);
2001MetaClassPtrAlias->eraseFromParent();
2002MetaClassPtrAlias =
nullptr;
2004assert(classStruct->getName() == SymbolForClass(className));
2006 autoclassInitRef =
newllvm::GlobalVariable(TheModule,
2007classStruct->getType(),
false, llvm::GlobalValue::ExternalLinkage,
2008classStruct, ManglePublicSymbol(
"OBJC_INIT_CLASS_") + className);
2009classInitRef->setSection(sectionName<ClassSection>());
2012EmittedClass =
true;
2015CGObjCGNUstep2(
CodeGenModule&Mod) : CGObjCGNUstep(Mod, 10, 4, 2) {
2016MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
2017PtrToObjCSuperTy, SelectorTy);
2018SentInitializeFn.init(&CGM,
"objc_send_initialize",
2019llvm::Type::getVoidTy(VMContext), IdTy);
2028PropertyMetadataTy =
2030{ PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty });
2033 voidGenerateDirectMethodPrologue(
CodeGenFunction&CGF, llvm::Function *Fn,
2036 auto&Builder = CGF.
Builder;
2037 boolReceiverCanBeNull =
true;
2039 autoselfValue = Builder.CreateLoad(selfAddr);
2064ReceiverCanBeNull = isWeakLinkedClass(OID);
2068 if(ReceiverCanBeNull) {
2069llvm::BasicBlock *SelfIsNilBlock =
2071llvm::BasicBlock *ContBlock =
2075 autoselfTy = cast<llvm::PointerType>(selfValue->getType());
2076 auto Zero= llvm::ConstantPointerNull::get(selfTy);
2078Builder.CreateCondBr(Builder.CreateICmpEQ(selfValue, Zero),
2079SelfIsNilBlock, ContBlock,
2080MDHelper.createUnlikelyBranchWeights());
2086Builder.SetInsertPoint(SelfIsNilBlock);
2087 if(!retTy->isVoidType()) {
2095Builder.SetInsertPoint(ContBlock);
2101llvm::StructType::get(PtrTy, PtrTy, PtrTy, LongTy, LongTy);
2108llvm::Value *Val = Builder.CreateStructGEP(classStart, selfValue, 4);
2110astContext.getTypeAlign(astContext.UnsignedLongTy));
2111 autoflags = Builder.CreateLoad(
Address{Val, LongTy, Align});
2112 autoisInitialized =
2113Builder.CreateAnd(flags, ClassFlags::ClassFlagInitialized);
2114llvm::BasicBlock *notInitializedBlock =
2116llvm::BasicBlock *initializedBlock =
2118Builder.CreateCondBr(Builder.CreateICmpEQ(isInitialized, Zeros[0]),
2119notInitializedBlock, initializedBlock,
2120MDHelper.createUnlikelyBranchWeights());
2122Builder.SetInsertPoint(notInitializedBlock);
2124Builder.CreateBr(initializedBlock);
2126Builder.SetInsertPoint(initializedBlock);
2134Builder.CreateStore(GetSelector(CGF, OMD),
2140const char*
constCGObjCGNUstep2::SectionsBaseNames[8] =
2144"__objc_class_refs",
2147"__objc_protocol_refs",
2148"__objc_class_aliases",
2149"__objc_constant_string" 2152const char*
constCGObjCGNUstep2::PECOFFSectionsBaseNames[8] =
2165classCGObjCObjFW:
publicCGObjCGNU {
2169LazyRuntimeFunction MsgLookupFn;
2172LazyRuntimeFunction MsgLookupFnSRet;
2176LazyRuntimeFunction MsgLookupSuperFn, MsgLookupSuperFnSRet;
2179llvm::Value *cmd, llvm::MDNode *node,
2180MessageSendInfo &MSI)
override{
2182llvm::Value *args[] = {
2183EnforceType(Builder, Receiver, IdTy),
2184EnforceType(Builder, cmd, SelectorTy) };
2186llvm::CallBase *imp;
2192imp->setMetadata(msgSendMDKind, node);
2197llvm::Value *cmd, MessageSendInfo &MSI)
override{
2199llvm::Value *lookupArgs[] = {
2200EnforceType(Builder, ObjCSuper.
emitRawPointer(CGF), PtrToObjCSuperTy),
2210llvm::Value *GetClassNamed(
CodeGenFunction&CGF,
conststd::string &Name,
2211 boolisWeak)
override{
2213 returnCGObjCGNU::GetClassNamed(CGF, Name, isWeak);
2216std::string SymbolName =
"_OBJC_CLASS_"+ Name;
2217llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(SymbolName);
2219ClassSymbol =
newllvm::GlobalVariable(TheModule, LongTy,
false,
2220llvm::GlobalValue::ExternalLinkage,
2221 nullptr, SymbolName);
2228MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
2229MsgLookupFnSRet.init(&CGM,
"objc_msg_lookup_stret", IMPTy, IdTy,
2232MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
2233PtrToObjCSuperTy, SelectorTy);
2234MsgLookupSuperFnSRet.init(&CGM,
"objc_msg_lookup_super_stret", IMPTy,
2235PtrToObjCSuperTy, SelectorTy);
2243voidCGObjCGNU::EmitClassRef(
conststd::string &className) {
2244std::string symbolRef =
"__objc_class_ref_"+ className;
2246 if(TheModule.getGlobalVariable(symbolRef))
2248std::string symbolName =
"__objc_class_name_"+ className;
2249llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
2251ClassSymbol =
newllvm::GlobalVariable(TheModule, LongTy,
false,
2252llvm::GlobalValue::ExternalLinkage,
2253 nullptr, symbolName);
2255 newllvm::GlobalVariable(TheModule, ClassSymbol->getType(),
true,
2256llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef);
2259CGObjCGNU::CGObjCGNU(
CodeGenModule&cgm,
unsignedruntimeABIVersion,
2260 unsignedprotocolClassVersion,
unsignedclassABI)
2262VMContext(cgm.getLLVMContext()), ClassPtrAlias(nullptr),
2263MetaClassPtrAlias(nullptr), RuntimeVersion(runtimeABIVersion),
2264ProtocolVersion(protocolClassVersion), ClassABIVersion(classABI) {
2266msgSendMDKind = VMContext.getMDKindID(
"GNUObjCMessageSend");
2274IntTy = cast<llvm::IntegerType>(
2276LongTy = cast<llvm::IntegerType>(
2278SizeTy = cast<llvm::IntegerType>(
2280PtrDiffTy = cast<llvm::IntegerType>(
2284Int8Ty = llvm::Type::getInt8Ty(VMContext);
2286PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
2287ProtocolPtrTy = llvm::PointerType::getUnqual(
2290Zeros[0] = llvm::ConstantInt::get(LongTy, 0);
2291Zeros[1] = Zeros[0];
2292NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty);
2296SelectorTy = PtrToInt8Ty;
2297SelectorElemTy = Int8Ty;
2303PtrToIntTy = llvm::PointerType::getUnqual(IntTy);
2304PtrTy = PtrToInt8Ty;
2306Int32Ty = llvm::Type::getInt32Ty(VMContext);
2307Int64Ty = llvm::Type::getInt64Ty(VMContext);
2310CGM.
getDataLayout().getPointerSizeInBits() == 32 ? Int32Ty : Int64Ty;
2324PtrToIdTy = llvm::PointerType::getUnqual(IdTy);
2325ProtocolTy = llvm::StructType::get(IdTy,
2347PropertyMetadataTy = llvm::StructType::get(CGM.
getLLVMContext(), {
2348PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty,
2349PtrToInt8Ty, PtrToInt8Ty });
2351ObjCSuperTy = llvm::StructType::get(IdTy, IdTy);
2352PtrToObjCSuperTy = llvm::PointerType::getUnqual(ObjCSuperTy);
2354llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
2357ExceptionThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy);
2358ExceptionReThrowFn.init(&CGM,
2359usesCxxExceptions ?
"objc_exception_rethrow" 2360:
"objc_exception_throw",
2363SyncEnterFn.init(&CGM,
"objc_sync_enter", IntTy, IdTy);
2365SyncExitFn.init(&CGM,
"objc_sync_exit", IntTy, IdTy);
2368EnumerationMutationFn.init(&CGM,
"objc_enumerationMutation", VoidTy, IdTy);
2371GetPropertyFn.init(&CGM,
"objc_getProperty", IdTy, IdTy, SelectorTy,
2374SetPropertyFn.init(&CGM,
"objc_setProperty", VoidTy, IdTy, SelectorTy,
2375PtrDiffTy, IdTy, BoolTy, BoolTy);
2377GetStructPropertyFn.init(&CGM,
"objc_getPropertyStruct", VoidTy, PtrTy, PtrTy,
2378PtrDiffTy, BoolTy, BoolTy);
2380SetStructPropertyFn.init(&CGM,
"objc_setPropertyStruct", VoidTy, PtrTy, PtrTy,
2381PtrDiffTy, BoolTy, BoolTy);
2384llvm::Type *IMPArgs[] = { IdTy, SelectorTy };
2385IMPTy = llvm::PointerType::getUnqual(llvm::FunctionType::get(IdTy, IMPArgs,
2389 if((Opts.getGC() != LangOptions::NonGC) || Opts.ObjCAutoRefCount)
2390RuntimeVersion = 10;
2393 if(Opts.getGC() != LangOptions::NonGC) {
2405IvarAssignFn.init(&CGM,
"objc_assign_ivar", IdTy, IdTy, IdTy, PtrDiffTy);
2407StrongCastAssignFn.init(&CGM,
"objc_assign_strongCast", IdTy, IdTy,
2410GlobalAssignFn.init(&CGM,
"objc_assign_global", IdTy, IdTy, PtrToIdTy);
2412WeakAssignFn.init(&CGM,
"objc_assign_weak", IdTy, IdTy, PtrToIdTy);
2414WeakReadFn.init(&CGM,
"objc_read_weak", IdTy, PtrToIdTy);
2416MemMoveFn.init(&CGM,
"objc_memmove_collectable", PtrTy, PtrTy, PtrTy,
2422 conststd::string &Name,
boolisWeak) {
2423llvm::Constant *ClassName = MakeConstantString(Name);
2435llvm::FunctionType::get(IdTy, PtrToInt8Ty,
true),
"objc_lookup_class");
2445 if(
auto*ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value))
2450llvm::Value *CGObjCGNU::EmitNSAutoreleasePoolClassRef(
CodeGenFunction&CGF) {
2451 auto*
Value= GetClassNamed(CGF,
"NSAutoreleasePool",
false);
2452 if(CGM.
getTriple().isOSBinFormatCOFF()) {
2453 if(
auto*ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value)) {
2459 for(
const auto*Result : DC->
lookup(&II))
2460 if((VD = dyn_cast<VarDecl>(Result)))
2470 conststd::string &TypeEncoding) {
2472llvm::GlobalAlias *SelValue =
nullptr;
2475e = Types.end() ; i!=e ; i++) {
2476 if(i->first == TypeEncoding) {
2477SelValue = i->second;
2482SelValue = llvm::GlobalAlias::create(SelectorElemTy, 0,
2483llvm::GlobalValue::PrivateLinkage,
2486Types.emplace_back(TypeEncoding, SelValue);
2493llvm::Value *SelValue = GetSelector(CGF, Sel);
2504 returnGetTypedSelector(CGF, Sel, std::string());
2510 returnGetTypedSelector(CGF, Method->
getSelector(), SelTypes);
2513llvm::Constant *CGObjCGNU::GetEHType(
QualType T) {
2520 returnMakeConstantString(
"@id");
2528assert(OPT &&
"Invalid @catch type.");
2530assert(IDecl &&
"Invalid @catch type.");
2534llvm::Constant *CGObjCGNUstep::GetEHType(
QualType T) {
2535 if(usesSEHExceptions)
2538 if(!CGM.
getLangOpts().CPlusPlus && !usesCxxExceptions)
2539 returnCGObjCGNU::GetEHType(
T);
2547llvm::Constant *IDEHType =
2548CGM.
getModule().getGlobalVariable(
"__objc_id_type_info");
2551 newllvm::GlobalVariable(CGM.
getModule(), PtrToInt8Ty,
2553llvm::GlobalValue::ExternalLinkage,
2554 nullptr,
"__objc_id_type_info");
2560assert(PT &&
"Invalid @catch type.");
2562assert(IT &&
"Invalid @catch type.");
2563std::string className =
2566std::string typeinfoName =
"__objc_eh_typeinfo_"+ className;
2569 if(llvm::Constant *typeinfo = TheModule.getGlobalVariable(typeinfoName))
2577 const char*vtableName =
"_ZTVN7gnustep7libobjc22__objc_class_type_infoE";
2578 auto*Vtable = TheModule.getGlobalVariable(vtableName);
2580Vtable =
newllvm::GlobalVariable(TheModule, PtrToInt8Ty,
true,
2581llvm::GlobalValue::ExternalLinkage,
2582 nullptr, vtableName);
2584llvm::Constant *Two = llvm::ConstantInt::get(IntTy, 2);
2586llvm::ConstantExpr::getGetElementPtr(Vtable->getValueType(), Vtable, Two);
2588llvm::Constant *typeName =
2589ExportUniqueString(className,
"__objc_eh_typename_");
2592 autofields = builder.beginStruct();
2593fields.add(BVtable);
2594fields.add(typeName);
2595llvm::Constant *TI =
2596fields.finishAndCreateGlobal(
"__objc_eh_typeinfo_"+ className,
2599llvm::GlobalValue::LinkOnceODRLinkage);
2606std::string Str = SL->
getString().str();
2610llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
2611 if(old != ObjCStrings.end())
2616 if(StringClass.empty()) StringClass =
"NSConstantString";
2618std::string Sym =
"_OBJC_CLASS_";
2621llvm::Constant *
isa= TheModule.getNamedGlobal(Sym);
2624 isa=
newllvm::GlobalVariable(TheModule, IdTy,
false,
2625llvm::GlobalValue::ExternalWeakLinkage,
2629 autoFields = Builder.beginStruct();
2631Fields.add(MakeConstantString(Str));
2632Fields.addInt(IntTy, Str.size());
2634ObjCStrings[Str] = ObjCStr;
2635ConstantStrings.push_back(ObjCStr);
2648 boolisCategoryImpl,
2649llvm::Value *Receiver,
2650 boolIsClassMessage,
2654 if(CGM.
getLangOpts().getGC() == LangOptions::GCOnly) {
2655 if(Sel == RetainSel || Sel == AutoreleaseSel) {
2656 return RValue::get(EnforceType(Builder, Receiver,
2659 if(Sel == ReleaseSel) {
2664llvm::Value *cmd = GetSelector(CGF, Sel);
2667ActualArgs.
add(
RValue::get(EnforceType(Builder, Receiver, IdTy)), ASTIdTy);
2669ActualArgs.
addFrom(CallArgs);
2671MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2673llvm::Value *ReceiverClass =
nullptr;
2676ReceiverClass = GetClassNamed(CGF,
2677 Class->getSuperClass()->getNameAsString(),
false);
2678 if(IsClassMessage) {
2680ReceiverClass = Builder.CreateBitCast(ReceiverClass,
2681llvm::PointerType::getUnqual(IdTy));
2683Builder.CreateAlignedLoad(IdTy, ReceiverClass, CGF.
getPointerAlign());
2685ReceiverClass = EnforceType(Builder, ReceiverClass, IdTy);
2687 if(isCategoryImpl) {
2688llvm::FunctionCallee classLookupFunction =
nullptr;
2689 if(IsClassMessage) {
2691IdTy, PtrTy,
true),
"objc_get_meta_class");
2694IdTy, PtrTy,
true),
"objc_get_class");
2696ReceiverClass = Builder.CreateCall(classLookupFunction,
2697MakeConstantString(
Class->getNameAsString()));
2704 if(IsClassMessage) {
2705 if(!MetaClassPtrAlias) {
2706MetaClassPtrAlias = llvm::GlobalAlias::create(
2707IdElemTy, 0, llvm::GlobalValue::InternalLinkage,
2708 ".objc_metaclass_ref"+
Class->getNameAsString(), &TheModule);
2710ReceiverClass = MetaClassPtrAlias;
2712 if(!ClassPtrAlias) {
2713ClassPtrAlias = llvm::GlobalAlias::create(
2714IdElemTy, 0, llvm::GlobalValue::InternalLinkage,
2715 ".objc_class_ref"+
Class->getNameAsString(), &TheModule);
2717ReceiverClass = ClassPtrAlias;
2721llvm::Type *CastTy = llvm::StructType::get(IdTy, IdTy);
2722ReceiverClass = Builder.CreateBitCast(ReceiverClass,
2723llvm::PointerType::getUnqual(CastTy));
2725ReceiverClass = Builder.CreateStructGEP(CastTy, ReceiverClass, 1);
2728Builder.CreateAlignedLoad(IdTy, ReceiverClass, CGF.
getPointerAlign());
2731llvm::StructType *ObjCSuperTy =
2732llvm::StructType::get(Receiver->getType(), IdTy);
2737Builder.CreateStore(Receiver, Builder.CreateStructGEP(ObjCSuper, 0));
2738Builder.CreateStore(ReceiverClass, Builder.CreateStructGEP(ObjCSuper, 1));
2741llvm::Value *imp = LookupIMPSuper(CGF, ObjCSuper, cmd, MSI);
2742imp = EnforceType(Builder, imp, MSI.MessengerType);
2744llvm::Metadata *impMD[] = {
2745llvm::MDString::get(VMContext, Sel.
getAsString()),
2746llvm::MDString::get(VMContext,
Class->getSuperClass()->getNameAsString()),
2747llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2748llvm::Type::getInt1Ty(VMContext), IsClassMessage))};
2749llvm::MDNode *
node= llvm::MDNode::get(VMContext, impMD);
2753llvm::CallBase *call;
2754 RValuemsgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2755call->setMetadata(msgSendMDKind, node);
2765llvm::Value *Receiver,
2772 if(CGM.
getLangOpts().getGC() == LangOptions::GCOnly) {
2773 if(Sel == RetainSel || Sel == AutoreleaseSel) {
2774 return RValue::get(EnforceType(Builder, Receiver,
2777 if(Sel == ReleaseSel) {
2788cmd = GetSelector(CGF, Method);
2790cmd = GetSelector(CGF, Sel);
2791cmd = EnforceType(Builder, cmd, SelectorTy);
2794Receiver = EnforceType(Builder, Receiver, IdTy);
2796llvm::Metadata *impMD[] = {
2797llvm::MDString::get(VMContext, Sel.
getAsString()),
2798llvm::MDString::get(VMContext, Class ?
Class->getNameAsString() :
""),
2799llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2800llvm::Type::getInt1Ty(VMContext), Class !=
nullptr))};
2801llvm::MDNode *
node= llvm::MDNode::get(VMContext, impMD);
2807ActualArgs.
addFrom(CallArgs);
2809MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2830 boolhasParamDestroyedInCallee =
false;
2831 boolrequiresExplicitZeroResult =
false;
2832 boolrequiresNilReceiverCheck = [&] {
2834 if(!canMessageReceiverBeNull(CGF, Method,
false,
2840hasParamDestroyedInCallee =
true;
2861requiresExplicitZeroResult = !isDirect;
2865 returnhasParamDestroyedInCallee || requiresExplicitZeroResult;
2871 boolrequiresExplicitAggZeroing =
2875llvm::BasicBlock *continueBB =
nullptr;
2877llvm::BasicBlock *nilPathBB =
nullptr;
2879llvm::BasicBlock *nilCleanupBB =
nullptr;
2882 if(requiresNilReceiverCheck) {
2889 if(requiresExplicitAggZeroing || hasParamDestroyedInCallee) {
2892nilPathBB = Builder.GetInsertBlock();
2895llvm::Value *isNil = Builder.CreateICmpEQ(Receiver,
2896llvm::Constant::getNullValue(Receiver->getType()));
2897Builder.CreateCondBr(isNil, nilCleanupBB ? nilCleanupBB : continueBB,
2914imp = LookupIMP(CGF, Receiver, cmd, node, MSI);
2918StringRef
name=
"objc_msgSend";
2920 name=
"objc_msgSend_fpret";
2922 name=
"objc_msgSend_stret";
2926 boolshouldCheckForInReg =
2930.isWindowsMSVCEnvironment() &&
2933 name=
"objc_msgSend_stret2";
2946imp = EnforceType(Builder, imp, MSI.MessengerType);
2948llvm::CallBase *call;
2950 RValuemsgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2952call->setMetadata(msgSendMDKind, node);
2954 if(requiresNilReceiverCheck) {
2955llvm::BasicBlock *nonNilPathBB = CGF.
Builder.GetInsertBlock();
2956CGF.
Builder.CreateBr(continueBB);
2962 if(hasParamDestroyedInCallee) {
2963destroyCalleeDestroyedArguments(CGF, Method, CallArgs);
2966 if(requiresExplicitAggZeroing) {
2972nilPathBB = CGF.
Builder.GetInsertBlock();
2973CGF.
Builder.CreateBr(continueBB);
2981llvm::PHINode *phi = Builder.CreatePHI(
v->getType(), 2);
2982phi->addIncoming(
v, nonNilPathBB);
2989std::pair<llvm::Value*,llvm::Value*>
v= msgRet.
getComplexVal();
2990llvm::PHINode *phi = Builder.CreatePHI(
v.first->getType(), 2);
2991phi->addIncoming(
v.first, nonNilPathBB);
2992phi->addIncoming(llvm::Constant::getNullValue(
v.first->getType()),
2994llvm::PHINode *phi2 = Builder.CreatePHI(
v.second->getType(), 2);
2995phi2->addIncoming(
v.second, nonNilPathBB);
2996phi2->addIncoming(llvm::Constant::getNullValue(
v.second->getType()),
3006llvm::Constant *CGObjCGNU::
3007GenerateMethodList(StringRef ClassName,
3008StringRef CategoryName,
3010 boolisClassMethodList) {
3011 if(Methods.empty())
3016 autoMethodList = Builder.beginStruct();
3017MethodList.addNullPointer(CGM.
Int8PtrTy);
3018MethodList.addInt(Int32Ty, Methods.size());
3021llvm::StructType *ObjCMethodTy =
3030 constllvm::DataLayout &DL = TheModule.getDataLayout();
3031MethodList.addInt(SizeTy, DL.getTypeSizeInBits(ObjCMethodTy) /
3047 autoMethodArray = MethodList.beginArray();
3049 for(
const auto*OMD : Methods) {
3050llvm::Constant *FnPtr =
3051TheModule.getFunction(getSymbolNameForMethod(OMD));
3052assert(FnPtr &&
"Can't generate metadata for method that doesn't exist");
3053 autoMethod = MethodArray.beginStruct(ObjCMethodTy);
3055Method.
add(FnPtr);
3062Method.
add(FnPtr);
3064Method.finishAndAddTo(MethodArray);
3066MethodArray.finishAndAddTo(MethodList);
3069 returnMethodList.finishAndCreateGlobal(
".objc_method_list",
3074llvm::Constant *CGObjCGNU::
3080 if(IvarNames.empty())
3086 autoIvarList = Builder.beginStruct();
3087IvarList.addInt(IntTy, (
int)IvarNames.size());
3090llvm::StructType *ObjCIvarTy =
3091llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, IntTy);
3094 autoIvars = IvarList.beginArray(ObjCIvarTy);
3095 for(
unsigned inti = 0, e = IvarNames.size() ; i < e ; i++) {
3096 autoIvar = Ivars.beginStruct(ObjCIvarTy);
3097Ivar.
add(IvarNames[i]);
3098Ivar.
add(IvarTypes[i]);
3099Ivar.
add(IvarOffsets[i]);
3100Ivar.finishAndAddTo(Ivars);
3102Ivars.finishAndAddTo(IvarList);
3105 returnIvarList.finishAndCreateGlobal(
".objc_ivar_list",
3110llvm::Constant *CGObjCGNU::GenerateClassStructure(
3111llvm::Constant *MetaClass,
3112llvm::Constant *SuperClass,
3115llvm::Constant *Version,
3116llvm::Constant *InstanceSize,
3117llvm::Constant *IVars,
3118llvm::Constant *Methods,
3119llvm::Constant *Protocols,
3120llvm::Constant *IvarOffsets,
3121llvm::Constant *Properties,
3122llvm::Constant *StrongIvarBitmap,
3123llvm::Constant *WeakIvarBitmap,
3132llvm::StructType *ClassTy = llvm::StructType::get(
3149IvarOffsets->getType(),
3150Properties->getType(),
3156 autoElements = Builder.beginStruct(ClassTy);
3161Elements.add(MetaClass);
3163Elements.add(SuperClass);
3165Elements.add(MakeConstantString(Name,
".class_name"));
3167Elements.addInt(LongTy, 0);
3169Elements.addInt(LongTy, info);
3172 constllvm::DataLayout &DL = TheModule.getDataLayout();
3173Elements.addInt(LongTy, DL.getTypeSizeInBits(ClassTy) /
3176Elements.add(InstanceSize);
3178Elements.add(IVars);
3180Elements.add(Methods);
3183Elements.add(NULLPtr);
3185Elements.add(NULLPtr);
3187Elements.add(NULLPtr);
3189Elements.add(Protocols);
3191Elements.add(NULLPtr);
3193Elements.addInt(LongTy, ClassABIVersion);
3195Elements.add(IvarOffsets);
3197Elements.add(Properties);
3199Elements.add(StrongIvarBitmap);
3201Elements.add(WeakIvarBitmap);
3206std::string ClassSym((isMeta ?
"_OBJC_METACLASS_":
"_OBJC_CLASS_") +
3208llvm::GlobalVariable *ClassRef = TheModule.getNamedGlobal(ClassSym);
3209llvm::Constant *
Class=
3210Elements.finishAndCreateGlobal(ClassSym, CGM.
getPointerAlign(),
false,
3211llvm::GlobalValue::ExternalLinkage);
3213ClassRef->replaceAllUsesWith(Class);
3214ClassRef->removeFromParent();
3215 Class->setName(ClassSym);
3220llvm::Constant *CGObjCGNU::
3223llvm::StructType *ObjCMethodDescTy =
3224llvm::StructType::get(CGM.
getLLVMContext(), { PtrToInt8Ty, PtrToInt8Ty });
3227 autoMethodList = Builder.beginStruct();
3228MethodList.addInt(IntTy, Methods.size());
3229 autoMethodArray = MethodList.beginArray(ObjCMethodDescTy);
3230 for(
auto*M : Methods) {
3231 autoMethod = MethodArray.beginStruct(ObjCMethodDescTy);
3232Method.
add(MakeConstantString(M->getSelector().getAsString()));
3234Method.finishAndAddTo(MethodArray);
3236MethodArray.finishAndAddTo(MethodList);
3237 returnMethodList.finishAndCreateGlobal(
".objc_method_list",
3246 autoProtocolList = Builder.beginStruct();
3247ProtocolList.add(NULLPtr);
3248ProtocolList.addInt(LongTy, Protocols.size());
3250 autoElements = ProtocolList.beginArray(PtrToInt8Ty);
3251 for(
conststd::string *iter = Protocols.begin(), *endIter = Protocols.end();
3252iter != endIter ; iter++) {
3253llvm::Constant *protocol =
nullptr;
3254llvm::StringMap<llvm::Constant*>::iterator value =
3255ExistingProtocols.find(*iter);
3256 if(value == ExistingProtocols.end()) {
3257protocol = GenerateEmptyProtocol(*iter);
3259protocol = value->getValue();
3261Elements.add(protocol);
3263Elements.finishAndAddTo(ProtocolList);
3264 returnProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
3270 autoprotocol = GenerateProtocolRef(PD);
3273 returnCGF.
Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(
T));
3276llvm::Constant *CGObjCGNU::GenerateProtocolRef(
const ObjCProtocolDecl*PD) {
3277llvm::Constant *&protocol = ExistingProtocols[PD->
getNameAsString()];
3279GenerateProtocol(PD);
3280assert(protocol &&
"Unknown protocol");
3285CGObjCGNU::GenerateEmptyProtocol(StringRef ProtocolName) {
3286llvm::Constant *ProtocolList = GenerateProtocolList({});
3287llvm::Constant *MethodList = GenerateProtocolMethodList({});
3291 autoElements = Builder.beginStruct();
3295Elements.add(llvm::ConstantExpr::getIntToPtr(
3296llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3298Elements.add(MakeConstantString(ProtocolName,
".objc_protocol_name"));
3299Elements.add(ProtocolList);
3300Elements.add(MethodList);
3301Elements.add(MethodList);
3302Elements.add(MethodList);
3303Elements.add(MethodList);
3304Elements.add(NULLPtr);
3305Elements.add(NULLPtr);
3306 returnElements.finishAndCreateGlobal(SymbolForProtocol(ProtocolName),
3321 for(
const auto*PI : PD->
protocols())
3322Protocols.push_back(PI->getNameAsString());
3326 if(I->isOptional())
3327OptionalInstanceMethods.push_back(I);
3329InstanceMethods.push_back(I);
3334 if(I->isOptional())
3335OptionalClassMethods.push_back(I);
3337ClassMethods.push_back(I);
3339llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
3340llvm::Constant *InstanceMethodList =
3341GenerateProtocolMethodList(InstanceMethods);
3342llvm::Constant *ClassMethodList =
3343GenerateProtocolMethodList(ClassMethods);
3344llvm::Constant *OptionalInstanceMethodList =
3345GenerateProtocolMethodList(OptionalInstanceMethods);
3346llvm::Constant *OptionalClassMethodList =
3347GenerateProtocolMethodList(OptionalClassMethods);
3355llvm::Constant *PropertyList =
3356GeneratePropertyList(
nullptr, PD,
false,
false);
3357llvm::Constant *OptionalPropertyList =
3358GeneratePropertyList(
nullptr, PD,
false,
true);
3365 autoElements = Builder.beginStruct();
3367llvm::ConstantExpr::getIntToPtr(
3368llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3369Elements.add(MakeConstantString(ProtocolName));
3370Elements.add(ProtocolList);
3371Elements.add(InstanceMethodList);
3372Elements.add(ClassMethodList);
3373Elements.add(OptionalInstanceMethodList);
3374Elements.add(OptionalClassMethodList);
3375Elements.add(PropertyList);
3376Elements.add(OptionalPropertyList);
3377ExistingProtocols[ProtocolName] =
3378Elements.finishAndCreateGlobal(
".objc_protocol", CGM.
getPointerAlign());
3380voidCGObjCGNU::GenerateProtocolHolderCategory() {
3384 autoElements = Builder.beginStruct();
3386 conststd::string ClassName =
"__ObjC_Protocol_Holder_Ugly_Hack";
3387 conststd::string CategoryName =
"AnotherHack";
3388Elements.add(MakeConstantString(CategoryName));
3389Elements.add(MakeConstantString(ClassName));
3391Elements.add(GenerateMethodList(ClassName, CategoryName, {},
false));
3393Elements.add(GenerateMethodList(ClassName, CategoryName, {},
true));
3397 autoProtocolList = ProtocolListBuilder.beginStruct();
3398ProtocolList.add(NULLPtr);
3399ProtocolList.addInt(LongTy, ExistingProtocols.size());
3400 autoProtocolElements = ProtocolList.beginArray(PtrTy);
3401 for(
autoiter = ExistingProtocols.begin(), endIter = ExistingProtocols.end();
3402iter != endIter ; iter++) {
3403ProtocolElements.add(iter->getValue());
3405ProtocolElements.finishAndAddTo(ProtocolList);
3406Elements.add(ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
3408Categories.push_back(
3424 intbitCount = bits.size();
3426 if(bitCount < ptrBits) {
3428 for(
inti=0 ; i<bitCount ; ++i) {
3429 if(bits[i]) val |= 1ULL<<(i+1);
3431 returnllvm::ConstantInt::get(IntPtrTy, val);
3435 while(
v< bitCount) {
3437 for(
inti=0 ; (i<32) && (
v<bitCount) ; ++i) {
3438 if(bits[
v]) word |= 1<<i;
3441values.push_back(llvm::ConstantInt::get(Int32Ty, word));
3445 autofields = builder.beginStruct();
3446fields.addInt(Int32Ty, values.size());
3447 autoarray = fields.beginArray();
3448 for(
auto*
v: values) array.add(
v);
3449array.finishAndAddTo(fields);
3451llvm::Constant *GS =
3453llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy);
3457llvm::Constant *CGObjCGNU::GenerateCategoryProtocolList(
const 3460 const autoRuntimeProtos =
3461GetRuntimeProtocolList(RefPro.begin(), RefPro.end());
3463 for(
const auto*PD : RuntimeProtos)
3465 returnGenerateProtocolList(Protocols);
3470std::string ClassName =
Class->getNameAsString();
3477 autoElements = Builder.beginStruct();
3478Elements.add(MakeConstantString(CategoryName));
3479Elements.add(MakeConstantString(ClassName));
3482InstanceMethods.insert(InstanceMethods.begin(), OCD->
instmeth_begin(),
3485GenerateMethodList(ClassName, CategoryName, InstanceMethods,
false));
3492Elements.add(GenerateMethodList(ClassName, CategoryName, ClassMethods,
true));
3495Elements.add(GenerateCategoryProtocolList(CatDecl));
3501Elements.add(GeneratePropertyList(OCD,
Category,
false));
3503Elements.add(GeneratePropertyList(OCD,
Category,
true));
3505Elements.addNullPointer(PtrTy);
3506Elements.addNullPointer(PtrTy);
3510Categories.push_back(Elements.finishAndCreateGlobal(
3511std::string(
".objc_category_") + ClassName + CategoryName,
3515llvm::Constant *CGObjCGNU::GeneratePropertyList(
const Decl*Container,
3517 boolisClassProperty,
3518 boolprotocolOptionalProperties) {
3522 boolisProtocol = isa<ObjCProtocolDecl>(OCD);
3525std::function<void(
const ObjCProtocolDecl*Proto)> collectProtocolProperties
3527 for(
const auto*
P: Proto->protocols())
3528collectProtocolProperties(
P);
3529 for(
const auto*PD : Proto->properties()) {
3530 if(isClassProperty != PD->isClassProperty())
3538Properties.push_back(PD);
3544 for(
auto*PD : ClassExt->properties()) {
3545 if(isClassProperty != PD->isClassProperty())
3548Properties.push_back(PD);
3551 for(
const auto*PD : OCD->
properties()) {
3552 if(isClassProperty != PD->isClassProperty())
3556 if(isProtocol && (protocolOptionalProperties != PD->isOptional()))
3563Properties.push_back(PD);
3568collectProtocolProperties(
P);
3570 for(
const auto*
P: CD->protocols())
3571collectProtocolProperties(
P);
3573 autonumProperties = Properties.size();
3575 if(numProperties == 0)
3579 autopropertyList = builder.beginStruct();
3580 autoproperties = PushPropertyListHeader(propertyList, numProperties);
3584 for(
auto*property : Properties) {
3585 boolisSynthesized =
false;
3586 boolisDynamic =
false;
3590isSynthesized = (propertyImpl->getPropertyImplementation() ==
3592isDynamic = (propertyImpl->getPropertyImplementation() ==
3596PushProperty(properties, property, Container, isSynthesized, isDynamic);
3598properties.finishAndAddTo(propertyList);
3600 returnpropertyList.finishAndCreateGlobal(
".objc_property_list",
3618std::string SuperClassName;
3619 if(SuperClassDecl) {
3621EmitClassRef(SuperClassName);
3631std::string classSymbolName =
"__objc_class_name_"+ ClassName;
3632 if(
auto*symbol = TheModule.getGlobalVariable(classSymbolName)) {
3633symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0));
3635 newllvm::GlobalVariable(TheModule, LongTy,
false,
3636llvm::GlobalValue::ExternalLinkage,
3637llvm::ConstantInt::get(LongTy, 0),
3653 autoIvarOffsetValues = IvarOffsetBuilder.beginArray(PtrToIntTy);
3657 intsuperInstanceSize = !SuperClassDecl ? 0 :
3662instanceSize = 0 - (instanceSize - superInstanceSize);
3668IvarNames.push_back(MakeConstantString(IVD->getNameAsString()));
3670std::string TypeStr;
3672IvarTypes.push_back(MakeConstantString(TypeStr));
3673IvarAligns.push_back(llvm::ConstantInt::get(IntTy,
3676 uint64_tBaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
3679Offset = BaseOffset - superInstanceSize;
3681llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
3683std::string OffsetName =
"__objc_ivar_offset_value_"+ ClassName +
"."+
3684IVD->getNameAsString();
3686llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
3688OffsetVar->setInitializer(OffsetValue);
3692OffsetVar->setLinkage(llvm::GlobalValue::ExternalLinkage);
3694OffsetVar =
newllvm::GlobalVariable(TheModule, Int32Ty,
3695 false, llvm::GlobalValue::ExternalLinkage,
3696OffsetValue, OffsetName);
3697IvarOffsets.push_back(OffsetValue);
3698IvarOffsetValues.add(OffsetVar);
3700IvarOwnership.push_back(lt);
3703StrongIvars.push_back(
true);
3704WeakIvars.push_back(
false);
3707StrongIvars.push_back(
false);
3708WeakIvars.push_back(
true);
3711StrongIvars.push_back(
false);
3712WeakIvars.push_back(
false);
3715llvm::Constant *StrongIvarBitmap = MakeBitField(StrongIvars);
3716llvm::Constant *WeakIvarBitmap = MakeBitField(WeakIvars);
3717llvm::GlobalVariable *IvarOffsetArray =
3718IvarOffsetValues.finishAndCreateGlobal(
".ivar.offsets",
3723InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
3730llvm::Constant *Properties = GeneratePropertyList(OID, ClassDecl);
3733 autoRefProtocols = ClassDecl->
protocols();
3734 autoRuntimeProtocols =
3735GetRuntimeProtocolList(RefProtocols.begin(), RefProtocols.end());
3737 for(
const auto*I : RuntimeProtocols)
3738Protocols.push_back(I->getNameAsString());
3741llvm::Constant *SuperClass;
3742 if(!SuperClassName.empty()) {
3743SuperClass = MakeConstantString(SuperClassName,
".super_class_name");
3745SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty);
3750llvm::Constant *MethodList = GenerateMethodList(ClassName,
"",
3751InstanceMethods,
false);
3752llvm::Constant *ClassMethodList = GenerateMethodList(ClassName,
"",
3753ClassMethods,
true);
3754llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
3755IvarOffsets, IvarAligns, IvarOwnership);
3766llvm::Type *IndexTy = Int32Ty;
3767llvm::Constant *offsetPointerIndexes[] = {Zeros[0],
3768llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 2 : 1),
nullptr,
3769llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 3 : 2) };
3771 unsignedivarIndex = 0;
3774 conststd::string Name = GetIVarOffsetVariableName(ClassDecl, IVD);
3775offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, ivarIndex);
3777llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr(
3778cast<llvm::GlobalVariable>(IvarList)->getValueType(), IvarList,
3779offsetPointerIndexes);
3781llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name);
3783offset->setInitializer(offsetValue);
3787offset->setLinkage(llvm::GlobalValue::ExternalLinkage);
3790 newllvm::GlobalVariable(TheModule, offsetValue->getType(),
3791 false, llvm::GlobalValue::ExternalLinkage, offsetValue, Name);
3794llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0);
3797llvm::Constant *MetaClassStruct = GenerateClassStructure(
3798NULLPtr, NULLPtr, 0x12L, ClassName.c_str(),
nullptr, Zeros[0],
3799NULLPtr, ClassMethodList, NULLPtr, NULLPtr,
3800GeneratePropertyList(OID, ClassDecl,
true), ZeroPtr, ZeroPtr,
true);
3805llvm::Constant *ClassStruct = GenerateClassStructure(
3806MetaClassStruct, SuperClass, 0x11L, ClassName.c_str(),
nullptr,
3807llvm::ConstantInt::get(LongTy, instanceSize), IvarList, MethodList,
3808GenerateProtocolList(Protocols), IvarOffsetArray, Properties,
3809StrongIvarBitmap, WeakIvarBitmap);
3814 if(ClassPtrAlias) {
3815ClassPtrAlias->replaceAllUsesWith(ClassStruct);
3816ClassPtrAlias->eraseFromParent();
3817ClassPtrAlias =
nullptr;
3819 if(MetaClassPtrAlias) {
3820MetaClassPtrAlias->replaceAllUsesWith(MetaClassStruct);
3821MetaClassPtrAlias->eraseFromParent();
3822MetaClassPtrAlias =
nullptr;
3826Classes.push_back(ClassStruct);
3829llvm::Function *CGObjCGNU::ModuleInitFunction() {
3831 if(Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
3836GenerateProtocolHolderCategory();
3838llvm::StructType *selStructTy = dyn_cast<llvm::StructType>(SelectorElemTy);
3841{ PtrToInt8Ty, PtrToInt8Ty });
3845llvm::Constant *statics = NULLPtr;
3846 if(!ConstantStrings.empty()) {
3847llvm::GlobalVariable *fileStatics = [&] {
3849 autostaticsStruct = builder.beginStruct();
3852 if(stringClass.empty()) stringClass =
"NXConstantString";
3853staticsStruct.add(MakeConstantString(stringClass,
3854 ".objc_static_class_name"));
3856 autoarray = staticsStruct.beginArray();
3857array.addAll(ConstantStrings);
3859array.finishAndAddTo(staticsStruct);
3861 returnstaticsStruct.finishAndCreateGlobal(
".objc_statics",
3866 autoallStaticsArray = builder.beginArray(fileStatics->getType());
3867allStaticsArray.add(fileStatics);
3868allStaticsArray.addNullPointer(fileStatics->getType());
3870statics = allStaticsArray.finishAndCreateGlobal(
".objc_statics_ptr",
3877 unsignedselectorCount;
3880llvm::GlobalVariable *selectorList = [&] {
3882 autoselectors = builder.beginArray(selStructTy);
3884std::vector<Selector> allSelectors;
3885 for(
auto&entry : table)
3886allSelectors.push_back(entry.first);
3887llvm::sort(allSelectors);
3889 for(
auto&untypedSel : allSelectors) {
3890std::string selNameStr = untypedSel.getAsString();
3891llvm::Constant *selName = ExportUniqueString(selNameStr,
".objc_sel_name");
3893 for(TypedSelector &sel : table[untypedSel]) {
3894llvm::Constant *selectorTypeEncoding = NULLPtr;
3895 if(!sel.first.empty())
3896selectorTypeEncoding =
3897MakeConstantString(sel.first,
".objc_sel_types");
3899 autoselStruct = selectors.beginStruct(selStructTy);
3900selStruct.add(selName);
3901selStruct.add(selectorTypeEncoding);
3902selStruct.finishAndAddTo(selectors);
3905selectorAliases.push_back(sel.second);
3910selectorCount = selectors.size();
3916 autoselStruct = selectors.beginStruct(selStructTy);
3917selStruct.add(NULLPtr);
3918selStruct.add(NULLPtr);
3919selStruct.finishAndAddTo(selectors);
3921 returnselectors.finishAndCreateGlobal(
".objc_selector_list",
3926 for(
unsignedi = 0; i < selectorCount; ++i) {
3927llvm::Constant *idxs[] = {
3929llvm::ConstantInt::get(Int32Ty, i)
3932llvm::Constant *selPtr = llvm::ConstantExpr::getGetElementPtr(
3933selectorList->getValueType(), selectorList, idxs);
3934selectorAliases[i]->replaceAllUsesWith(selPtr);
3935selectorAliases[i]->eraseFromParent();
3938llvm::GlobalVariable *symtab = [&] {
3940 autosymtab = builder.beginStruct();
3943symtab.addInt(LongTy, selectorCount);
3945symtab.add(selectorList);
3948symtab.addInt(CGM.
Int16Ty, Classes.size());
3950symtab.addInt(CGM.
Int16Ty, Categories.size());
3953 autoclassList = symtab.beginArray(PtrToInt8Ty);
3954classList.addAll(Classes);
3955classList.addAll(Categories);
3957classList.add(statics);
3958classList.add(NULLPtr);
3959classList.finishAndAddTo(symtab);
3967llvm::Constant *module = [&] {
3968llvm::Type *moduleEltTys[] = {
3969LongTy, LongTy, PtrToInt8Ty, symtab->getType(), IntTy
3971llvm::StructType *moduleTy = llvm::StructType::get(
3973 ArrayRef(moduleEltTys).drop_back(
unsigned(RuntimeVersion < 10)));
3976 automodule = builder.beginStruct(moduleTy);
3978module.addInt(LongTy, RuntimeVersion);
3980module.addInt(LongTy, CGM.
getDataLayout().getTypeStoreSize(moduleTy));
3987module.add(MakeConstantString(path,
".objc_source_file_name"));
3990 if(RuntimeVersion >= 10) {
3992 caseLangOptions::GCOnly:
3993module.addInt(IntTy, 2);
3995 caseLangOptions::NonGC:
3997module.addInt(IntTy, 1);
3999module.addInt(IntTy, 0);
4001 caseLangOptions::HybridGC:
4002module.addInt(IntTy, 1);
4012llvm::Function * LoadFunction = llvm::Function::Create(
4013llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
4014llvm::GlobalValue::InternalLinkage,
".objc_load_function",
4016llvm::BasicBlock *EntryBB =
4017llvm::BasicBlock::Create(VMContext,
"entry", LoadFunction);
4019Builder.SetInsertPoint(EntryBB);
4021llvm::FunctionType *FT =
4022llvm::FunctionType::get(Builder.getVoidTy(), module->getType(),
true);
4023llvm::FunctionCallee Register =
4025Builder.CreateCall(Register, module);
4027 if(!ClassAliases.empty()) {
4028llvm::Type *ArgTypes[2] = {PtrTy, PtrToInt8Ty};
4029llvm::FunctionType *RegisterAliasTy =
4030llvm::FunctionType::get(Builder.getVoidTy(),
4032llvm::Function *RegisterAlias = llvm::Function::Create(
4034llvm::GlobalValue::ExternalWeakLinkage,
"class_registerAlias_np",
4036llvm::BasicBlock *AliasBB =
4037llvm::BasicBlock::Create(VMContext,
"alias", LoadFunction);
4038llvm::BasicBlock *NoAliasBB =
4039llvm::BasicBlock::Create(VMContext,
"no_alias", LoadFunction);
4042llvm::Value *HasRegisterAlias = Builder.CreateICmpNE(RegisterAlias,
4043llvm::Constant::getNullValue(RegisterAlias->getType()));
4044Builder.CreateCondBr(HasRegisterAlias, AliasBB, NoAliasBB);
4047Builder.SetInsertPoint(AliasBB);
4049 for(std::vector<ClassAliasPair>::iterator iter = ClassAliases.begin();
4050iter != ClassAliases.end(); ++iter) {
4051llvm::Constant *TheClass =
4052TheModule.getGlobalVariable(
"_OBJC_CLASS_"+ iter->first,
true);
4054Builder.CreateCall(RegisterAlias,
4055{TheClass, MakeConstantString(iter->second)});
4059Builder.CreateBr(NoAliasBB);
4062Builder.SetInsertPoint(NoAliasBB);
4064Builder.CreateRetVoid();
4066 returnLoadFunction;
4069llvm::Function *CGObjCGNU::GenerateMethod(
const ObjCMethodDecl*OMD,
4072llvm::FunctionType *MethodTy =
4073Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
4076std::string FunctionName =
4077getSymbolNameForMethod(OMD,
!isDirect);
4080 returnllvm::Function::Create(MethodTy,
4081llvm::GlobalVariable::InternalLinkage,
4082FunctionName, &TheModule);
4085 autoI = DirectMethodDefinitions.find(COMD);
4086llvm::Function *OldFn =
nullptr, *
Fn=
nullptr;
4088 if(I == DirectMethodDefinitions.end()) {
4090llvm::Function::Create(MethodTy, llvm::GlobalVariable::ExternalLinkage,
4091FunctionName, &TheModule);
4092DirectMethodDefinitions.insert(std::make_pair(COMD, F));
4109 Fn= llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,
"",
4111 Fn->takeName(OldFn);
4112OldFn->replaceAllUsesWith(Fn);
4113OldFn->eraseFromParent();
4127llvm::FunctionCallee CGObjCGNU::GetPropertyGetFunction() {
4128 returnGetPropertyFn;
4131llvm::FunctionCallee CGObjCGNU::GetPropertySetFunction() {
4132 returnSetPropertyFn;
4135llvm::FunctionCallee CGObjCGNU::GetOptimizedPropertySetFunction(
boolatomic,
4140llvm::FunctionCallee CGObjCGNU::GetGetStructFunction() {
4141 returnGetStructPropertyFn;
4144llvm::FunctionCallee CGObjCGNU::GetSetStructFunction() {
4145 returnSetStructPropertyFn;
4148llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectGetFunction() {
4152llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectSetFunction() {
4156llvm::FunctionCallee CGObjCGNU::EnumerationMutationFunction() {
4157 returnEnumerationMutationFn;
4162EmitAtSynchronizedStmt(CGF, S, SyncEnterFn, SyncExitFn);
4179EmitTryCatchStmt(CGF, S, EnterCatchFn, ExitCatchFn, ExceptionReThrowFn);
4184 boolClearInsertionPoint) {
4185llvm::Value *ExceptionAsObject;
4186 boolisRethrow =
false;
4188 if(
const Expr*ThrowExpr = S.getThrowExpr()) {
4190ExceptionAsObject = Exception;
4193 "Unexpected rethrow outside @catch block.");
4197 if(isRethrow && (usesSEHExceptions || usesCxxExceptions)) {
4206Throw->setDoesNotReturn();
4208ExceptionAsObject = CGF.
Builder.CreateBitCast(ExceptionAsObject, IdTy);
4209llvm::CallBase *Throw =
4211Throw->setDoesNotReturn();
4213CGF.
Builder.CreateUnreachable();
4214 if(ClearInsertionPoint)
4215CGF.
Builder.ClearInsertionPoint();
4221 returnB.CreateCall(
4222WeakReadFn, EnforceType(B, AddrWeakObj.
emitRawPointer(CGF), PtrToIdTy));
4226llvm::Value *src,
Addressdst) {
4228src = EnforceType(B, src, IdTy);
4229llvm::Value *dstVal = EnforceType(B, dst.
emitRawPointer(CGF), PtrToIdTy);
4230B.CreateCall(WeakAssignFn, {src, dstVal});
4234llvm::Value *src,
Addressdst,
4237src = EnforceType(B, src, IdTy);
4238llvm::Value *dstVal = EnforceType(B, dst.
emitRawPointer(CGF), PtrToIdTy);
4240assert(!threadlocal &&
"EmitObjCGlobalAssign - Threal Local API NYI");
4241B.CreateCall(GlobalAssignFn, {src, dstVal});
4245llvm::Value *src,
Addressdst,
4246llvm::Value *ivarOffset) {
4248src = EnforceType(B, src, IdTy);
4249llvm::Value *dstVal = EnforceType(B, dst.
emitRawPointer(CGF), IdTy);
4250B.CreateCall(IvarAssignFn, {src, dstVal, ivarOffset});
4254llvm::Value *src,
Addressdst) {
4256src = EnforceType(B, src, IdTy);
4257llvm::Value *dstVal = EnforceType(B, dst.
emitRawPointer(CGF), PtrToIdTy);
4258B.CreateCall(StrongCastAssignFn, {src, dstVal});
4264llvm::Value *Size) {
4266llvm::Value *DestPtrVal = EnforceType(B, DestPtr.
emitRawPointer(CGF), PtrTy);
4267llvm::Value *SrcPtrVal = EnforceType(B, SrcPtr.
emitRawPointer(CGF), PtrTy);
4269B.CreateCall(MemMoveFn, {DestPtrVal, SrcPtrVal,
Size});
4272llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
4275 conststd::string Name = GetIVarOffsetVariableName(ID, Ivar);
4279llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
4280 if(!IvarOffsetPointer)
4281IvarOffsetPointer =
newllvm::GlobalVariable(
4282TheModule, llvm::PointerType::getUnqual(VMContext),
false,
4283llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
4284 returnIvarOffsetPointer;
4289llvm::Value *BaseValue,
4291 unsignedCVRQualifiers) {
4294 returnEmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
4295EmitIvarOffset(CGF, ID, Ivar));
4323 if(RuntimeVersion < 10 ||
4325 returnCGF.
Builder.CreateZExtOrBitCast(
4329llvm::PointerType::getUnqual(VMContext),
4330ObjCIvarOffsetVariable(
Interface, Ivar),
4334std::string
name=
"__objc_ivar_offset_value_"+
4337llvm::Value *Offset = TheModule.getGlobalVariable(name);
4339 autoGV =
newllvm::GlobalVariable(TheModule, IntTy,
4340 false, llvm::GlobalValue::LinkOnceAnyLinkage,
4341llvm::Constant::getNullValue(IntTy), name);
4346 if(Offset->getType() != PtrDiffTy)
4347Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
4351 returnllvm::ConstantInt::get(PtrDiffTy, Offset,
true);
4357 switch(Runtime.getKind()) {
4359 if(Runtime.getVersion() >= VersionTuple(2, 0))
4360 return newCGObjCGNUstep2(CGM);
4361 return newCGObjCGNUstep(CGM);
4364 return newCGObjCGCC(CGM);
4367 return newCGObjCObjFW(CGM);
4373llvm_unreachable(
"these runtimes are not GNU runtimes");
4375llvm_unreachable(
"bad runtime");
Defines the clang::ASTContext interface.
static const ObjCInterfaceDecl * FindIvarInterface(ASTContext &Context, const ObjCInterfaceDecl *OID, const ObjCIvarDecl *OIVD)
static bool isNamed(const NamedDecl *ND, const char(&Str)[Len])
Defines the SourceManager interface.
Defines the Objective-C statement AST node classes.
__device__ __2f16 float __ockl_bool s
__device__ __2f16 float c
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
TranslationUnitDecl * getTranslationUnitDecl() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
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.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
std::string getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, bool Extended=false) const
Emit the encoded type for the method declaration Decl into S.
std::string getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD, const Decl *Container) const
getObjCEncodingForPropertyDecl - Return the encoded type for this method declaration.
const ASTRecordLayout & getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const
Get or compute information about the layout of the specified Objective-C implementation.
const ASTRecordLayout & getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const
Get or compute information about the layout of the specified Objective-C interface.
QualType getObjCProtoType() const
Retrieve the type of the Objective-C Protocol class.
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
ObjCPropertyImplDecl * getObjCPropertyImplDeclForPropertyDecl(const ObjCPropertyDecl *PD, const Decl *Container) const
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
QualType getObjCIdType() const
Represents the Objective-CC id type.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
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...
const TargetInfo & getTargetInfo() const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
CharUnits getSize() const
getSize - Get the record size in characters.
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
CharUnits - This is an opaque type for sizes expressed in character units.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
CGBlockInfo - Information to generate a block literal.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
virtual llvm::Constant * getAddrOfRTTIDescriptor(QualType Ty)=0
virtual CatchTypeInfo getCatchAllTypeInfo()
Abstract information about a function or function prototype.
All available information about a concrete callee.
Implements runtime-specific code generation functions.
virtual llvm::Constant * GetEHType(QualType T)=0
Get the type constant to catch for the given ObjC pointer type.
virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest, llvm::Value *ivarOffset)=0
virtual llvm::FunctionCallee GetCppAtomicObjectGetFunction()=0
API for atomic copying of qualified aggregates with non-trivial copy assignment (c++) in getter.
virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest)=0
virtual llvm::Constant * BuildByrefLayout(CodeGen::CodeGenModule &CGM, QualType T)=0
Returns an i8* which points to the byref layout information.
virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, Address DestPtr, Address SrcPtr, llvm::Value *Size)=0
virtual llvm::FunctionCallee GetPropertySetFunction()=0
Return the runtime function for setting properties.
virtual llvm::FunctionCallee GetCppAtomicObjectSetFunction()=0
API for atomic copying of qualified aggregates with non-trivial copy assignment (c++) in setter.
virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtTryStmt &S)=0
virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, ReturnValueSlot ReturnSlot, QualType ResultType, Selector Sel, llvm::Value *Receiver, const CallArgList &CallArgs, const ObjCInterfaceDecl *Class=nullptr, const ObjCMethodDecl *Method=nullptr)=0
Generate an Objective-C message send operation.
virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy, llvm::Value *BaseValue, const ObjCIvarDecl *Ivar, unsigned CVRQualifiers)=0
virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD)=0
Register an class alias.
virtual void GenerateCategory(const ObjCCategoryImplDecl *OCD)=0
Generate a category.
virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S, bool ClearInsertionPoint=true)=0
virtual llvm::Value * EmitIvarOffset(CodeGen::CodeGenFunction &CGF, const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar)=0
virtual llvm::Function * GenerateMethod(const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD)=0
Generate a function preamble for a method with the specified types.
virtual llvm::Value * GenerateProtocolRef(CodeGenFunction &CGF, const ObjCProtocolDecl *OPD)=0
Emit the code to return the named protocol as an object, as in a @protocol expression.
virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, Address AddrWeakObj)=0
virtual llvm::Function * ModuleInitFunction()=0
Generate the function required to register all Objective-C components in this compilation unit with t...
virtual CodeGen::RValue GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, ReturnValueSlot ReturnSlot, QualType ResultType, Selector Sel, const ObjCInterfaceDecl *Class, bool isCategoryImpl, llvm::Value *Self, bool IsClassMessage, const CallArgList &CallArgs, const ObjCMethodDecl *Method=nullptr)=0
Generate an Objective-C message send operation to the super class initiated in a method for Class and...
virtual void GenerateClass(const ObjCImplementationDecl *OID)=0
Generate a class structure for this class.
virtual llvm::FunctionCallee EnumerationMutationFunction()=0
EnumerationMutationFunction - Return the function that's called by the compiler when a mutation is de...
virtual llvm::Constant * BuildGCBlockLayout(CodeGen::CodeGenModule &CGM, const CodeGen::CGBlockInfo &blockInfo)=0
virtual llvm::FunctionCallee GetGetStructFunction()=0
virtual llvm::Constant * GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0
GetOrEmitProtocol - Get the protocol object for the given declaration, emitting it if necessary.
virtual ConstantAddress GenerateConstantString(const StringLiteral *)=0
Generate a constant string object.
virtual llvm::Value * GetClass(CodeGenFunction &CGF, const ObjCInterfaceDecl *OID)=0
GetClass - Return a reference to the class for the given interface decl.
virtual void GenerateProtocol(const ObjCProtocolDecl *OPD)=0
Generate the named protocol.
virtual llvm::Constant * BuildRCBlockLayout(CodeGen::CodeGenModule &CGM, const CodeGen::CGBlockInfo &blockInfo)=0
virtual llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic, bool copy)=0
Return the runtime function for optimized setting properties.
virtual llvm::Value * GetSelector(CodeGenFunction &CGF, Selector Sel)=0
Get a selector for the specified name and type values.
virtual void GenerateDirectMethodPrologue(CodeGenFunction &CGF, llvm::Function *Fn, const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD)=0
Generates prologue for direct Objective-C Methods.
virtual Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel)=0
Get the address of a selector for the specified name and type values.
virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest)=0
virtual llvm::Value * EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF)
virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest, bool threadlocal=false)=0
virtual llvm::FunctionCallee GetPropertyGetFunction()=0
Return the runtime function for getting properties.
virtual llvm::FunctionCallee GetSetStructFunction()=0
virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S)=0
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
void addFrom(const CallArgList &other)
Add all the arguments from another CallArgList to this one.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
SmallVector< llvm::Value *, 8 > ObjCEHValueStack
ObjCEHValueStack - Stack of Objective-C exception values, used for rethrows.
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...
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
JumpDest ReturnBlock
ReturnBlock - Unified return block.
llvm::Value * EmitObjCThrowOperand(const Expr *expr)
llvm::Value * LoadObjCSelf()
LoadObjCSelf - Load the value of self.
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
void EmitVarDecl(const VarDecl &D)
EmitVarDecl - Emit a local variable declaration.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
static bool hasAggregateEvaluationKind(QualType T)
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
llvm::LLVMContext & getLLVMContext()
This class organizes the cross-function state that is used while generating LLVM code.
void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const
Set visibility, dllimport/dllexport and dso_local.
llvm::Module & getModule() const
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
void addCompilerUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.compiler.used metadata.
bool ReturnTypeUsesFPRet(QualType ResultType)
Return true iff the given type uses 'fpret' when used as a return type.
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
void addUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.used metadata.
const llvm::DataLayout & getDataLayout() const
CGCXXABI & getCXXABI() const
const llvm::Triple & getTriple() const
bool ReturnTypeHasInReg(const CGFunctionInfo &FI)
Return true iff the given type has inreg set.
ASTContext & getContext() const
bool ReturnTypeUsesSRet(const CGFunctionInfo &FI)
Return true iff the given type uses 'sret' when used as a return type.
const CodeGenOptions & getCodeGenOpts() const
llvm::LLVMContext & getLLVMContext()
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
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.
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
bool isZeroInitializable(QualType T)
IsZeroInitializable - Return whether a type can be zero-initialized (in the C++ sense) with an LLVM z...
A specialization of Address that requires the address to be an LLVM Constant.
ArrayBuilder beginArray(llvm::Type *eltTy=nullptr)
llvm::GlobalVariable * finishAndCreateGlobal(As &&...args)
Given that this builder was created by beginning an array or struct directly on a ConstantInitBuilder...
StructBuilder beginStruct(llvm::StructType *ty=nullptr)
void finishAndAddTo(AggregateBuilderBase &parent)
Given that this builder was created by beginning an array or struct component on the given parent bui...
A helper class of ConstantInitBuilder, used for building constant array initializers.
The standard implementation of ConstantInitBuilder used in Clang.
A helper class of ConstantInitBuilder, used for building constant struct initializers.
LValue - This represents an lvalue references.
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
An abstract representation of an aligned address.
llvm::Value * getPointer() const
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
Decl - This represents one declaration (or definition), e.g.
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
StringRef getName() const
This represents one expression.
StringRef getName() const
The name of this FileEntry.
DirectoryEntryRef getDir() const
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
std::string ObjCConstantStringClass
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Visibility getVisibility() const
Determines the visibility of this entity.
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...
Represents Objective-C's @synchronized statement.
Represents Objective-C's @throw statement.
Represents Objective-C's @try ... @catch ... @finally statement.
ObjCCategoryDecl - Represents a category declaration.
const ObjCProtocolList & getReferencedProtocols() const
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
ObjCCategoryDecl * getCategoryDecl() const
ObjCCompatibleAliasDecl - Represents alias of a class.
const ObjCInterfaceDecl * getClassInterface() const
ObjCContainerDecl - Represents a container for method declarations.
classmeth_iterator classmeth_end() const
classmeth_iterator classmeth_begin() const
instmeth_range instance_methods() const
instmeth_iterator instmeth_end() const
instmeth_iterator instmeth_begin() const
prop_range properties() const
classmeth_range class_methods() const
propimpl_range property_impls() const
const ObjCInterfaceDecl * getClassInterface() const
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Represents an ObjC class declaration.
all_protocol_range all_referenced_protocols() const
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
protocol_range protocols() const
protocol_iterator protocol_end() const
protocol_iterator protocol_begin() const
ObjCInterfaceDecl * getSuperClass() const
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
known_extensions_range known_extensions() const
Interfaces are the core concept in Objective-C for object oriented design.
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
ObjCIvarDecl - Represents an ObjC instance variable.
AccessControl getAccessControl() const
ObjCInterfaceDecl * getContainingInterface()
Return the class interface that this ivar is logically contained in; this is either the interface whe...
ObjCIvarDecl * getNextIvar()
ObjCMethodDecl - Represents an instance or class method declaration.
ImplicitParamDecl * getSelfDecl() const
bool hasParamDestroyedInCallee() const
True if the method has a parameter that's destroyed in the callee.
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
ObjCMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Selector getSelector() const
ImplicitParamDecl * getCmdDecl() const
QualType getReturnType() const
bool isClassMethod() const
ObjCInterfaceDecl * getClassInterface()
Represents a pointer to an Objective C object.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
const ObjCInterfaceType * getInterfaceType() const
If this pointer points to an Objective C @interface type, gets the type for that interface.
Represents a class type in Objective C.
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface.
Represents one property declaration in an Objective-C interface.
ObjCMethodDecl * getGetterMethodDecl() const
ObjCMethodDecl * getSetterMethodDecl() const
Represents an Objective-C protocol declaration.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
bool isNonRuntimeProtocol() const
This is true iff the protocol is tagged with the objc_non_runtime_protocol attribute.
protocol_iterator protocol_begin() const
protocol_range protocols() const
protocol_iterator protocol_end() const
The basic abstraction for the target Objective-C runtime.
const VersionTuple & getVersion() const
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
Kind
The basic Objective-C runtimes that we know about.
@ MacOSX
'macosx' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the non-fragile AB...
@ FragileMacOSX
'macosx-fragile' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the fragil...
@ GNUstep
'gnustep' is the modern non-fragile GNUstep runtime.
@ ObjFW
'objfw' is the Objective-C runtime included in ObjFW
@ iOS
'ios' is the Apple-provided NeXT-derived runtime on iOS or the iOS simulator; it is always non-fragil...
@ GCC
'gcc' is the Objective-C runtime shipped with GCC, implementing a fragile Objective-C ABI
@ WatchOS
'watchos' is a variant of iOS for Apple's watchOS.
A (possibly-)qualified type.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
This table allows us to fully hide how we implement multi-keyword caching.
Smart pointer class that efficiently represents Objective-C method names.
std::string getAsString() const
Derive the full selector name (e.g.
This class handles loading and caching of source files into memory.
StringLiteral - This represents a string literal expression, e.g.
bool containsNonAscii() const
unsigned getLength() const
uint32_t getCodeUnit(size_t i) const
StringRef getString() const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
The top declaration context.
static DeclContext * castToDeclContext(const TranslationUnitDecl *D)
const T * castAs() const
Member-template castAs<specific type>.
bool isObjCQualifiedIdType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isObjCIdType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
Represents a variable declaration or definition.
CGObjCRuntime * CreateGNUObjCRuntime(CodeGenModule &CGM)
Creates an instance of an Objective-C runtime class.
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
bool Zero(InterpState &S, CodePtr OpPC)
RangeSelector node(std::string ID)
Selects a node, including trailing semicolon, if any (for declarations and non-expression statements)...
RangeSelector name(std::string ID)
Given a node with a "name", (like NamedDecl, DeclRefExpr, CxxCtorInitializer, and TypeLoc) selects th...
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
const FunctionProtoType * T
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ HiddenVisibility
Objects with "hidden" visibility are not seen by the dynamic linker.
The MS C++ ABI needs a pointer to RTTI data plus some flags to describe the type of a catch handler,...
CharUnits getIntAlign() const
llvm::IntegerType * Int16Ty
llvm::PointerType * Int8PtrTy
CharUnits getPointerAlign() const
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4