31#include "llvm/ADT/SmallVector.h"
32#include "llvm/ADT/StringMap.h"
33#include "llvm/IR/DataLayout.h"
34#include "llvm/IR/Intrinsics.h"
35#include "llvm/IR/LLVMContext.h"
36#include "llvm/IR/Module.h"
37#include "llvm/Support/Compiler.h"
38#include "llvm/Support/ConvertUTF.h"
42using namespace CodeGen;
49class LazyRuntimeFunction {
51 llvm::FunctionType *FTy =
nullptr;
52 const char *FunctionName =
nullptr;
53 llvm::FunctionCallee
Function =
nullptr;
56 LazyRuntimeFunction() =
default;
60 template <
typename... Tys>
61 void init(
CodeGenModule *Mod,
const char *name, llvm::Type *RetTy,
68 FTy = llvm::FunctionType::get(RetTy, ArgTys,
false);
71 FTy = llvm::FunctionType::get(RetTy, {},
false);
75 llvm::FunctionType *getType() {
return FTy; }
79 operator llvm::FunctionCallee() {
96 llvm::Module &TheModule;
99 llvm::StructType *ObjCSuperTy;
102 llvm::PointerType *PtrToObjCSuperTy;
106 llvm::PointerType *SelectorTy;
108 llvm::Type *SelectorElemTy;
111 llvm::IntegerType *Int8Ty;
114 llvm::PointerType *PtrToInt8Ty;
116 llvm::StructType *ProtocolTy;
118 llvm::PointerType *ProtocolPtrTy;
124 llvm::PointerType *IMPTy;
129 llvm::PointerType *IdTy;
131 llvm::Type *IdElemTy;
134 llvm::PointerType *PtrToIdTy;
139 llvm::IntegerType *IntTy;
143 llvm::PointerType *PtrTy;
147 llvm::IntegerType *LongTy;
149 llvm::IntegerType *SizeTy;
151 llvm::IntegerType *IntPtrTy;
153 llvm::IntegerType *PtrDiffTy;
156 llvm::PointerType *PtrToIntTy;
160 llvm::IntegerType *Int32Ty;
162 llvm::IntegerType *Int64Ty;
164 llvm::StructType *PropertyMetadataTy;
168 unsigned msgSendMDKind;
171 bool usesSEHExceptions;
173 bool usesCxxExceptions;
178 return (R.
getKind() == kind) &&
179 (R.
getVersion() >= VersionTuple(major, minor));
182 std::string ManglePublicSymbol(StringRef Name) {
183 return (StringRef(CGM.
getTriple().isOSBinFormatCOFF() ?
"$_" :
"._") + Name).str();
186 std::string SymbolForProtocol(Twine Name) {
187 return (ManglePublicSymbol(
"OBJC_PROTOCOL_") + Name).str();
190 std::string SymbolForProtocolRef(StringRef Name) {
191 return (ManglePublicSymbol(
"OBJC_REF_PROTOCOL_") + Name).str();
198 llvm::Constant *MakeConstantString(StringRef Str,
const char *Name =
"") {
201 return Array.getPointer();
208 llvm::Constant *ExportUniqueString(
const std::string &Str,
209 const std::string &prefix,
210 bool Private=
false) {
211 std::string
name = prefix + Str;
212 auto *ConstStr = TheModule.getGlobalVariable(name);
214 llvm::Constant *value = llvm::ConstantDataArray::getString(VMContext,Str);
215 auto *GV =
new llvm::GlobalVariable(TheModule, value->getType(),
true,
216 llvm::GlobalValue::LinkOnceODRLinkage, value, name);
217 GV->setComdat(TheModule.getOrInsertComdat(name));
219 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
227 const Decl *Container) {
230 std::string NameAndAttributes;
231 std::string TypeStr =
233 NameAndAttributes +=
'\0';
234 NameAndAttributes += TypeStr.length() + 3;
235 NameAndAttributes += TypeStr;
236 NameAndAttributes +=
'\0';
238 return MakeConstantString(NameAndAttributes);
247 int attrs =
property->getPropertyAttributes();
250 attrs &= ~ObjCPropertyAttribute::kind_copy;
251 attrs &= ~ObjCPropertyAttribute::kind_retain;
252 attrs &= ~ObjCPropertyAttribute::kind_weak;
253 attrs &= ~ObjCPropertyAttribute::kind_strong;
256 Fields.addInt(Int8Ty, attrs & 0xff);
262 attrs |= isSynthesized ? (1<<0) : 0;
263 attrs |= isDynamic ? (1<<1) : 0;
266 Fields.addInt(Int8Ty, attrs & 0xff);
268 Fields.addInt(Int8Ty, 0);
269 Fields.addInt(Int8Ty, 0);
272 virtual llvm::Constant *GenerateCategoryProtocolList(
const
277 Fields.addInt(IntTy, count);
280 const llvm::DataLayout &DL = TheModule.getDataLayout();
281 Fields.addInt(IntTy, DL.getTypeSizeInBits(PropertyMetadataTy) /
292 bool isSynthesized=
true,
bool
294 auto Fields = PropertiesArray.
beginStruct(PropertyMetadataTy);
296 Fields.add(MakePropertyEncodingString(property, OCD));
297 PushPropertyAttributes(Fields, property, isSynthesized, isDynamic);
301 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
302 Fields.add(MakeConstantString(accessor->getSelector().getAsString()));
303 Fields.add(TypeEncoding);
317 llvm::Value *EnforceType(
CGBuilderTy &B, llvm::Value *
V, llvm::Type *Ty) {
318 if (
V->getType() == Ty)
320 return B.CreateBitCast(
V, Ty);
324 llvm::Constant *Zeros[2];
326 llvm::Constant *NULLPtr;
328 llvm::LLVMContext &VMContext;
336 llvm::GlobalAlias *ClassPtrAlias;
341 llvm::GlobalAlias *MetaClassPtrAlias;
343 std::vector<llvm::Constant*> Classes;
345 std::vector<llvm::Constant*> Categories;
348 std::vector<llvm::Constant*> ConstantStrings;
352 llvm::StringMap<llvm::Constant*> ObjCStrings;
354 llvm::StringMap<llvm::Constant*> ExistingProtocols;
360 typedef std::pair<std::string, llvm::GlobalAlias*> TypedSelector;
364 typedef llvm::DenseMap<Selector, SmallVector<TypedSelector, 2> >
372 Selector RetainSel, ReleaseSel, AutoreleaseSel;
376 LazyRuntimeFunction IvarAssignFn, StrongCastAssignFn, MemMoveFn, WeakReadFn,
377 WeakAssignFn, GlobalAssignFn;
379 typedef std::pair<std::string, std::string> ClassAliasPair;
381 std::vector<ClassAliasPair> ClassAliases;
385 LazyRuntimeFunction ExceptionThrowFn;
388 LazyRuntimeFunction ExceptionReThrowFn;
391 LazyRuntimeFunction EnterCatchFn;
394 LazyRuntimeFunction ExitCatchFn;
396 LazyRuntimeFunction SyncEnterFn;
398 LazyRuntimeFunction SyncExitFn;
403 LazyRuntimeFunction EnumerationMutationFn;
406 LazyRuntimeFunction GetPropertyFn;
409 LazyRuntimeFunction SetPropertyFn;
411 LazyRuntimeFunction GetStructPropertyFn;
413 LazyRuntimeFunction SetStructPropertyFn;
425 const int ProtocolVersion;
428 const int ClassABIVersion;
444 llvm::Constant *GenerateMethodList(StringRef ClassName,
445 StringRef CategoryName,
447 bool isClassMethodList);
452 virtual llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName);
456 llvm::Constant *GeneratePropertyList(
const Decl *Container,
458 bool isClassProperty=
false,
459 bool protocolOptionalProperties=
false);
469 void GenerateProtocolHolderCategory();
472 llvm::Constant *GenerateClassStructure(
473 llvm::Constant *MetaClass,
474 llvm::Constant *SuperClass,
477 llvm::Constant *Version,
478 llvm::Constant *InstanceSize,
479 llvm::Constant *IVars,
480 llvm::Constant *Methods,
481 llvm::Constant *Protocols,
482 llvm::Constant *IvarOffsets,
483 llvm::Constant *Properties,
484 llvm::Constant *StrongIvarBitmap,
485 llvm::Constant *WeakIvarBitmap,
490 virtual llvm::Constant *GenerateProtocolMethodList(
494 void EmitProtocolMethodList(
T &&Methods, llvm::Constant *&
Required,
498 for (
const auto *I : Methods)
500 OptionalMethods.push_back(I);
502 RequiredMethods.push_back(I);
503 Required = GenerateProtocolMethodList(RequiredMethods);
504 Optional = GenerateProtocolMethodList(OptionalMethods);
510 const std::string &TypeEncoding);
517 const std::string Name =
"__objc_ivar_offset_" +
ID->getNameAsString()
526 void EmitClassRef(
const std::string &className);
530 const std::string &Name,
bool isWeak);
536 llvm::Value *&Receiver,
539 MessageSendInfo &MSI) = 0;
547 MessageSendInfo &MSI) = 0;
564 unsigned protocolClassVersion,
unsigned classABI=1);
571 llvm::Value *Receiver,
const CallArgList &CallArgs,
578 bool isCategoryImpl, llvm::Value *Receiver,
587 virtual llvm::Constant *GetConstantSelector(
Selector Sel,
588 const std::string &TypeEncoding) {
589 llvm_unreachable(
"Runtime unable to generate constant selector");
601 llvm::DenseMap<const ObjCMethodDecl *, llvm::Function *>
602 DirectMethodDefinitions;
636 bool ClearInsertionPoint=
true)
override;
640 llvm::Value *src,
Address dst)
override;
642 llvm::Value *src,
Address dest,
643 bool threadlocal=
false)
override;
645 Address dest, llvm::Value *ivarOffset)
override;
647 llvm::Value *src,
Address dest)
override;
650 llvm::Value *Size)
override;
653 unsigned CVRQualifiers)
override;
680class CGObjCGCC :
public CGObjCGNU {
683 LazyRuntimeFunction MsgLookupFn;
687 LazyRuntimeFunction MsgLookupSuperFn;
691 llvm::Value *cmd, llvm::MDNode *node,
692 MessageSendInfo &MSI)
override {
694 llvm::Value *args[] = {
695 EnforceType(Builder, Receiver, IdTy),
696 EnforceType(Builder, cmd, SelectorTy) };
698 imp->setMetadata(msgSendMDKind, node);
703 llvm::Value *cmd, MessageSendInfo &MSI)
override {
705 llvm::Value *lookupArgs[] = {
706 EnforceType(Builder, ObjCSuper.
emitRawPointer(CGF), PtrToObjCSuperTy),
714 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
716 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
717 PtrToObjCSuperTy, SelectorTy);
722class CGObjCGNUstep :
public CGObjCGNU {
725 LazyRuntimeFunction SlotLookupFn;
730 LazyRuntimeFunction SlotLookupSuperFn;
732 LazyRuntimeFunction SetPropertyAtomic;
734 LazyRuntimeFunction SetPropertyAtomicCopy;
736 LazyRuntimeFunction SetPropertyNonAtomic;
738 LazyRuntimeFunction SetPropertyNonAtomicCopy;
741 LazyRuntimeFunction CxxAtomicObjectGetFn;
744 LazyRuntimeFunction CxxAtomicObjectSetFn;
749 llvm::Type *SlotStructTy;
752 llvm::Constant *GetEHType(
QualType T)
override;
756 llvm::Value *cmd, llvm::MDNode *node,
757 MessageSendInfo &MSI)
override {
759 llvm::FunctionCallee LookupFn = SlotLookupFn;
764 Builder.CreateStore(Receiver, ReceiverPtr);
771 self = llvm::ConstantPointerNull::get(IdTy);
775 if (
auto *LookupFn2 = dyn_cast<llvm::Function>(LookupFn.getCallee()))
776 LookupFn2->addParamAttr(
778 llvm::CaptureInfo::none()));
780 llvm::Value *args[] = {
781 EnforceType(Builder, ReceiverPtr.
getPointer(), PtrToIdTy),
782 EnforceType(Builder, cmd, SelectorTy),
783 EnforceType(Builder, self, IdTy)};
785 slot->setOnlyReadsMemory();
786 slot->setMetadata(msgSendMDKind, node);
789 llvm::Value *imp = Builder.CreateAlignedLoad(
790 IMPTy, Builder.CreateStructGEP(SlotStructTy, slot, 4),
795 Receiver = Builder.CreateLoad(ReceiverPtr,
true);
801 MessageSendInfo &MSI)
override {
805 llvm::CallInst *slot =
807 slot->setOnlyReadsMemory();
809 return Builder.CreateAlignedLoad(
810 IMPTy, Builder.CreateStructGEP(SlotStructTy, slot, 4),
815 CGObjCGNUstep(
CodeGenModule &Mod) : CGObjCGNUstep(Mod, 9, 3, 1) {}
816 CGObjCGNUstep(
CodeGenModule &Mod,
unsigned ABI,
unsigned ProtocolABI,
818 CGObjCGNU(Mod, ABI, ProtocolABI, ClassABI) {
821 SlotStructTy = llvm::StructType::get(PtrTy, PtrTy, PtrTy, IntTy, IMPTy);
824 SlotLookupFn.init(&CGM,
"objc_msg_lookup_sender", SlotTy, PtrToIdTy,
827 SlotLookupSuperFn.init(&CGM,
"objc_slot_lookup_super", SlotTy,
828 PtrToObjCSuperTy, SelectorTy);
830 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
831 if (usesCxxExceptions) {
833 EnterCatchFn.init(&CGM,
"__cxa_begin_catch", PtrTy, PtrTy);
835 ExitCatchFn.init(&CGM,
"__cxa_end_catch", VoidTy);
837 ExceptionReThrowFn.init(&CGM,
"__cxa_rethrow", PtrTy);
838 }
else if (usesSEHExceptions) {
840 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy);
843 EnterCatchFn.init(&CGM,
"__cxa_begin_catch", PtrTy, PtrTy);
845 ExitCatchFn.init(&CGM,
"__cxa_end_catch", VoidTy);
847 ExceptionReThrowFn.init(&CGM,
"_Unwind_Resume_or_Rethrow", VoidTy,
849 }
else if (R.
getVersion() >= VersionTuple(1, 7)) {
851 EnterCatchFn.init(&CGM,
"objc_begin_catch", IdTy, PtrTy);
853 ExitCatchFn.init(&CGM,
"objc_end_catch", VoidTy);
855 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy, PtrTy);
857 SetPropertyAtomic.init(&CGM,
"objc_setProperty_atomic", VoidTy, IdTy,
858 SelectorTy, IdTy, PtrDiffTy);
859 SetPropertyAtomicCopy.init(&CGM,
"objc_setProperty_atomic_copy", VoidTy,
860 IdTy, SelectorTy, IdTy, PtrDiffTy);
861 SetPropertyNonAtomic.init(&CGM,
"objc_setProperty_nonatomic", VoidTy,
862 IdTy, SelectorTy, IdTy, PtrDiffTy);
863 SetPropertyNonAtomicCopy.init(&CGM,
"objc_setProperty_nonatomic_copy",
864 VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy);
867 CxxAtomicObjectSetFn.init(&CGM,
"objc_setCppObjectAtomic", VoidTy, PtrTy,
871 CxxAtomicObjectGetFn.init(&CGM,
"objc_getCppObjectAtomic", VoidTy, PtrTy,
875 llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override {
880 return CxxAtomicObjectGetFn;
883 llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override {
888 return CxxAtomicObjectSetFn;
891 llvm::FunctionCallee GetOptimizedPropertySetFunction(
bool atomic,
892 bool copy)
override {
896 assert ((CGM.
getLangOpts().getGC() == LangOptions::NonGC));
903 if (copy)
return SetPropertyAtomicCopy;
904 return SetPropertyAtomic;
907 return copy ? SetPropertyNonAtomicCopy : SetPropertyNonAtomic;
914class CGObjCGNUstep2 :
public CGObjCGNUstep {
919 ClassReferenceSection,
922 ProtocolReferenceSection,
924 ConstantStringSection
929 ClassFlagMeta = (1 << 0),
932 ClassFlagInitialized = (1 << 8),
934 static const char *
const SectionsBaseNames[8];
935 static const char *
const PECOFFSectionsBaseNames[8];
936 template<SectionKind K>
937 std::string sectionName() {
938 if (CGM.
getTriple().isOSBinFormatCOFF()) {
939 std::string
name(PECOFFSectionsBaseNames[K]);
943 return SectionsBaseNames[K];
948 LazyRuntimeFunction MsgLookupSuperFn;
950 LazyRuntimeFunction SentInitializeFn;
954 bool EmittedProtocol =
false;
959 bool EmittedProtocolRef =
false;
963 bool EmittedClass =
false;
967 typedef std::pair<std::string, std::pair<llvm::GlobalVariable*, int>>
969 std::vector<EarlyInitPair> EarlyInitList;
971 std::string SymbolForClassRef(StringRef Name,
bool isWeak) {
973 return (ManglePublicSymbol(
"OBJC_WEAK_REF_CLASS_") + Name).str();
975 return (ManglePublicSymbol(
"OBJC_REF_CLASS_") + Name).str();
978 std::string SymbolForClass(StringRef Name) {
979 return (ManglePublicSymbol(
"OBJC_CLASS_") + Name).str();
981 void CallRuntimeFunction(
CGBuilderTy &B, StringRef FunctionName,
984 for (
auto *Arg : Args)
985 Types.push_back(Arg->getType());
986 llvm::FunctionType *FT = llvm::FunctionType::get(B.getVoidTy(), Types,
989 B.CreateCall(Fn, Args);
998 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
999 if (old != ObjCStrings.end())
1007 (LiteralLength < 9) && !isNonASCII) {
1013 for (
unsigned i=0 ; i<LiteralLength ; i++)
1014 str |= ((uint64_t)SL->
getCodeUnit(i)) << ((64 - 4 - 3) - (i*7));
1016 str |= LiteralLength << 3;
1019 auto *ObjCStr = llvm::ConstantExpr::getIntToPtr(
1020 llvm::ConstantInt::get(Int64Ty, str), IdTy);
1021 ObjCStrings[Str] = ObjCStr;
1027 if (StringClass.empty()) StringClass =
"NSConstantString";
1029 std::string Sym = SymbolForClass(StringClass);
1031 llvm::Constant *
isa = TheModule.getNamedGlobal(Sym);
1034 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
1035 llvm::GlobalValue::ExternalLinkage,
nullptr, Sym);
1036 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1037 cast<llvm::GlobalValue>(isa)->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
1052 auto Fields = Builder.beginStruct();
1053 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
1056 Fields.addNullPointer(PtrTy);
1063 unsigned NumU8CodeUnits = Str.size();
1068 const llvm::UTF8 *FromPtr = (
const llvm::UTF8 *)Str.data();
1069 llvm::UTF16 *ToPtr = &ToBuf[0];
1070 (void)llvm::ConvertUTF8toUTF16(&FromPtr, FromPtr + NumU8CodeUnits,
1071 &ToPtr, ToPtr + NumU8CodeUnits, llvm::strictConversion);
1072 uint32_t StringLength = ToPtr - &ToBuf[0];
1076 Fields.addInt(Int32Ty, 2);
1078 Fields.addInt(Int32Ty, StringLength);
1080 Fields.addInt(Int32Ty, StringLength * 2);
1082 Fields.addInt(Int32Ty, 0);
1085 auto *
C = llvm::ConstantDataArray::get(VMContext, Arr);
1086 auto *Buffer =
new llvm::GlobalVariable(TheModule,
C->getType(),
1087 true, llvm::GlobalValue::PrivateLinkage,
C,
".str");
1088 Buffer->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1092 Fields.addInt(Int32Ty, 0);
1094 Fields.addInt(Int32Ty, Str.size());
1096 Fields.addInt(Int32Ty, Str.size());
1098 Fields.addInt(Int32Ty, 0);
1100 Fields.add(MakeConstantString(Str));
1102 std::string StringName;
1105 StringName =
".objc_str_";
1106 for (
unsigned char c : Str) {
1117 llvm::GlobalVariable *ObjCStrGV =
1119 isNamed ? StringRef(StringName) :
".objc_string",
1120 Align,
false,
isNamed ? llvm::GlobalValue::LinkOnceODRLinkage
1121 : llvm::GlobalValue::PrivateLinkage);
1122 ObjCStrGV->setSection(sectionName<ConstantStringSection>());
1124 ObjCStrGV->setComdat(TheModule.getOrInsertComdat(StringName));
1125 ObjCStrGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1127 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1128 std::pair<llvm::GlobalVariable*, int> v{ObjCStrGV, 0};
1129 EarlyInitList.emplace_back(Sym, v);
1131 ObjCStrings[Str] = ObjCStrGV;
1132 ConstantStrings.push_back(ObjCStrGV);
1139 bool isSynthesized=
true,
bool
1140 isDynamic=
true)
override {
1149 auto Fields = PropertiesArray.
beginStruct(PropertyMetadataTy);
1152 std::string TypeStr =
1154 Fields.add(MakeConstantString(TypeStr));
1155 std::string typeStr;
1157 Fields.add(MakeConstantString(typeStr));
1161 Fields.add(GetConstantSelector(accessor->getSelector(), TypeStr));
1163 Fields.add(NULLPtr);
1178 llvm::StructType *ObjCMethodDescTy =
1180 { PtrToInt8Ty, PtrToInt8Ty });
1189 auto MethodList = Builder.beginStruct();
1191 MethodList.addInt(IntTy, Methods.size());
1193 const llvm::DataLayout &DL = TheModule.getDataLayout();
1194 MethodList.addInt(IntTy, DL.getTypeSizeInBits(ObjCMethodDescTy) /
1197 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
1198 for (
auto *M : Methods) {
1199 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
1200 Method.add(CGObjCGNU::GetConstantSelector(M));
1202 Method.finishAndAddTo(MethodArray);
1204 MethodArray.finishAndAddTo(MethodList);
1205 return MethodList.finishAndCreateGlobal(
".objc_protocol_method_list",
1211 auto RuntimeProtocols = GetRuntimeProtocolList(ReferencedProtocols.begin(),
1212 ReferencedProtocols.end());
1214 for (
const auto *PI : RuntimeProtocols)
1215 Protocols.push_back(GenerateProtocolRef(PI));
1216 return GenerateProtocolList(Protocols);
1220 llvm::Value *cmd, MessageSendInfo &MSI)
override {
1223 llvm::Value *lookupArgs[] = {
1230 llvm::GlobalVariable *GetClassVar(StringRef Name,
bool isWeak=
false) {
1231 std::string SymbolName = SymbolForClassRef(Name, isWeak);
1232 auto *ClassSymbol = TheModule.getNamedGlobal(SymbolName);
1235 ClassSymbol =
new llvm::GlobalVariable(TheModule,
1236 IdTy,
false, llvm::GlobalValue::ExternalLinkage,
1237 nullptr, SymbolName);
1243 ClassSymbol->setInitializer(
new llvm::GlobalVariable(TheModule,
1244 Int8Ty,
false, llvm::GlobalValue::ExternalWeakLinkage,
1245 nullptr, SymbolForClass(Name)));
1247 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1253 for (
const auto *Result : DC->
lookup(&II))
1254 if ((OID = dyn_cast<ObjCInterfaceDecl>(Result)))
1260 assert(OID &&
"Failed to find ObjCInterfaceDecl");
1262 if (OIDDef !=
nullptr)
1265 auto Storage = llvm::GlobalValue::DefaultStorageClass;
1266 if (OID->
hasAttr<DLLImportAttr>())
1267 Storage = llvm::GlobalValue::DLLImportStorageClass;
1268 else if (OID->
hasAttr<DLLExportAttr>())
1269 Storage = llvm::GlobalValue::DLLExportStorageClass;
1271 cast<llvm::GlobalValue>(ClassSymbol)->setDLLStorageClass(Storage);
1274 assert(ClassSymbol->getName() == SymbolName);
1278 const std::string &Name,
1279 bool isWeak)
override {
1291 switch (Ownership) {
1313 llvm_unreachable(
"Method should not be called!");
1316 llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName)
override {
1317 std::string Name = SymbolForProtocol(ProtocolName);
1318 auto *GV = TheModule.getGlobalVariable(Name);
1321 GV =
new llvm::GlobalVariable(TheModule, ProtocolTy,
false,
1322 llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
1329 llvm::StringMap<llvm::Constant*> ExistingProtocolRefs;
1334 auto *&Ref = ExistingProtocolRefs[Name];
1336 auto *&
Protocol = ExistingProtocols[Name];
1338 Protocol = GenerateProtocolRef(PD);
1339 std::string RefName = SymbolForProtocolRef(Name);
1340 assert(!TheModule.getGlobalVariable(RefName));
1342 auto GV =
new llvm::GlobalVariable(TheModule, ProtocolPtrTy,
false,
1343 llvm::GlobalValue::LinkOnceODRLinkage,
1345 GV->setComdat(TheModule.getOrInsertComdat(RefName));
1346 GV->setSection(sectionName<ProtocolReferenceSection>());
1350 EmittedProtocolRef =
true;
1356 llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(ProtocolPtrTy,
1358 llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
1361 auto ProtocolBuilder = builder.beginStruct();
1362 ProtocolBuilder.addNullPointer(PtrTy);
1363 ProtocolBuilder.addInt(SizeTy, Protocols.size());
1364 ProtocolBuilder.add(ProtocolArray);
1365 return ProtocolBuilder.finishAndCreateGlobal(
".objc_protocol_list",
1374 auto *&
Protocol = ExistingProtocols[ProtocolName];
1378 EmittedProtocol =
true;
1380 auto SymName = SymbolForProtocol(ProtocolName);
1381 auto *OldGV = TheModule.getGlobalVariable(SymName);
1391 Protocol =
new llvm::GlobalVariable(TheModule, ProtocolTy,
1393 llvm::GlobalValue::ExternalLinkage,
nullptr, SymName);
1398 auto RuntimeProtocols =
1400 for (
const auto *PI : RuntimeProtocols)
1401 Protocols.push_back(GenerateProtocolRef(PI));
1402 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
1405 llvm::Constant *InstanceMethodList, *OptionalInstanceMethodList;
1406 llvm::Constant *ClassMethodList, *OptionalClassMethodList;
1408 OptionalInstanceMethodList);
1409 EmitProtocolMethodList(PD->
class_methods(), ClassMethodList,
1410 OptionalClassMethodList);
1415 auto ProtocolBuilder = builder.beginStruct();
1416 ProtocolBuilder.add(llvm::ConstantExpr::getIntToPtr(
1417 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
1418 ProtocolBuilder.add(MakeConstantString(ProtocolName));
1419 ProtocolBuilder.add(ProtocolList);
1420 ProtocolBuilder.add(InstanceMethodList);
1421 ProtocolBuilder.add(ClassMethodList);
1422 ProtocolBuilder.add(OptionalInstanceMethodList);
1423 ProtocolBuilder.add(OptionalClassMethodList);
1425 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
false,
false));
1427 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
false,
true));
1429 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
true,
false));
1431 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
true,
true));
1433 auto *GV = ProtocolBuilder.finishAndCreateGlobal(SymName,
1435 GV->setSection(sectionName<ProtocolSection>());
1436 GV->setComdat(TheModule.getOrInsertComdat(SymName));
1438 OldGV->replaceAllUsesWith(GV);
1439 OldGV->removeFromParent();
1440 GV->setName(SymName);
1446 const std::string &TypeEncoding)
override {
1447 return GetConstantSelector(Sel, TypeEncoding);
1449 std::string GetSymbolNameForTypeEncoding(
const std::string &TypeEncoding) {
1450 std::string MangledTypes = std::string(TypeEncoding);
1456 llvm::replace(MangledTypes,
'@',
'\1');
1459 llvm::replace(MangledTypes,
'=',
'\2');
1460 return MangledTypes;
1462 llvm::Constant *GetTypeString(llvm::StringRef TypeEncoding) {
1463 if (TypeEncoding.empty())
1465 std::string MangledTypes =
1466 GetSymbolNameForTypeEncoding(std::string(TypeEncoding));
1467 std::string TypesVarName =
".objc_sel_types_" + MangledTypes;
1468 auto *TypesGlobal = TheModule.getGlobalVariable(TypesVarName);
1470 llvm::Constant *
Init = llvm::ConstantDataArray::getString(VMContext,
1472 auto *GV =
new llvm::GlobalVariable(TheModule,
Init->getType(),
1473 true, llvm::GlobalValue::LinkOnceODRLinkage,
Init, TypesVarName);
1474 GV->setComdat(TheModule.getOrInsertComdat(TypesVarName));
1475 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1480 llvm::Constant *GetConstantSelector(
Selector Sel,
1481 const std::string &TypeEncoding)
override {
1482 std::string MangledTypes = GetSymbolNameForTypeEncoding(TypeEncoding);
1483 auto SelVarName = (StringRef(
".objc_selector_") + Sel.
getAsString() +
"_" +
1484 MangledTypes).str();
1485 if (
auto *GV = TheModule.getNamedGlobal(SelVarName))
1488 auto SelBuilder = builder.beginStruct();
1489 SelBuilder.add(ExportUniqueString(Sel.
getAsString(),
".objc_sel_name_",
1491 SelBuilder.add(GetTypeString(TypeEncoding));
1492 auto *GV = SelBuilder.finishAndCreateGlobal(SelVarName,
1494 GV->setComdat(TheModule.getOrInsertComdat(SelVarName));
1495 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1496 GV->setSection(sectionName<SelectorSection>());
1499 llvm::StructType *emptyStruct =
nullptr;
1508 std::pair<llvm::Constant*,llvm::Constant*>
1509 GetSectionBounds(StringRef Section) {
1510 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1511 if (emptyStruct ==
nullptr) {
1512 emptyStruct = llvm::StructType::create(
1513 VMContext, {},
".objc_section_sentinel",
true);
1515 auto ZeroInit = llvm::Constant::getNullValue(emptyStruct);
1516 auto Sym = [&](StringRef Prefix, StringRef SecSuffix) {
1517 auto *Sym =
new llvm::GlobalVariable(TheModule, emptyStruct,
1519 llvm::GlobalValue::LinkOnceODRLinkage, ZeroInit, Prefix +
1521 Sym->setVisibility(llvm::GlobalValue::HiddenVisibility);
1522 Sym->setSection((Section + SecSuffix).str());
1523 Sym->setComdat(TheModule.getOrInsertComdat((Prefix +
1528 return { Sym(
"__start_",
"$a"), Sym(
"__stop",
"$z") };
1530 auto *Start =
new llvm::GlobalVariable(TheModule, PtrTy,
1532 llvm::GlobalValue::ExternalLinkage,
nullptr, StringRef(
"__start_") +
1534 Start->setVisibility(llvm::GlobalValue::HiddenVisibility);
1535 auto *Stop =
new llvm::GlobalVariable(TheModule, PtrTy,
1537 llvm::GlobalValue::ExternalLinkage,
nullptr, StringRef(
"__stop_") +
1539 Stop->setVisibility(llvm::GlobalValue::HiddenVisibility);
1540 return { Start, Stop };
1545 llvm::Function *ModuleInitFunction()
override {
1546 llvm::Function *LoadFunction = llvm::Function::Create(
1547 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
1548 llvm::GlobalValue::LinkOnceODRLinkage,
".objcv2_load_function",
1550 LoadFunction->setVisibility(llvm::GlobalValue::HiddenVisibility);
1551 LoadFunction->setComdat(TheModule.getOrInsertComdat(
".objcv2_load_function"));
1553 llvm::BasicBlock *EntryBB =
1554 llvm::BasicBlock::Create(VMContext,
"entry", LoadFunction);
1556 B.SetInsertPoint(EntryBB);
1558 auto InitStructBuilder = builder.beginStruct();
1559 InitStructBuilder.addInt(Int64Ty, 0);
1560 auto §ionVec = CGM.
getTriple().isOSBinFormatCOFF() ? PECOFFSectionsBaseNames : SectionsBaseNames;
1561 for (
auto *
s : sectionVec) {
1562 auto bounds = GetSectionBounds(
s);
1563 InitStructBuilder.add(bounds.first);
1564 InitStructBuilder.add(bounds.second);
1566 auto *InitStruct = InitStructBuilder.finishAndCreateGlobal(
".objc_init",
1568 InitStruct->setVisibility(llvm::GlobalValue::HiddenVisibility);
1569 InitStruct->setComdat(TheModule.getOrInsertComdat(
".objc_init"));
1571 CallRuntimeFunction(B,
"__objc_load", {InitStruct});;
1578 auto *InitVar =
new llvm::GlobalVariable(TheModule, LoadFunction->getType(),
1579 false, llvm::GlobalValue::LinkOnceAnyLinkage,
1580 LoadFunction,
".objc_ctor");
1583 assert(InitVar->getName() ==
".objc_ctor");
1589 if (CGM.
getTriple().isOSBinFormatCOFF())
1590 InitVar->setSection(
".CRT$XCLz");
1594 InitVar->setSection(
".init_array");
1596 InitVar->setSection(
".ctors");
1598 InitVar->setVisibility(llvm::GlobalValue::HiddenVisibility);
1599 InitVar->setComdat(TheModule.getOrInsertComdat(
".objc_ctor"));
1601 for (
auto *
C : Categories) {
1602 auto *Cat = cast<llvm::GlobalVariable>(
C->stripPointerCasts());
1603 Cat->setSection(sectionName<CategorySection>());
1607 StringRef Section) {
1608 auto nullBuilder = builder.beginStruct();
1609 for (
auto *F :
Init)
1611 auto GV = nullBuilder.finishAndCreateGlobal(Name, CGM.
getPointerAlign(),
1612 false, llvm::GlobalValue::LinkOnceODRLinkage);
1613 GV->setSection(Section);
1614 GV->setComdat(TheModule.getOrInsertComdat(Name));
1615 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1619 for (
auto clsAlias : ClassAliases)
1620 createNullGlobal(std::string(
".objc_class_alias") +
1621 clsAlias.second, { MakeConstantString(clsAlias.second),
1622 GetClassVar(clsAlias.first) }, sectionName<ClassAliasSection>());
1627 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
1628 createNullGlobal(
".objc_null_selector", {NULLPtr, NULLPtr},
1629 sectionName<SelectorSection>());
1630 if (Categories.empty())
1631 createNullGlobal(
".objc_null_category", {NULLPtr, NULLPtr,
1632 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr},
1633 sectionName<CategorySection>());
1634 if (!EmittedClass) {
1635 createNullGlobal(
".objc_null_cls_init_ref", NULLPtr,
1636 sectionName<ClassSection>());
1637 createNullGlobal(
".objc_null_class_ref", { NULLPtr, NULLPtr },
1638 sectionName<ClassReferenceSection>());
1640 if (!EmittedProtocol)
1641 createNullGlobal(
".objc_null_protocol", {NULLPtr, NULLPtr, NULLPtr,
1642 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr,
1643 NULLPtr}, sectionName<ProtocolSection>());
1644 if (!EmittedProtocolRef)
1645 createNullGlobal(
".objc_null_protocol_ref", {NULLPtr},
1646 sectionName<ProtocolReferenceSection>());
1647 if (ClassAliases.empty())
1648 createNullGlobal(
".objc_null_class_alias", { NULLPtr, NULLPtr },
1649 sectionName<ClassAliasSection>());
1650 if (ConstantStrings.empty()) {
1651 auto i32Zero = llvm::ConstantInt::get(Int32Ty, 0);
1652 createNullGlobal(
".objc_null_constant_string", { NULLPtr, i32Zero,
1653 i32Zero, i32Zero, i32Zero, NULLPtr },
1654 sectionName<ConstantStringSection>());
1657 ConstantStrings.clear();
1661 if (EarlyInitList.size() > 0) {
1662 auto *
Init = llvm::Function::Create(llvm::FunctionType::get(CGM.
VoidTy,
1663 {}), llvm::GlobalValue::InternalLinkage,
".objc_early_init",
1665 llvm::IRBuilder<>
b(llvm::BasicBlock::Create(CGM.
getLLVMContext(),
"entry",
1667 for (
const auto &lateInit : EarlyInitList) {
1668 auto *global = TheModule.getGlobalVariable(lateInit.first);
1670 llvm::GlobalVariable *GV = lateInit.second.first;
1671 b.CreateAlignedStore(
1673 b.CreateStructGEP(GV->getValueType(), GV, lateInit.second.second),
1680 auto *InitVar =
new llvm::GlobalVariable(CGM.
getModule(),
Init->getType(),
1681 true, llvm::GlobalValue::InternalLinkage,
1682 Init,
".objc_early_init_ptr");
1683 InitVar->setSection(
".CRT$XCLb");
1692 std::string TypeEncoding;
1694 TypeEncoding = GetSymbolNameForTypeEncoding(TypeEncoding);
1695 const std::string Name =
"__objc_ivar_offset_" +
ID->getNameAsString()
1704 const std::string Name =
1705 GetIVarOffsetVariableName(ContainingInterface, Ivar);
1706 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
1707 if (!IvarOffsetPointer) {
1708 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule, IntTy,
false,
1709 llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
1715 llvm::Value *Offset =
1717 if (Offset->getType() != PtrDiffTy)
1718 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
1723 bool IsCOFF = CGM.
getTriple().isOSBinFormatCOFF();
1729 auto *classNameConstant = MakeConstantString(className);
1732 auto metaclassFields = builder.beginStruct();
1734 metaclassFields.addNullPointer(PtrTy);
1736 metaclassFields.addNullPointer(PtrTy);
1738 metaclassFields.add(classNameConstant);
1740 metaclassFields.addInt(LongTy, 0);
1743 metaclassFields.addInt(LongTy, ClassFlags::ClassFlagMeta);
1747 metaclassFields.addInt(LongTy, 0);
1749 metaclassFields.addNullPointer(PtrTy);
1754 metaclassFields.addNullPointer(PtrTy);
1759 metaclassFields.add(
1760 GenerateMethodList(className,
"", ClassMethods,
true));
1763 metaclassFields.addNullPointer(PtrTy);
1765 metaclassFields.addNullPointer(PtrTy);
1767 metaclassFields.addNullPointer(PtrTy);
1769 metaclassFields.addNullPointer(PtrTy);
1771 metaclassFields.addNullPointer(PtrTy);
1773 metaclassFields.addNullPointer(PtrTy);
1775 metaclassFields.addNullPointer(PtrTy);
1777 metaclassFields.addInt(LongTy, 0);
1779 metaclassFields.add(GeneratePropertyList(OID, classDecl,
true));
1781 auto *metaclass = metaclassFields.finishAndCreateGlobal(
1782 ManglePublicSymbol(
"OBJC_METACLASS_") + className,
1785 auto classFields = builder.beginStruct();
1787 classFields.add(metaclass);
1792 llvm::Constant *SuperClass =
nullptr;
1793 if (SuperClassDecl) {
1794 auto SuperClassName = SymbolForClass(SuperClassDecl->
getNameAsString());
1795 SuperClass = TheModule.getNamedGlobal(SuperClassName);
1798 SuperClass =
new llvm::GlobalVariable(TheModule, PtrTy,
false,
1799 llvm::GlobalValue::ExternalLinkage,
nullptr, SuperClassName);
1801 auto Storage = llvm::GlobalValue::DefaultStorageClass;
1802 if (SuperClassDecl->
hasAttr<DLLImportAttr>())
1803 Storage = llvm::GlobalValue::DLLImportStorageClass;
1804 else if (SuperClassDecl->
hasAttr<DLLExportAttr>())
1805 Storage = llvm::GlobalValue::DLLExportStorageClass;
1807 cast<llvm::GlobalValue>(SuperClass)->setDLLStorageClass(Storage);
1811 classFields.add(SuperClass);
1813 classFields.addNullPointer(PtrTy);
1815 classFields.addNullPointer(PtrTy);
1817 classFields.add(classNameConstant);
1819 classFields.addInt(LongTy, 0);
1822 classFields.addInt(LongTy, 0);
1824 int superInstanceSize = !SuperClassDecl ? 0 :
1832 superInstanceSize));
1835 classFields.addNullPointer(PtrTy);
1840 const llvm::DataLayout &DL = TheModule.getDataLayout();
1843 auto ivarListBuilder =
b.beginStruct();
1845 ivarListBuilder.addInt(IntTy, ivar_count);
1847 llvm::StructType *ObjCIvarTy = llvm::StructType::get(
1853 ivarListBuilder.addInt(SizeTy, DL.getTypeSizeInBits(ObjCIvarTy) /
1856 auto ivarArrayBuilder = ivarListBuilder.beginArray();
1859 auto ivarTy = IVD->getType();
1860 auto ivarBuilder = ivarArrayBuilder.beginStruct();
1862 ivarBuilder.add(MakeConstantString(IVD->getNameAsString()));
1864 std::string TypeStr;
1867 ivarBuilder.add(MakeConstantString(TypeStr));
1869 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
1870 uint64_t Offset = BaseOffset - superInstanceSize;
1871 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
1872 std::string OffsetName = GetIVarOffsetVariableName(classDecl, IVD);
1873 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
1875 OffsetVar->setInitializer(OffsetValue);
1877 OffsetVar =
new llvm::GlobalVariable(TheModule, IntTy,
1878 false, llvm::GlobalValue::ExternalLinkage,
1879 OffsetValue, OffsetName);
1880 auto ivarVisibility =
1884 llvm::GlobalValue::HiddenVisibility :
1885 llvm::GlobalValue::DefaultVisibility;
1886 OffsetVar->setVisibility(ivarVisibility);
1887 if (ivarVisibility != llvm::GlobalValue::HiddenVisibility)
1889 ivarBuilder.add(OffsetVar);
1891 ivarBuilder.addInt(Int32Ty,
1902 ivarBuilder.addInt(Int32Ty,
1903 (align << 3) | (1<<2) |
1904 FlagsForOwnership(ivarTy.getQualifiers().getObjCLifetime()));
1905 ivarBuilder.finishAndAddTo(ivarArrayBuilder);
1907 ivarArrayBuilder.finishAndAddTo(ivarListBuilder);
1908 auto ivarList = ivarListBuilder.finishAndCreateGlobal(
".objc_ivar_list",
1910 llvm::GlobalValue::PrivateLinkage);
1911 classFields.add(ivarList);
1915 InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
1918 if (propImpl->getPropertyImplementation() ==
1921 if (OMD && OMD->hasBody())
1922 InstanceMethods.push_back(OMD);
1924 addIfExists(propImpl->getGetterMethodDecl());
1925 addIfExists(propImpl->getSetterMethodDecl());
1928 if (InstanceMethods.size() == 0)
1929 classFields.addNullPointer(PtrTy);
1932 GenerateMethodList(className,
"", InstanceMethods,
false));
1935 classFields.addNullPointer(PtrTy);
1937 classFields.addNullPointer(PtrTy);
1939 classFields.addNullPointer(PtrTy);
1941 classFields.addNullPointer(PtrTy);
1943 classFields.addNullPointer(PtrTy);
1945 auto RuntimeProtocols =
1949 for (
const auto *I : RuntimeProtocols)
1950 Protocols.push_back(GenerateProtocolRef(I));
1952 if (Protocols.empty())
1953 classFields.addNullPointer(PtrTy);
1955 classFields.add(GenerateProtocolList(Protocols));
1957 classFields.addNullPointer(PtrTy);
1959 classFields.addInt(LongTy, 0);
1961 classFields.add(GeneratePropertyList(OID, classDecl));
1963 llvm::GlobalVariable *classStruct =
1964 classFields.finishAndCreateGlobal(SymbolForClass(className),
1967 auto *classRefSymbol = GetClassVar(className);
1968 classRefSymbol->setSection(sectionName<ClassReferenceSection>());
1969 classRefSymbol->setInitializer(classStruct);
1974 classStruct->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1975 cast<llvm::GlobalValue>(classRefSymbol)->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1979 std::pair<llvm::GlobalVariable*, int> v{classStruct, 1};
1980 EarlyInitList.emplace_back(std::string(SuperClass->getName()),
1989 if (ClassPtrAlias) {
1990 ClassPtrAlias->replaceAllUsesWith(classStruct);
1991 ClassPtrAlias->eraseFromParent();
1992 ClassPtrAlias =
nullptr;
1994 if (
auto Placeholder =
1995 TheModule.getNamedGlobal(SymbolForClass(className)))
1996 if (Placeholder != classStruct) {
1997 Placeholder->replaceAllUsesWith(classStruct);
1998 Placeholder->eraseFromParent();
1999 classStruct->setName(SymbolForClass(className));
2001 if (MetaClassPtrAlias) {
2002 MetaClassPtrAlias->replaceAllUsesWith(metaclass);
2003 MetaClassPtrAlias->eraseFromParent();
2004 MetaClassPtrAlias =
nullptr;
2006 assert(classStruct->getName() == SymbolForClass(className));
2008 auto classInitRef =
new llvm::GlobalVariable(TheModule,
2009 classStruct->getType(),
false, llvm::GlobalValue::ExternalLinkage,
2010 classStruct, ManglePublicSymbol(
"OBJC_INIT_CLASS_") + className);
2011 classInitRef->setSection(sectionName<ClassSection>());
2014 EmittedClass =
true;
2017 CGObjCGNUstep2(
CodeGenModule &Mod) : CGObjCGNUstep(Mod, 10, 4, 2) {
2018 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
2019 PtrToObjCSuperTy, SelectorTy);
2020 SentInitializeFn.init(&CGM,
"objc_send_initialize",
2021 llvm::Type::getVoidTy(VMContext), IdTy);
2030 PropertyMetadataTy =
2032 { PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty });
2035 void GenerateDirectMethodPrologue(
CodeGenFunction &CGF, llvm::Function *Fn,
2039 bool ReceiverCanBeNull =
true;
2041 auto selfValue = Builder.CreateLoad(selfAddr);
2066 ReceiverCanBeNull = isWeakLinkedClass(OID);
2070 if (ReceiverCanBeNull) {
2071 llvm::BasicBlock *SelfIsNilBlock =
2073 llvm::BasicBlock *ContBlock =
2077 auto selfTy = cast<llvm::PointerType>(selfValue->getType());
2078 auto Zero = llvm::ConstantPointerNull::get(selfTy);
2080 Builder.CreateCondBr(Builder.CreateICmpEQ(selfValue,
Zero),
2081 SelfIsNilBlock, ContBlock,
2082 MDHelper.createUnlikelyBranchWeights());
2088 Builder.SetInsertPoint(SelfIsNilBlock);
2089 if (!retTy->isVoidType()) {
2097 Builder.SetInsertPoint(ContBlock);
2103 llvm::StructType::get(PtrTy, PtrTy, PtrTy, LongTy, LongTy);
2110 llvm::Value *Val = Builder.CreateStructGEP(classStart, selfValue, 4);
2112 astContext.getTypeAlign(astContext.UnsignedLongTy));
2113 auto flags = Builder.CreateLoad(
Address{Val, LongTy, Align});
2114 auto isInitialized =
2115 Builder.CreateAnd(flags, ClassFlags::ClassFlagInitialized);
2116 llvm::BasicBlock *notInitializedBlock =
2118 llvm::BasicBlock *initializedBlock =
2120 Builder.CreateCondBr(Builder.CreateICmpEQ(isInitialized, Zeros[0]),
2121 notInitializedBlock, initializedBlock,
2122 MDHelper.createUnlikelyBranchWeights());
2124 Builder.SetInsertPoint(notInitializedBlock);
2126 Builder.CreateBr(initializedBlock);
2128 Builder.SetInsertPoint(initializedBlock);
2136 Builder.CreateStore(GetSelector(CGF, OMD),
2142const char *
const CGObjCGNUstep2::SectionsBaseNames[8] =
2149"__objc_protocol_refs",
2150"__objc_class_aliases",
2151"__objc_constant_string"
2154const char *
const CGObjCGNUstep2::PECOFFSectionsBaseNames[8] =
2167class CGObjCObjFW:
public CGObjCGNU {
2171 LazyRuntimeFunction MsgLookupFn;
2174 LazyRuntimeFunction MsgLookupFnSRet;
2178 LazyRuntimeFunction MsgLookupSuperFn, MsgLookupSuperFnSRet;
2181 llvm::Value *cmd, llvm::MDNode *node,
2182 MessageSendInfo &MSI)
override {
2184 llvm::Value *args[] = {
2185 EnforceType(Builder, Receiver, IdTy),
2186 EnforceType(Builder, cmd, SelectorTy) };
2188 llvm::CallBase *imp;
2194 imp->setMetadata(msgSendMDKind, node);
2199 llvm::Value *cmd, MessageSendInfo &MSI)
override {
2201 llvm::Value *lookupArgs[] = {
2202 EnforceType(Builder, ObjCSuper.
emitRawPointer(CGF), PtrToObjCSuperTy),
2212 llvm::Value *GetClassNamed(
CodeGenFunction &CGF,
const std::string &Name,
2213 bool isWeak)
override {
2215 return CGObjCGNU::GetClassNamed(CGF, Name, isWeak);
2218 std::string SymbolName =
"_OBJC_CLASS_" + Name;
2219 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(SymbolName);
2221 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
2222 llvm::GlobalValue::ExternalLinkage,
2223 nullptr, SymbolName);
2227 void GenerateDirectMethodPrologue(
2231 bool ReceiverCanBeNull =
true;
2233 auto selfValue = Builder.CreateLoad(selfAddr);
2252 "GenerateDirectMethod() should be called with the Class Interface");
2265 result = GeneratePossiblySpecializedMessageSend(
2273 ReceiverCanBeNull = isWeakLinkedClass(OID);
2276 if (ReceiverCanBeNull) {
2277 llvm::BasicBlock *SelfIsNilBlock =
2279 llvm::BasicBlock *ContBlock =
2283 auto selfTy = cast<llvm::PointerType>(selfValue->getType());
2284 auto Zero = llvm::ConstantPointerNull::get(selfTy);
2287 Builder.CreateCondBr(Builder.CreateICmpEQ(selfValue,
Zero),
2288 SelfIsNilBlock, ContBlock,
2289 MDHelper.createUnlikelyBranchWeights());
2295 Builder.SetInsertPoint(SelfIsNilBlock);
2296 if (!retTy->isVoidType()) {
2304 Builder.SetInsertPoint(ContBlock);
2312 Builder.CreateStore(GetSelector(CGF, OMD),
2320 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
2321 MsgLookupFnSRet.init(&CGM,
"objc_msg_lookup_stret", IMPTy, IdTy,
2324 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
2325 PtrToObjCSuperTy, SelectorTy);
2326 MsgLookupSuperFnSRet.init(&CGM,
"objc_msg_lookup_super_stret", IMPTy,
2327 PtrToObjCSuperTy, SelectorTy);
2335void CGObjCGNU::EmitClassRef(
const std::string &className) {
2336 std::string symbolRef =
"__objc_class_ref_" + className;
2338 if (TheModule.getGlobalVariable(symbolRef))
2340 std::string symbolName =
"__objc_class_name_" + className;
2341 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
2343 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
2344 llvm::GlobalValue::ExternalLinkage,
2345 nullptr, symbolName);
2347 new llvm::GlobalVariable(TheModule, ClassSymbol->getType(),
true,
2348 llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef);
2351CGObjCGNU::CGObjCGNU(
CodeGenModule &cgm,
unsigned runtimeABIVersion,
2352 unsigned protocolClassVersion,
unsigned classABI)
2354 VMContext(cgm.getLLVMContext()), ClassPtrAlias(nullptr),
2355 MetaClassPtrAlias(nullptr), RuntimeVersion(runtimeABIVersion),
2356 ProtocolVersion(protocolClassVersion), ClassABIVersion(classABI) {
2358 msgSendMDKind = VMContext.getMDKindID(
"GNUObjCMessageSend");
2366 IntTy = cast<llvm::IntegerType>(
2368 LongTy = cast<llvm::IntegerType>(
2370 SizeTy = cast<llvm::IntegerType>(
2372 PtrDiffTy = cast<llvm::IntegerType>(
2376 Int8Ty = llvm::Type::getInt8Ty(VMContext);
2381 PtrToInt8Ty = PtrTy;
2382 ProtocolPtrTy = PtrTy;
2384 Zeros[0] = llvm::ConstantInt::get(LongTy, 0);
2385 Zeros[1] = Zeros[0];
2386 NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty);
2390 SelectorTy = PtrToInt8Ty;
2391 SelectorElemTy = Int8Ty;
2397 Int32Ty = llvm::Type::getInt32Ty(VMContext);
2398 Int64Ty = llvm::Type::getInt64Ty(VMContext);
2401 CGM.
getDataLayout().getPointerSizeInBits() == 32 ? Int32Ty : Int64Ty;
2416 ProtocolTy = llvm::StructType::get(IdTy,
2438 PropertyMetadataTy = llvm::StructType::get(CGM.
getLLVMContext(), {
2439 PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty,
2440 PtrToInt8Ty, PtrToInt8Ty });
2442 ObjCSuperTy = llvm::StructType::get(IdTy, IdTy);
2443 PtrToObjCSuperTy = PtrTy;
2445 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
2448 ExceptionThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy);
2449 ExceptionReThrowFn.init(&CGM,
2450 usesCxxExceptions ?
"objc_exception_rethrow"
2451 :
"objc_exception_throw",
2454 SyncEnterFn.init(&CGM,
"objc_sync_enter", IntTy, IdTy);
2456 SyncExitFn.init(&CGM,
"objc_sync_exit", IntTy, IdTy);
2459 EnumerationMutationFn.init(&CGM,
"objc_enumerationMutation", VoidTy, IdTy);
2462 GetPropertyFn.init(&CGM,
"objc_getProperty", IdTy, IdTy, SelectorTy,
2465 SetPropertyFn.init(&CGM,
"objc_setProperty", VoidTy, IdTy, SelectorTy,
2466 PtrDiffTy, IdTy, BoolTy, BoolTy);
2468 GetStructPropertyFn.init(&CGM,
"objc_getPropertyStruct", VoidTy, PtrTy, PtrTy,
2469 PtrDiffTy, BoolTy, BoolTy);
2471 SetStructPropertyFn.init(&CGM,
"objc_setPropertyStruct", VoidTy, PtrTy, PtrTy,
2472 PtrDiffTy, BoolTy, BoolTy);
2478 if ((Opts.getGC() != LangOptions::NonGC) || Opts.ObjCAutoRefCount)
2479 RuntimeVersion = 10;
2482 if (Opts.getGC() != LangOptions::NonGC) {
2494 IvarAssignFn.init(&CGM,
"objc_assign_ivar", IdTy, IdTy, IdTy, PtrDiffTy);
2496 StrongCastAssignFn.init(&CGM,
"objc_assign_strongCast", IdTy, IdTy,
2499 GlobalAssignFn.init(&CGM,
"objc_assign_global", IdTy, IdTy, PtrToIdTy);
2501 WeakAssignFn.init(&CGM,
"objc_assign_weak", IdTy, IdTy, PtrToIdTy);
2503 WeakReadFn.init(&CGM,
"objc_read_weak", IdTy, PtrToIdTy);
2505 MemMoveFn.init(&CGM,
"objc_memmove_collectable", PtrTy, PtrTy, PtrTy,
2511 const std::string &Name,
bool isWeak) {
2512 llvm::Constant *ClassName = MakeConstantString(Name);
2524 llvm::FunctionType::get(IdTy, PtrToInt8Ty,
true),
"objc_lookup_class");
2534 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value))
2539llvm::Value *CGObjCGNU::EmitNSAutoreleasePoolClassRef(
CodeGenFunction &CGF) {
2540 auto *
Value = GetClassNamed(CGF,
"NSAutoreleasePool",
false);
2541 if (CGM.
getTriple().isOSBinFormatCOFF()) {
2542 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value)) {
2548 for (
const auto *Result : DC->
lookup(&II))
2549 if ((VD = dyn_cast<VarDecl>(Result)))
2559 const std::string &TypeEncoding) {
2561 llvm::GlobalAlias *SelValue =
nullptr;
2563 for (
const TypedSelector &
Type : Types) {
2564 if (
Type.first == TypeEncoding) {
2565 SelValue =
Type.second;
2570 SelValue = llvm::GlobalAlias::create(SelectorElemTy, 0,
2571 llvm::GlobalValue::PrivateLinkage,
2574 Types.emplace_back(TypeEncoding, SelValue);
2581 llvm::Value *SelValue = GetSelector(CGF, Sel);
2592 return GetTypedSelector(CGF, Sel, std::string());
2598 return GetTypedSelector(CGF,
Method->getSelector(), SelTypes);
2601llvm::Constant *CGObjCGNU::GetEHType(
QualType T) {
2608 return MakeConstantString(
"@id");
2616 assert(OPT &&
"Invalid @catch type.");
2618 assert(IDecl &&
"Invalid @catch type.");
2622llvm::Constant *CGObjCGNUstep::GetEHType(
QualType T) {
2623 if (usesSEHExceptions)
2626 if (!CGM.
getLangOpts().CPlusPlus && !usesCxxExceptions)
2627 return CGObjCGNU::GetEHType(
T);
2635 llvm::Constant *IDEHType =
2636 CGM.
getModule().getGlobalVariable(
"__objc_id_type_info");
2639 new llvm::GlobalVariable(CGM.
getModule(), PtrToInt8Ty,
2641 llvm::GlobalValue::ExternalLinkage,
2642 nullptr,
"__objc_id_type_info");
2648 assert(PT &&
"Invalid @catch type.");
2650 assert(IT &&
"Invalid @catch type.");
2651 std::string className =
2654 std::string typeinfoName =
"__objc_eh_typeinfo_" + className;
2657 if (llvm::Constant *typeinfo = TheModule.getGlobalVariable(typeinfoName))
2665 const char *vtableName =
"_ZTVN7gnustep7libobjc22__objc_class_type_infoE";
2666 auto *Vtable = TheModule.getGlobalVariable(vtableName);
2668 Vtable =
new llvm::GlobalVariable(TheModule, PtrToInt8Ty,
true,
2669 llvm::GlobalValue::ExternalLinkage,
2670 nullptr, vtableName);
2672 llvm::Constant *Two = llvm::ConstantInt::get(IntTy, 2);
2674 llvm::ConstantExpr::getGetElementPtr(Vtable->getValueType(), Vtable, Two);
2676 llvm::Constant *typeName =
2677 ExportUniqueString(className,
"__objc_eh_typename_");
2680 auto fields = builder.beginStruct();
2681 fields.add(BVtable);
2682 fields.add(typeName);
2683 llvm::Constant *TI =
2684 fields.finishAndCreateGlobal(
"__objc_eh_typeinfo_" + className,
2687 llvm::GlobalValue::LinkOnceODRLinkage);
2694 std::string Str = SL->
getString().str();
2698 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
2699 if (old != ObjCStrings.end())
2704 if (StringClass.empty()) StringClass =
"NSConstantString";
2706 std::string Sym =
"_OBJC_CLASS_";
2709 llvm::Constant *
isa = TheModule.getNamedGlobal(Sym);
2712 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
2713 llvm::GlobalValue::ExternalWeakLinkage,
2717 auto Fields = Builder.beginStruct();
2719 Fields.add(MakeConstantString(Str));
2720 Fields.addInt(IntTy, Str.size());
2722 ObjCStrings[Str] = ObjCStr;
2723 ConstantStrings.push_back(ObjCStr);
2736 bool isCategoryImpl,
2737 llvm::Value *Receiver,
2738 bool IsClassMessage,
2742 if (CGM.
getLangOpts().getGC() == LangOptions::GCOnly) {
2743 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2747 if (Sel == ReleaseSel) {
2752 llvm::Value *cmd = GetSelector(CGF, Sel);
2755 ActualArgs.
add(
RValue::get(EnforceType(Builder, Receiver, IdTy)), ASTIdTy);
2759 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2761 llvm::Value *ReceiverClass =
nullptr;
2764 ReceiverClass = GetClassNamed(CGF,
2765 Class->getSuperClass()->getNameAsString(),
false);
2766 if (IsClassMessage) {
2769 Builder.CreateAlignedLoad(IdTy, ReceiverClass, CGF.
getPointerAlign());
2771 ReceiverClass = EnforceType(Builder, ReceiverClass, IdTy);
2773 if (isCategoryImpl) {
2774 llvm::FunctionCallee classLookupFunction =
nullptr;
2775 if (IsClassMessage) {
2777 IdTy, PtrTy,
true),
"objc_get_meta_class");
2780 IdTy, PtrTy,
true),
"objc_get_class");
2782 ReceiverClass = Builder.CreateCall(classLookupFunction,
2783 MakeConstantString(
Class->getNameAsString()));
2790 if (IsClassMessage) {
2791 if (!MetaClassPtrAlias) {
2792 MetaClassPtrAlias = llvm::GlobalAlias::create(
2793 IdElemTy, 0, llvm::GlobalValue::InternalLinkage,
2794 ".objc_metaclass_ref" +
Class->getNameAsString(), &TheModule);
2796 ReceiverClass = MetaClassPtrAlias;
2798 if (!ClassPtrAlias) {
2799 ClassPtrAlias = llvm::GlobalAlias::create(
2800 IdElemTy, 0, llvm::GlobalValue::InternalLinkage,
2801 ".objc_class_ref" +
Class->getNameAsString(), &TheModule);
2803 ReceiverClass = ClassPtrAlias;
2807 llvm::Type *CastTy = llvm::StructType::get(IdTy, IdTy);
2809 ReceiverClass = Builder.CreateStructGEP(CastTy, ReceiverClass, 1);
2812 Builder.CreateAlignedLoad(IdTy, ReceiverClass, CGF.
getPointerAlign());
2815 llvm::StructType *ObjCSuperTy =
2816 llvm::StructType::get(Receiver->getType(), IdTy);
2821 Builder.CreateStore(Receiver, Builder.CreateStructGEP(ObjCSuper, 0));
2822 Builder.CreateStore(ReceiverClass, Builder.CreateStructGEP(ObjCSuper, 1));
2825 llvm::Value *imp = LookupIMPSuper(CGF, ObjCSuper, cmd, MSI);
2826 imp = EnforceType(Builder, imp, MSI.MessengerType);
2828 llvm::Metadata *impMD[] = {
2829 llvm::MDString::get(VMContext, Sel.
getAsString()),
2830 llvm::MDString::get(VMContext,
Class->getSuperClass()->getNameAsString()),
2831 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2832 llvm::Type::getInt1Ty(VMContext), IsClassMessage))};
2833 llvm::MDNode *
node = llvm::MDNode::get(VMContext, impMD);
2837 llvm::CallBase *call;
2838 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2839 call->setMetadata(msgSendMDKind, node);
2849 llvm::Value *Receiver,
2856 if (CGM.
getLangOpts().getGC() == LangOptions::GCOnly) {
2857 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2861 if (Sel == ReleaseSel) {
2872 cmd = GetSelector(CGF, Method);
2874 cmd = GetSelector(CGF, Sel);
2875 cmd = EnforceType(Builder, cmd, SelectorTy);
2878 Receiver = EnforceType(Builder, Receiver, IdTy);
2880 llvm::Metadata *impMD[] = {
2881 llvm::MDString::get(VMContext, Sel.
getAsString()),
2882 llvm::MDString::get(VMContext, Class ?
Class->getNameAsString() :
""),
2883 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2884 llvm::Type::getInt1Ty(VMContext), Class !=
nullptr))};
2885 llvm::MDNode *
node = llvm::MDNode::get(VMContext, impMD);
2893 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2914 bool hasParamDestroyedInCallee =
false;
2915 bool requiresExplicitZeroResult =
false;
2916 bool requiresNilReceiverCheck = [&] {
2918 if (!canMessageReceiverBeNull(CGF, Method,
false,
2923 if (Method &&
Method->hasParamDestroyedInCallee()) {
2924 hasParamDestroyedInCallee =
true;
2945 requiresExplicitZeroResult = !isDirect;
2949 return hasParamDestroyedInCallee || requiresExplicitZeroResult;
2955 bool requiresExplicitAggZeroing =
2959 llvm::BasicBlock *continueBB =
nullptr;
2961 llvm::BasicBlock *nilPathBB =
nullptr;
2963 llvm::BasicBlock *nilCleanupBB =
nullptr;
2966 if (requiresNilReceiverCheck) {
2973 if (requiresExplicitAggZeroing || hasParamDestroyedInCallee) {
2976 nilPathBB = Builder.GetInsertBlock();
2979 llvm::Value *isNil = Builder.CreateICmpEQ(Receiver,
2980 llvm::Constant::getNullValue(Receiver->getType()));
2981 Builder.CreateCondBr(isNil, nilCleanupBB ? nilCleanupBB : continueBB,
2991 imp = GenerateMethod(Method,
Method->getClassInterface());
2998 imp = LookupIMP(CGF, Receiver, cmd, node, MSI);
3002 StringRef
name =
"objc_msgSend";
3004 name =
"objc_msgSend_fpret";
3006 name =
"objc_msgSend_stret";
3010 bool shouldCheckForInReg =
3014 .isWindowsMSVCEnvironment() &&
3017 name =
"objc_msgSend_stret2";
3030 imp = EnforceType(Builder, imp, MSI.MessengerType);
3032 llvm::CallBase *call;
3034 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
3036 call->setMetadata(msgSendMDKind, node);
3038 if (requiresNilReceiverCheck) {
3039 llvm::BasicBlock *nonNilPathBB = CGF.
Builder.GetInsertBlock();
3040 CGF.
Builder.CreateBr(continueBB);
3046 if (hasParamDestroyedInCallee) {
3047 destroyCalleeDestroyedArguments(CGF, Method, CallArgs);
3050 if (requiresExplicitAggZeroing) {
3056 nilPathBB = CGF.
Builder.GetInsertBlock();
3057 CGF.
Builder.CreateBr(continueBB);
3065 llvm::PHINode *phi = Builder.CreatePHI(v->getType(), 2);
3066 phi->addIncoming(v, nonNilPathBB);
3073 std::pair<llvm::Value*,llvm::Value*> v = msgRet.
getComplexVal();
3074 llvm::PHINode *phi = Builder.CreatePHI(v.first->getType(), 2);
3075 phi->addIncoming(v.first, nonNilPathBB);
3076 phi->addIncoming(llvm::Constant::getNullValue(v.first->getType()),
3078 llvm::PHINode *phi2 = Builder.CreatePHI(v.second->getType(), 2);
3079 phi2->addIncoming(v.second, nonNilPathBB);
3080 phi2->addIncoming(llvm::Constant::getNullValue(v.second->getType()),
3090llvm::Constant *CGObjCGNU::
3091GenerateMethodList(StringRef ClassName,
3092 StringRef CategoryName,
3094 bool isClassMethodList) {
3095 if (Methods.empty())
3100 auto MethodList = Builder.beginStruct();
3101 MethodList.addNullPointer(CGM.
Int8PtrTy);
3102 MethodList.addInt(Int32Ty, Methods.size());
3105 llvm::StructType *ObjCMethodTy =
3114 const llvm::DataLayout &DL = TheModule.getDataLayout();
3115 MethodList.addInt(SizeTy, DL.getTypeSizeInBits(ObjCMethodTy) /
3131 auto MethodArray = MethodList.beginArray();
3133 for (
const auto *OMD : Methods) {
3134 llvm::Constant *FnPtr =
3135 TheModule.getFunction(getSymbolNameForMethod(OMD));
3136 assert(FnPtr &&
"Can't generate metadata for method that doesn't exist");
3137 auto Method = MethodArray.beginStruct(ObjCMethodTy);
3148 Method.finishAndAddTo(MethodArray);
3150 MethodArray.finishAndAddTo(MethodList);
3153 return MethodList.finishAndCreateGlobal(
".objc_method_list",
3158llvm::Constant *CGObjCGNU::
3164 if (IvarNames.empty())
3170 auto IvarList = Builder.beginStruct();
3171 IvarList.addInt(IntTy, (
int)IvarNames.size());
3174 llvm::StructType *ObjCIvarTy =
3175 llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, IntTy);
3178 auto Ivars = IvarList.beginArray(ObjCIvarTy);
3179 for (
unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {
3180 auto Ivar = Ivars.beginStruct(ObjCIvarTy);
3181 Ivar.
add(IvarNames[i]);
3182 Ivar.
add(IvarTypes[i]);
3183 Ivar.
add(IvarOffsets[i]);
3184 Ivar.finishAndAddTo(Ivars);
3186 Ivars.finishAndAddTo(IvarList);
3189 return IvarList.finishAndCreateGlobal(
".objc_ivar_list",
3194llvm::Constant *CGObjCGNU::GenerateClassStructure(
3195 llvm::Constant *MetaClass,
3196 llvm::Constant *SuperClass,
3199 llvm::Constant *Version,
3200 llvm::Constant *InstanceSize,
3201 llvm::Constant *IVars,
3202 llvm::Constant *Methods,
3203 llvm::Constant *Protocols,
3204 llvm::Constant *IvarOffsets,
3205 llvm::Constant *Properties,
3206 llvm::Constant *StrongIvarBitmap,
3207 llvm::Constant *WeakIvarBitmap,
3216 llvm::StructType *ClassTy = llvm::StructType::get(
3233 IvarOffsets->getType(),
3234 Properties->getType(),
3240 auto Elements = Builder.beginStruct(ClassTy);
3245 Elements.add(MetaClass);
3247 Elements.add(SuperClass);
3249 Elements.add(MakeConstantString(Name,
".class_name"));
3251 Elements.addInt(LongTy, 0);
3253 Elements.addInt(LongTy, info);
3256 const llvm::DataLayout &DL = TheModule.getDataLayout();
3257 Elements.addInt(LongTy, DL.getTypeSizeInBits(ClassTy) /
3260 Elements.add(InstanceSize);
3262 Elements.add(IVars);
3264 Elements.add(Methods);
3267 Elements.add(NULLPtr);
3269 Elements.add(NULLPtr);
3271 Elements.add(NULLPtr);
3273 Elements.add(Protocols);
3275 Elements.add(NULLPtr);
3277 Elements.addInt(LongTy, ClassABIVersion);
3279 Elements.add(IvarOffsets);
3281 Elements.add(Properties);
3283 Elements.add(StrongIvarBitmap);
3285 Elements.add(WeakIvarBitmap);
3290 std::string ClassSym((isMeta ?
"_OBJC_METACLASS_":
"_OBJC_CLASS_") +
3292 llvm::GlobalVariable *ClassRef = TheModule.getNamedGlobal(ClassSym);
3293 llvm::Constant *
Class =
3294 Elements.finishAndCreateGlobal(ClassSym, CGM.
getPointerAlign(),
false,
3295 llvm::GlobalValue::ExternalLinkage);
3297 ClassRef->replaceAllUsesWith(Class);
3298 ClassRef->removeFromParent();
3299 Class->setName(ClassSym);
3304llvm::Constant *CGObjCGNU::
3307 llvm::StructType *ObjCMethodDescTy =
3308 llvm::StructType::get(CGM.
getLLVMContext(), { PtrToInt8Ty, PtrToInt8Ty });
3311 auto MethodList = Builder.beginStruct();
3312 MethodList.addInt(IntTy, Methods.size());
3313 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
3314 for (
auto *M : Methods) {
3315 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
3316 Method.add(MakeConstantString(M->getSelector().getAsString()));
3318 Method.finishAndAddTo(MethodArray);
3320 MethodArray.finishAndAddTo(MethodList);
3321 return MethodList.finishAndCreateGlobal(
".objc_method_list",
3330 auto ProtocolList = Builder.beginStruct();
3331 ProtocolList.add(NULLPtr);
3332 ProtocolList.addInt(LongTy, Protocols.size());
3334 auto Elements = ProtocolList.beginArray(PtrToInt8Ty);
3335 for (
const std::string &Protocol : Protocols) {
3336 llvm::Constant *protocol =
nullptr;
3337 llvm::StringMap<llvm::Constant *>::iterator value =
3338 ExistingProtocols.find(Protocol);
3339 if (value == ExistingProtocols.end()) {
3340 protocol = GenerateEmptyProtocol(Protocol);
3342 protocol = value->getValue();
3344 Elements.add(protocol);
3346 Elements.finishAndAddTo(ProtocolList);
3347 return ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
3353 return GenerateProtocolRef(PD);
3356llvm::Constant *CGObjCGNU::GenerateProtocolRef(
const ObjCProtocolDecl *PD) {
3359 GenerateProtocol(PD);
3360 assert(protocol &&
"Unknown protocol");
3365CGObjCGNU::GenerateEmptyProtocol(StringRef ProtocolName) {
3366 llvm::Constant *ProtocolList = GenerateProtocolList({});
3367 llvm::Constant *MethodList = GenerateProtocolMethodList({});
3371 auto Elements = Builder.beginStruct();
3375 Elements.add(llvm::ConstantExpr::getIntToPtr(
3376 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3378 Elements.add(MakeConstantString(ProtocolName,
".objc_protocol_name"));
3379 Elements.add(ProtocolList);
3380 Elements.add(MethodList);
3381 Elements.add(MethodList);
3382 Elements.add(MethodList);
3383 Elements.add(MethodList);
3384 Elements.add(NULLPtr);
3385 Elements.add(NULLPtr);
3386 return Elements.finishAndCreateGlobal(SymbolForProtocol(ProtocolName),
3402 Protocols.push_back(PI->getNameAsString());
3406 if (I->isOptional())
3407 OptionalInstanceMethods.push_back(I);
3409 InstanceMethods.push_back(I);
3414 if (I->isOptional())
3415 OptionalClassMethods.push_back(I);
3417 ClassMethods.push_back(I);
3419 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
3420 llvm::Constant *InstanceMethodList =
3421 GenerateProtocolMethodList(InstanceMethods);
3422 llvm::Constant *ClassMethodList =
3423 GenerateProtocolMethodList(ClassMethods);
3424 llvm::Constant *OptionalInstanceMethodList =
3425 GenerateProtocolMethodList(OptionalInstanceMethods);
3426 llvm::Constant *OptionalClassMethodList =
3427 GenerateProtocolMethodList(OptionalClassMethods);
3435 llvm::Constant *PropertyList =
3436 GeneratePropertyList(
nullptr, PD,
false,
false);
3437 llvm::Constant *OptionalPropertyList =
3438 GeneratePropertyList(
nullptr, PD,
false,
true);
3445 auto Elements = Builder.beginStruct();
3447 llvm::ConstantExpr::getIntToPtr(
3448 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3449 Elements.add(MakeConstantString(ProtocolName));
3450 Elements.add(ProtocolList);
3451 Elements.add(InstanceMethodList);
3452 Elements.add(ClassMethodList);
3453 Elements.add(OptionalInstanceMethodList);
3454 Elements.add(OptionalClassMethodList);
3455 Elements.add(PropertyList);
3456 Elements.add(OptionalPropertyList);
3457 ExistingProtocols[ProtocolName] =
3458 Elements.finishAndCreateGlobal(
".objc_protocol", CGM.
getPointerAlign());
3460void CGObjCGNU::GenerateProtocolHolderCategory() {
3464 auto Elements = Builder.beginStruct();
3466 const std::string ClassName =
"__ObjC_Protocol_Holder_Ugly_Hack";
3467 const std::string CategoryName =
"AnotherHack";
3468 Elements.add(MakeConstantString(CategoryName));
3469 Elements.add(MakeConstantString(ClassName));
3471 Elements.add(GenerateMethodList(ClassName, CategoryName, {},
false));
3473 Elements.add(GenerateMethodList(ClassName, CategoryName, {},
true));
3477 auto ProtocolList = ProtocolListBuilder.beginStruct();
3478 ProtocolList.add(NULLPtr);
3479 ProtocolList.addInt(LongTy, ExistingProtocols.size());
3480 auto ProtocolElements = ProtocolList.beginArray(PtrTy);
3481 for (
auto iter = ExistingProtocols.begin(), endIter = ExistingProtocols.end();
3482 iter != endIter ; iter++) {
3483 ProtocolElements.add(iter->getValue());
3485 ProtocolElements.finishAndAddTo(ProtocolList);
3486 Elements.add(ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
3488 Categories.push_back(
3504 int bitCount = bits.size();
3506 if (bitCount < ptrBits) {
3508 for (
int i=0 ; i<bitCount ; ++i) {
3509 if (bits[i]) val |= 1ULL<<(i+1);
3511 return llvm::ConstantInt::get(IntPtrTy, val);
3515 while (v < bitCount) {
3517 for (
int i=0 ; (i<32) && (v<bitCount) ; ++i) {
3518 if (bits[v]) word |= 1<<i;
3521 values.push_back(llvm::ConstantInt::get(Int32Ty, word));
3525 auto fields = builder.beginStruct();
3526 fields.addInt(Int32Ty, values.size());
3527 auto array = fields.beginArray();
3528 for (
auto *v : values) array.add(v);
3529 array.finishAndAddTo(fields);
3531 llvm::Constant *GS =
3533 llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy);
3537llvm::Constant *CGObjCGNU::GenerateCategoryProtocolList(
const
3540 const auto RuntimeProtos =
3541 GetRuntimeProtocolList(RefPro.begin(), RefPro.end());
3543 for (
const auto *PD : RuntimeProtos)
3545 return GenerateProtocolList(Protocols);
3550 std::string ClassName =
Class->getNameAsString();
3557 auto Elements = Builder.beginStruct();
3558 Elements.add(MakeConstantString(CategoryName));
3559 Elements.add(MakeConstantString(ClassName));
3562 InstanceMethods.insert(InstanceMethods.begin(), OCD->
instmeth_begin(),
3565 GenerateMethodList(ClassName, CategoryName, InstanceMethods,
false));
3572 Elements.add(GenerateMethodList(ClassName, CategoryName, ClassMethods,
true));
3575 Elements.add(GenerateCategoryProtocolList(CatDecl));
3581 Elements.add(GeneratePropertyList(OCD,
Category,
false));
3583 Elements.add(GeneratePropertyList(OCD,
Category,
true));
3585 Elements.addNullPointer(PtrTy);
3586 Elements.addNullPointer(PtrTy);
3590 Categories.push_back(Elements.finishAndCreateGlobal(
3591 std::string(
".objc_category_") + ClassName + CategoryName,
3595llvm::Constant *CGObjCGNU::GeneratePropertyList(
const Decl *Container,
3597 bool isClassProperty,
3598 bool protocolOptionalProperties) {
3602 bool isProtocol = isa<ObjCProtocolDecl>(OCD);
3607 for (
const auto *
P : Proto->protocols())
3608 collectProtocolProperties(
P);
3609 for (
const auto *PD : Proto->properties()) {
3610 if (isClassProperty != PD->isClassProperty())
3618 Properties.push_back(PD);
3624 for (
auto *PD : ClassExt->properties()) {
3625 if (isClassProperty != PD->isClassProperty())
3628 Properties.push_back(PD);
3632 if (isClassProperty != PD->isClassProperty())
3636 if (isProtocol && (protocolOptionalProperties != PD->isOptional()))
3643 Properties.push_back(PD);
3648 collectProtocolProperties(
P);
3650 for (
const auto *
P : CD->protocols())
3651 collectProtocolProperties(
P);
3653 auto numProperties = Properties.size();
3655 if (numProperties == 0)
3659 auto propertyList = builder.beginStruct();
3660 auto properties = PushPropertyListHeader(propertyList, numProperties);
3664 for (
auto *property : Properties) {
3665 bool isSynthesized =
false;
3666 bool isDynamic =
false;
3670 isSynthesized = (propertyImpl->getPropertyImplementation() ==
3672 isDynamic = (propertyImpl->getPropertyImplementation() ==
3676 PushProperty(properties, property, Container, isSynthesized, isDynamic);
3678 properties.finishAndAddTo(propertyList);
3680 return propertyList.finishAndCreateGlobal(
".objc_property_list",
3698 std::string SuperClassName;
3699 if (SuperClassDecl) {
3701 EmitClassRef(SuperClassName);
3711 std::string classSymbolName =
"__objc_class_name_" + ClassName;
3712 if (
auto *symbol = TheModule.getGlobalVariable(classSymbolName)) {
3713 symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0));
3715 new llvm::GlobalVariable(TheModule, LongTy,
false,
3716 llvm::GlobalValue::ExternalLinkage,
3717 llvm::ConstantInt::get(LongTy, 0),
3734 auto IvarOffsetValues = IvarOffsetBuilder.beginArray(PtrToIntTy);
3738 int superInstanceSize = !SuperClassDecl ? 0 :
3743 instanceSize = 0 - (instanceSize - superInstanceSize);
3749 IvarNames.push_back(MakeConstantString(IVD->getNameAsString()));
3751 std::string TypeStr;
3753 IvarTypes.push_back(MakeConstantString(TypeStr));
3754 IvarAligns.push_back(llvm::ConstantInt::get(IntTy,
3757 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
3760 Offset = BaseOffset - superInstanceSize;
3762 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
3764 std::string OffsetName =
"__objc_ivar_offset_value_" + ClassName +
"." +
3765 IVD->getNameAsString();
3767 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
3769 OffsetVar->setInitializer(OffsetValue);
3773 OffsetVar->setLinkage(llvm::GlobalValue::ExternalLinkage);
3775 OffsetVar =
new llvm::GlobalVariable(TheModule, Int32Ty,
3776 false, llvm::GlobalValue::ExternalLinkage,
3777 OffsetValue, OffsetName);
3778 IvarOffsets.push_back(OffsetValue);
3779 IvarOffsetValues.add(OffsetVar);
3781 IvarOwnership.push_back(lt);
3784 StrongIvars.push_back(
true);
3785 WeakIvars.push_back(
false);
3788 StrongIvars.push_back(
false);
3789 WeakIvars.push_back(
true);
3792 StrongIvars.push_back(
false);
3793 WeakIvars.push_back(
false);
3796 llvm::Constant *StrongIvarBitmap = MakeBitField(StrongIvars);
3797 llvm::Constant *WeakIvarBitmap = MakeBitField(WeakIvars);
3798 llvm::GlobalVariable *IvarOffsetArray =
3799 IvarOffsetValues.finishAndCreateGlobal(
".ivar.offsets",
3804 InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
3811 llvm::Constant *Properties = GeneratePropertyList(OID, ClassDecl);
3814 auto RefProtocols = ClassDecl->
protocols();
3815 auto RuntimeProtocols =
3816 GetRuntimeProtocolList(RefProtocols.begin(), RefProtocols.end());
3818 for (
const auto *I : RuntimeProtocols)
3819 Protocols.push_back(I->getNameAsString());
3822 llvm::Constant *SuperClass;
3823 if (!SuperClassName.empty()) {
3824 SuperClass = MakeConstantString(SuperClassName,
".super_class_name");
3826 SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty);
3829 llvm::Constant *MethodList = GenerateMethodList(ClassName,
"",
3830 InstanceMethods,
false);
3831 llvm::Constant *ClassMethodList = GenerateMethodList(ClassName,
"",
3832 ClassMethods,
true);
3833 llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
3834 IvarOffsets, IvarAligns, IvarOwnership);
3845 llvm::Type *IndexTy = Int32Ty;
3846 llvm::Constant *offsetPointerIndexes[] = {Zeros[0],
3847 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 2 : 1),
nullptr,
3848 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 3 : 2) };
3850 unsigned ivarIndex = 0;
3853 const std::string Name = GetIVarOffsetVariableName(ClassDecl, IVD);
3854 offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, ivarIndex);
3856 llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr(
3857 cast<llvm::GlobalVariable>(IvarList)->getValueType(), IvarList,
3858 offsetPointerIndexes);
3860 llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name);
3862 offset->setInitializer(offsetValue);
3866 offset->setLinkage(llvm::GlobalValue::ExternalLinkage);
3869 new llvm::GlobalVariable(TheModule, offsetValue->getType(),
3870 false, llvm::GlobalValue::ExternalLinkage, offsetValue, Name);
3873 llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0);
3876 llvm::Constant *MetaClassStruct = GenerateClassStructure(
3877 NULLPtr, NULLPtr, 0x12L, ClassName.c_str(),
nullptr, Zeros[0],
3878 NULLPtr, ClassMethodList, NULLPtr, NULLPtr,
3879 GeneratePropertyList(OID, ClassDecl,
true), ZeroPtr, ZeroPtr,
true);
3884 llvm::Constant *ClassStruct = GenerateClassStructure(
3885 MetaClassStruct, SuperClass, 0x11L, ClassName.c_str(),
nullptr,
3886 llvm::ConstantInt::get(LongTy, instanceSize), IvarList, MethodList,
3887 GenerateProtocolList(Protocols), IvarOffsetArray, Properties,
3888 StrongIvarBitmap, WeakIvarBitmap);
3893 if (ClassPtrAlias) {
3894 ClassPtrAlias->replaceAllUsesWith(ClassStruct);
3895 ClassPtrAlias->eraseFromParent();
3896 ClassPtrAlias =
nullptr;
3898 if (MetaClassPtrAlias) {
3899 MetaClassPtrAlias->replaceAllUsesWith(MetaClassStruct);
3900 MetaClassPtrAlias->eraseFromParent();
3901 MetaClassPtrAlias =
nullptr;
3905 Classes.push_back(ClassStruct);
3908llvm::Function *CGObjCGNU::ModuleInitFunction() {
3910 if (Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
3915 GenerateProtocolHolderCategory();
3917 llvm::StructType *selStructTy = dyn_cast<llvm::StructType>(SelectorElemTy);
3920 { PtrToInt8Ty, PtrToInt8Ty });
3924 llvm::Constant *statics = NULLPtr;
3925 if (!ConstantStrings.empty()) {
3926 llvm::GlobalVariable *fileStatics = [&] {
3928 auto staticsStruct = builder.beginStruct();
3931 if (stringClass.empty()) stringClass =
"NXConstantString";
3932 staticsStruct.add(MakeConstantString(stringClass,
3933 ".objc_static_class_name"));
3935 auto array = staticsStruct.beginArray();
3936 array.addAll(ConstantStrings);
3938 array.finishAndAddTo(staticsStruct);
3940 return staticsStruct.finishAndCreateGlobal(
".objc_statics",
3945 auto allStaticsArray = builder.beginArray(fileStatics->getType());
3946 allStaticsArray.add(fileStatics);
3947 allStaticsArray.addNullPointer(fileStatics->getType());
3949 statics = allStaticsArray.finishAndCreateGlobal(
".objc_statics_ptr",
3956 unsigned selectorCount;
3959 llvm::GlobalVariable *selectorList = [&] {
3961 auto selectors = builder.beginArray(selStructTy);
3963 std::vector<Selector> allSelectors;
3964 for (
auto &entry : table)
3965 allSelectors.push_back(entry.first);
3966 llvm::sort(allSelectors);
3968 for (
auto &untypedSel : allSelectors) {
3969 std::string selNameStr = untypedSel.getAsString();
3970 llvm::Constant *selName = ExportUniqueString(selNameStr,
".objc_sel_name");
3972 for (TypedSelector &sel : table[untypedSel]) {
3973 llvm::Constant *selectorTypeEncoding = NULLPtr;
3974 if (!sel.first.empty())
3975 selectorTypeEncoding =
3976 MakeConstantString(sel.first,
".objc_sel_types");
3978 auto selStruct = selectors.beginStruct(selStructTy);
3979 selStruct.add(selName);
3980 selStruct.add(selectorTypeEncoding);
3981 selStruct.finishAndAddTo(selectors);
3984 selectorAliases.push_back(sel.second);
3989 selectorCount = selectors.size();
3995 auto selStruct = selectors.beginStruct(selStructTy);
3996 selStruct.add(NULLPtr);
3997 selStruct.add(NULLPtr);
3998 selStruct.finishAndAddTo(selectors);
4000 return selectors.finishAndCreateGlobal(
".objc_selector_list",
4005 for (
unsigned i = 0; i < selectorCount; ++i) {
4006 llvm::Constant *idxs[] = {
4008 llvm::ConstantInt::get(Int32Ty, i)
4011 llvm::Constant *selPtr = llvm::ConstantExpr::getGetElementPtr(
4012 selectorList->getValueType(), selectorList, idxs);
4013 selectorAliases[i]->replaceAllUsesWith(selPtr);
4014 selectorAliases[i]->eraseFromParent();
4017 llvm::GlobalVariable *symtab = [&] {
4019 auto symtab = builder.beginStruct();
4022 symtab.addInt(LongTy, selectorCount);
4024 symtab.add(selectorList);
4027 symtab.addInt(CGM.
Int16Ty, Classes.size());
4029 symtab.addInt(CGM.
Int16Ty, Categories.size());
4032 auto classList = symtab.beginArray(PtrToInt8Ty);
4033 classList.addAll(Classes);
4034 classList.addAll(Categories);
4036 classList.add(statics);
4037 classList.add(NULLPtr);
4038 classList.finishAndAddTo(symtab);
4046 llvm::Constant *module = [&] {
4047 llvm::Type *moduleEltTys[] = {
4048 LongTy, LongTy, PtrToInt8Ty, symtab->getType(), IntTy
4050 llvm::StructType *moduleTy = llvm::StructType::get(
4052 ArrayRef(moduleEltTys).drop_back(
unsigned(RuntimeVersion < 10)));
4055 auto module = builder.beginStruct(moduleTy);
4057 module.addInt(LongTy, RuntimeVersion);
4059 module.addInt(LongTy, CGM.
getDataLayout().getTypeStoreSize(moduleTy));
4066 module.add(MakeConstantString(path,
".objc_source_file_name"));
4069 if (RuntimeVersion >= 10) {
4071 case LangOptions::GCOnly:
4072 module.addInt(IntTy, 2);
4074 case LangOptions::NonGC:
4076 module.addInt(IntTy, 1);
4078 module.addInt(IntTy, 0);
4080 case LangOptions::HybridGC:
4081 module.addInt(IntTy, 1);
4091 llvm::Function * LoadFunction = llvm::Function::Create(
4092 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
4093 llvm::GlobalValue::InternalLinkage,
".objc_load_function",
4095 llvm::BasicBlock *EntryBB =
4096 llvm::BasicBlock::Create(VMContext,
"entry", LoadFunction);
4098 Builder.SetInsertPoint(EntryBB);
4100 llvm::FunctionType *FT =
4101 llvm::FunctionType::get(Builder.getVoidTy(), module->getType(),
true);
4102 llvm::FunctionCallee Register =
4104 Builder.CreateCall(Register, module);
4106 if (!ClassAliases.empty()) {
4107 llvm::Type *ArgTypes[2] = {PtrTy, PtrToInt8Ty};
4108 llvm::FunctionType *RegisterAliasTy =
4109 llvm::FunctionType::get(Builder.getVoidTy(),
4111 llvm::Function *RegisterAlias = llvm::Function::Create(
4113 llvm::GlobalValue::ExternalWeakLinkage,
"class_registerAlias_np",
4115 llvm::BasicBlock *AliasBB =
4116 llvm::BasicBlock::Create(VMContext,
"alias", LoadFunction);
4117 llvm::BasicBlock *NoAliasBB =
4118 llvm::BasicBlock::Create(VMContext,
"no_alias", LoadFunction);
4121 llvm::Value *HasRegisterAlias = Builder.CreateICmpNE(RegisterAlias,
4122 llvm::Constant::getNullValue(RegisterAlias->getType()));
4123 Builder.CreateCondBr(HasRegisterAlias, AliasBB, NoAliasBB);
4126 Builder.SetInsertPoint(AliasBB);
4128 for (std::vector<ClassAliasPair>::iterator iter = ClassAliases.begin();
4129 iter != ClassAliases.end(); ++iter) {
4130 llvm::Constant *TheClass =
4131 TheModule.getGlobalVariable(
"_OBJC_CLASS_" + iter->first,
true);
4133 Builder.CreateCall(RegisterAlias,
4134 {TheClass, MakeConstantString(iter->second)});
4138 Builder.CreateBr(NoAliasBB);
4141 Builder.SetInsertPoint(NoAliasBB);
4143 Builder.CreateRetVoid();
4145 return LoadFunction;
4148llvm::Function *CGObjCGNU::GenerateMethod(
const ObjCMethodDecl *OMD,
4151 llvm::FunctionType *MethodTy =
4152 Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
4155 std::string FunctionName =
4156 getSymbolNameForMethod(OMD, !isDirect);
4159 return llvm::Function::Create(MethodTy,
4160 llvm::GlobalVariable::InternalLinkage,
4161 FunctionName, &TheModule);
4164 auto I = DirectMethodDefinitions.find(COMD);
4165 llvm::Function *OldFn =
nullptr, *
Fn =
nullptr;
4167 if (I == DirectMethodDefinitions.end()) {
4169 llvm::Function::Create(MethodTy, llvm::GlobalVariable::ExternalLinkage,
4170 FunctionName, &TheModule);
4171 DirectMethodDefinitions.insert(std::make_pair(COMD, F));
4188 Fn = llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,
"",
4190 Fn->takeName(OldFn);
4191 OldFn->replaceAllUsesWith(Fn);
4192 OldFn->eraseFromParent();
4206llvm::FunctionCallee CGObjCGNU::GetPropertyGetFunction() {
4207 return GetPropertyFn;
4210llvm::FunctionCallee CGObjCGNU::GetPropertySetFunction() {
4211 return SetPropertyFn;
4214llvm::FunctionCallee CGObjCGNU::GetOptimizedPropertySetFunction(
bool atomic,
4219llvm::FunctionCallee CGObjCGNU::GetGetStructFunction() {
4220 return GetStructPropertyFn;
4223llvm::FunctionCallee CGObjCGNU::GetSetStructFunction() {
4224 return SetStructPropertyFn;
4227llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectGetFunction() {
4231llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectSetFunction() {
4235llvm::FunctionCallee CGObjCGNU::EnumerationMutationFunction() {
4236 return EnumerationMutationFn;
4241 EmitAtSynchronizedStmt(CGF, S, SyncEnterFn, SyncExitFn);
4258 EmitTryCatchStmt(CGF, S, EnterCatchFn, ExitCatchFn, ExceptionReThrowFn);
4263 bool ClearInsertionPoint) {
4264 llvm::Value *ExceptionAsObject;
4265 bool isRethrow =
false;
4267 if (
const Expr *ThrowExpr = S.getThrowExpr()) {
4269 ExceptionAsObject = Exception;
4272 "Unexpected rethrow outside @catch block.");
4276 if (isRethrow && (usesSEHExceptions || usesCxxExceptions)) {
4285 Throw->setDoesNotReturn();
4287 ExceptionAsObject = CGF.
Builder.CreateBitCast(ExceptionAsObject, IdTy);
4288 llvm::CallBase *Throw =
4290 Throw->setDoesNotReturn();
4292 CGF.
Builder.CreateUnreachable();
4293 if (ClearInsertionPoint)
4294 CGF.
Builder.ClearInsertionPoint();
4300 return B.CreateCall(
4301 WeakReadFn, EnforceType(B, AddrWeakObj.
emitRawPointer(CGF), PtrToIdTy));
4305 llvm::Value *src,
Address dst) {
4307 src = EnforceType(B, src, IdTy);
4308 llvm::Value *dstVal = EnforceType(B,
dst.emitRawPointer(CGF), PtrToIdTy);
4309 B.CreateCall(WeakAssignFn, {src, dstVal});
4313 llvm::Value *src,
Address dst,
4316 src = EnforceType(B, src, IdTy);
4317 llvm::Value *dstVal = EnforceType(B,
dst.emitRawPointer(CGF), PtrToIdTy);
4319 assert(!threadlocal &&
"EmitObjCGlobalAssign - Threal Local API NYI");
4320 B.CreateCall(GlobalAssignFn, {src, dstVal});
4324 llvm::Value *src,
Address dst,
4325 llvm::Value *ivarOffset) {
4327 src = EnforceType(B, src, IdTy);
4328 llvm::Value *dstVal = EnforceType(B,
dst.emitRawPointer(CGF), IdTy);
4329 B.CreateCall(IvarAssignFn, {src, dstVal, ivarOffset});
4333 llvm::Value *src,
Address dst) {
4335 src = EnforceType(B, src, IdTy);
4336 llvm::Value *dstVal = EnforceType(B,
dst.emitRawPointer(CGF), PtrToIdTy);
4337 B.CreateCall(StrongCastAssignFn, {src, dstVal});
4343 llvm::Value *Size) {
4345 llvm::Value *DestPtrVal = EnforceType(B, DestPtr.
emitRawPointer(CGF), PtrTy);
4346 llvm::Value *SrcPtrVal = EnforceType(B, SrcPtr.
emitRawPointer(CGF), PtrTy);
4348 B.CreateCall(MemMoveFn, {DestPtrVal, SrcPtrVal,
Size});
4351llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
4354 const std::string Name = GetIVarOffsetVariableName(ID, Ivar);
4358 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
4359 if (!IvarOffsetPointer)
4360 IvarOffsetPointer =
new llvm::GlobalVariable(
4361 TheModule, llvm::PointerType::getUnqual(VMContext),
false,
4362 llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
4363 return IvarOffsetPointer;
4368 llvm::Value *BaseValue,
4370 unsigned CVRQualifiers) {
4373 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
4374 EmitIvarOffset(CGF, ID, Ivar));
4402 if (RuntimeVersion < 10 ||
4404 return CGF.
Builder.CreateZExtOrBitCast(
4408 llvm::PointerType::getUnqual(VMContext),
4409 ObjCIvarOffsetVariable(
Interface, Ivar),
4413 std::string
name =
"__objc_ivar_offset_value_" +
4416 llvm::Value *Offset = TheModule.getGlobalVariable(name);
4418 auto GV =
new llvm::GlobalVariable(TheModule, IntTy,
4419 false, llvm::GlobalValue::LinkOnceAnyLinkage,
4420 llvm::Constant::getNullValue(IntTy), name);
4425 if (Offset->getType() != PtrDiffTy)
4426 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
4430 return llvm::ConstantInt::get(PtrDiffTy, Offset,
true);
4436 switch (Runtime.getKind()) {
4438 if (Runtime.getVersion() >= VersionTuple(2, 0))
4439 return new CGObjCGNUstep2(CGM);
4440 return new CGObjCGNUstep(CGM);
4443 return new CGObjCGCC(CGM);
4446 return new CGObjCObjFW(CGM);
4452 llvm_unreachable(
"these runtimes are not GNU runtimes");
4454 llvm_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 & getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const
Get or compute information about the layout of the specified Objective-C interface.
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.
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...
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
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::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
llvm::Value * EmitObjCThrowOperand(const Expr *expr)
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
JumpDest ReturnBlock
ReturnBlock - Unified return block.
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...
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,...
llvm::Value * LoadObjCSelf()
LoadObjCSelf - Load the value of self.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
SmallVector< llvm::Value *, 8 > ObjCEHValueStack
ObjCEHValueStack - Stack of Objective-C exception values, used for rethrows.
void EmitVarDecl(const VarDecl &D)
EmitVarDecl - Emit a local variable declaration.
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()
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
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_iterator all_referenced_protocol_end() const
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
all_protocol_iterator all_referenced_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
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
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)
The base class of the type hierarchy.
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.
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.
const half4 dst(half4 Src0, half4 Src1)
int const char * function
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