32#include "llvm/ADT/SmallVector.h"
33#include "llvm/ADT/StringMap.h"
34#include "llvm/IR/DataLayout.h"
35#include "llvm/IR/Intrinsics.h"
36#include "llvm/IR/LLVMContext.h"
37#include "llvm/IR/Module.h"
38#include "llvm/Support/Compiler.h"
39#include "llvm/Support/ConvertUTF.h"
43using namespace CodeGen;
50class LazyRuntimeFunction {
52 llvm::FunctionType *FTy =
nullptr;
53 const char *FunctionName =
nullptr;
54 llvm::FunctionCallee
Function =
nullptr;
57 LazyRuntimeFunction() =
default;
61 template <
typename... Tys>
62 void init(
CodeGenModule *Mod,
const char *name, llvm::Type *RetTy,
69 FTy = llvm::FunctionType::get(RetTy, ArgTys,
false);
72 FTy = llvm::FunctionType::get(RetTy, std::nullopt,
false);
76 llvm::FunctionType *getType() {
return FTy; }
80 operator llvm::FunctionCallee() {
97 llvm::Module &TheModule;
100 llvm::StructType *ObjCSuperTy;
103 llvm::PointerType *PtrToObjCSuperTy;
107 llvm::PointerType *SelectorTy;
109 llvm::Type *SelectorElemTy;
112 llvm::IntegerType *Int8Ty;
115 llvm::PointerType *PtrToInt8Ty;
117 llvm::StructType *ProtocolTy;
119 llvm::PointerType *ProtocolPtrTy;
125 llvm::PointerType *IMPTy;
130 llvm::PointerType *IdTy;
132 llvm::Type *IdElemTy;
135 llvm::PointerType *PtrToIdTy;
140 llvm::IntegerType *IntTy;
144 llvm::PointerType *PtrTy;
148 llvm::IntegerType *LongTy;
150 llvm::IntegerType *SizeTy;
152 llvm::IntegerType *IntPtrTy;
154 llvm::IntegerType *PtrDiffTy;
157 llvm::PointerType *PtrToIntTy;
161 llvm::IntegerType *Int32Ty;
163 llvm::IntegerType *Int64Ty;
165 llvm::StructType *PropertyMetadataTy;
169 unsigned msgSendMDKind;
172 bool usesSEHExceptions;
174 bool usesCxxExceptions;
179 return (R.
getKind() == kind) &&
180 (R.
getVersion() >= VersionTuple(major, minor));
183 std::string ManglePublicSymbol(StringRef Name) {
184 return (StringRef(CGM.
getTriple().isOSBinFormatCOFF() ?
"$_" :
"._") + Name).str();
187 std::string SymbolForProtocol(Twine Name) {
188 return (ManglePublicSymbol(
"OBJC_PROTOCOL_") + Name).str();
191 std::string SymbolForProtocolRef(StringRef Name) {
192 return (ManglePublicSymbol(
"OBJC_REF_PROTOCOL_") + Name).str();
199 llvm::Constant *MakeConstantString(StringRef Str,
const char *Name =
"") {
202 return llvm::ConstantExpr::getGetElementPtr(Array.getElementType(),
203 Array.getPointer(), Zeros);
210 llvm::Constant *ExportUniqueString(
const std::string &Str,
211 const std::string &prefix,
212 bool Private=
false) {
213 std::string
name = prefix + Str;
214 auto *ConstStr = TheModule.getGlobalVariable(name);
216 llvm::Constant *value = llvm::ConstantDataArray::getString(VMContext,Str);
217 auto *GV =
new llvm::GlobalVariable(TheModule, value->getType(),
true,
218 llvm::GlobalValue::LinkOnceODRLinkage, value, name);
219 GV->setComdat(TheModule.getOrInsertComdat(name));
221 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
224 return llvm::ConstantExpr::getGetElementPtr(ConstStr->getValueType(),
230 const Decl *Container) {
233 std::string NameAndAttributes;
234 std::string TypeStr =
236 NameAndAttributes +=
'\0';
237 NameAndAttributes += TypeStr.length() + 3;
238 NameAndAttributes += TypeStr;
239 NameAndAttributes +=
'\0';
241 return MakeConstantString(NameAndAttributes);
250 int attrs =
property->getPropertyAttributes();
253 attrs &= ~ObjCPropertyAttribute::kind_copy;
254 attrs &= ~ObjCPropertyAttribute::kind_retain;
255 attrs &= ~ObjCPropertyAttribute::kind_weak;
256 attrs &= ~ObjCPropertyAttribute::kind_strong;
259 Fields.addInt(Int8Ty, attrs & 0xff);
265 attrs |= isSynthesized ? (1<<0) : 0;
266 attrs |= isDynamic ? (1<<1) : 0;
269 Fields.addInt(Int8Ty, attrs & 0xff);
271 Fields.addInt(Int8Ty, 0);
272 Fields.addInt(Int8Ty, 0);
275 virtual llvm::Constant *GenerateCategoryProtocolList(
const
280 Fields.addInt(IntTy, count);
283 llvm::DataLayout td(&TheModule);
284 Fields.addInt(IntTy, td.getTypeSizeInBits(PropertyMetadataTy) /
295 bool isSynthesized=
true,
bool
297 auto Fields = PropertiesArray.
beginStruct(PropertyMetadataTy);
299 Fields.add(MakePropertyEncodingString(property, OCD));
300 PushPropertyAttributes(Fields, property, isSynthesized, isDynamic);
304 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
305 Fields.add(MakeConstantString(accessor->getSelector().getAsString()));
306 Fields.add(TypeEncoding);
320 llvm::Value *EnforceType(
CGBuilderTy &B, llvm::Value *
V, llvm::Type *Ty) {
321 if (
V->getType() == Ty)
323 return B.CreateBitCast(
V, Ty);
327 llvm::Constant *Zeros[2];
329 llvm::Constant *NULLPtr;
331 llvm::LLVMContext &VMContext;
339 llvm::GlobalAlias *ClassPtrAlias;
344 llvm::GlobalAlias *MetaClassPtrAlias;
346 std::vector<llvm::Constant*> Classes;
348 std::vector<llvm::Constant*> Categories;
351 std::vector<llvm::Constant*> ConstantStrings;
355 llvm::StringMap<llvm::Constant*> ObjCStrings;
357 llvm::StringMap<llvm::Constant*> ExistingProtocols;
363 typedef std::pair<std::string, llvm::GlobalAlias*> TypedSelector;
367 typedef llvm::DenseMap<Selector, SmallVector<TypedSelector, 2> >
375 Selector RetainSel, ReleaseSel, AutoreleaseSel;
379 LazyRuntimeFunction IvarAssignFn, StrongCastAssignFn, MemMoveFn, WeakReadFn,
380 WeakAssignFn, GlobalAssignFn;
382 typedef std::pair<std::string, std::string> ClassAliasPair;
384 std::vector<ClassAliasPair> ClassAliases;
388 LazyRuntimeFunction ExceptionThrowFn;
391 LazyRuntimeFunction ExceptionReThrowFn;
394 LazyRuntimeFunction EnterCatchFn;
397 LazyRuntimeFunction ExitCatchFn;
399 LazyRuntimeFunction SyncEnterFn;
401 LazyRuntimeFunction SyncExitFn;
406 LazyRuntimeFunction EnumerationMutationFn;
409 LazyRuntimeFunction GetPropertyFn;
412 LazyRuntimeFunction SetPropertyFn;
414 LazyRuntimeFunction GetStructPropertyFn;
416 LazyRuntimeFunction SetStructPropertyFn;
428 const int ProtocolVersion;
431 const int ClassABIVersion;
447 llvm::Constant *GenerateMethodList(StringRef ClassName,
448 StringRef CategoryName,
450 bool isClassMethodList);
455 virtual llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName);
459 llvm::Constant *GeneratePropertyList(
const Decl *Container,
461 bool isClassProperty=
false,
462 bool protocolOptionalProperties=
false);
472 void GenerateProtocolHolderCategory();
475 llvm::Constant *GenerateClassStructure(
476 llvm::Constant *MetaClass,
477 llvm::Constant *SuperClass,
480 llvm::Constant *Version,
481 llvm::Constant *InstanceSize,
482 llvm::Constant *IVars,
483 llvm::Constant *Methods,
484 llvm::Constant *Protocols,
485 llvm::Constant *IvarOffsets,
486 llvm::Constant *Properties,
487 llvm::Constant *StrongIvarBitmap,
488 llvm::Constant *WeakIvarBitmap,
493 virtual llvm::Constant *GenerateProtocolMethodList(
497 void EmitProtocolMethodList(
T &&Methods, llvm::Constant *&
Required,
501 for (
const auto *I : Methods)
503 OptionalMethods.push_back(I);
505 RequiredMethods.push_back(I);
506 Required = GenerateProtocolMethodList(RequiredMethods);
507 Optional = GenerateProtocolMethodList(OptionalMethods);
513 const std::string &TypeEncoding);
520 const std::string Name =
"__objc_ivar_offset_" +
ID->getNameAsString()
529 void EmitClassRef(
const std::string &className);
533 const std::string &Name,
bool isWeak);
539 llvm::Value *&Receiver,
542 MessageSendInfo &MSI) = 0;
550 MessageSendInfo &MSI) = 0;
567 unsigned protocolClassVersion,
unsigned classABI=1);
574 llvm::Value *Receiver,
const CallArgList &CallArgs,
581 bool isCategoryImpl, llvm::Value *Receiver,
590 virtual llvm::Constant *GetConstantSelector(
Selector Sel,
591 const std::string &TypeEncoding) {
592 llvm_unreachable(
"Runtime unable to generate constant selector");
604 llvm::DenseMap<const ObjCMethodDecl *, llvm::Function *>
605 DirectMethodDefinitions;
639 bool ClearInsertionPoint=
true)
override;
643 llvm::Value *src,
Address dst)
override;
645 llvm::Value *src,
Address dest,
646 bool threadlocal=
false)
override;
648 Address dest, llvm::Value *ivarOffset)
override;
650 llvm::Value *src,
Address dest)
override;
653 llvm::Value *Size)
override;
656 unsigned CVRQualifiers)
override;
683class CGObjCGCC :
public CGObjCGNU {
686 LazyRuntimeFunction MsgLookupFn;
690 LazyRuntimeFunction MsgLookupSuperFn;
694 llvm::Value *cmd, llvm::MDNode *node,
695 MessageSendInfo &MSI)
override {
697 llvm::Value *args[] = {
698 EnforceType(Builder, Receiver, IdTy),
699 EnforceType(Builder, cmd, SelectorTy) };
701 imp->setMetadata(msgSendMDKind, node);
706 llvm::Value *cmd, MessageSendInfo &MSI)
override {
708 llvm::Value *lookupArgs[] = {
709 EnforceType(Builder, ObjCSuper.
emitRawPointer(CGF), PtrToObjCSuperTy),
717 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
719 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
720 PtrToObjCSuperTy, SelectorTy);
725class CGObjCGNUstep :
public CGObjCGNU {
728 LazyRuntimeFunction SlotLookupFn;
733 LazyRuntimeFunction SlotLookupSuperFn;
735 LazyRuntimeFunction SetPropertyAtomic;
737 LazyRuntimeFunction SetPropertyAtomicCopy;
739 LazyRuntimeFunction SetPropertyNonAtomic;
741 LazyRuntimeFunction SetPropertyNonAtomicCopy;
744 LazyRuntimeFunction CxxAtomicObjectGetFn;
747 LazyRuntimeFunction CxxAtomicObjectSetFn;
752 llvm::Type *SlotStructTy;
755 llvm::Constant *GetEHType(
QualType T)
override;
759 llvm::Value *cmd, llvm::MDNode *node,
760 MessageSendInfo &MSI)
override {
762 llvm::FunctionCallee LookupFn = SlotLookupFn;
767 Builder.CreateStore(Receiver, ReceiverPtr);
774 self = llvm::ConstantPointerNull::get(IdTy);
778 if (
auto *LookupFn2 = dyn_cast<llvm::Function>(LookupFn.getCallee()))
779 LookupFn2->addParamAttr(0, llvm::Attribute::NoCapture);
781 llvm::Value *args[] = {
782 EnforceType(Builder, ReceiverPtr.
getPointer(), PtrToIdTy),
783 EnforceType(Builder, cmd, SelectorTy),
784 EnforceType(Builder, self, IdTy)};
786 slot->setOnlyReadsMemory();
787 slot->setMetadata(msgSendMDKind, node);
790 llvm::Value *imp = Builder.CreateAlignedLoad(
791 IMPTy, Builder.CreateStructGEP(SlotStructTy, slot, 4),
796 Receiver = Builder.CreateLoad(ReceiverPtr,
true);
802 MessageSendInfo &MSI)
override {
806 llvm::CallInst *slot =
808 slot->setOnlyReadsMemory();
810 return Builder.CreateAlignedLoad(
811 IMPTy, Builder.CreateStructGEP(SlotStructTy, slot, 4),
816 CGObjCGNUstep(
CodeGenModule &Mod) : CGObjCGNUstep(Mod, 9, 3, 1) {}
817 CGObjCGNUstep(
CodeGenModule &Mod,
unsigned ABI,
unsigned ProtocolABI,
819 CGObjCGNU(Mod, ABI, ProtocolABI, ClassABI) {
822 SlotStructTy = llvm::StructType::get(PtrTy, PtrTy, PtrTy, IntTy, IMPTy);
823 SlotTy = llvm::PointerType::getUnqual(SlotStructTy);
825 SlotLookupFn.init(&CGM,
"objc_msg_lookup_sender", SlotTy, PtrToIdTy,
828 SlotLookupSuperFn.init(&CGM,
"objc_slot_lookup_super", SlotTy,
829 PtrToObjCSuperTy, SelectorTy);
831 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
832 if (usesCxxExceptions) {
834 EnterCatchFn.init(&CGM,
"__cxa_begin_catch", PtrTy, PtrTy);
836 ExitCatchFn.init(&CGM,
"__cxa_end_catch", VoidTy);
838 ExceptionReThrowFn.init(&CGM,
"__cxa_rethrow", PtrTy);
839 }
else if (usesSEHExceptions) {
841 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy);
844 EnterCatchFn.init(&CGM,
"__cxa_begin_catch", PtrTy, PtrTy);
846 ExitCatchFn.init(&CGM,
"__cxa_end_catch", VoidTy);
848 ExceptionReThrowFn.init(&CGM,
"_Unwind_Resume_or_Rethrow", VoidTy,
850 }
else if (R.
getVersion() >= VersionTuple(1, 7)) {
852 EnterCatchFn.init(&CGM,
"objc_begin_catch", IdTy, PtrTy);
854 ExitCatchFn.init(&CGM,
"objc_end_catch", VoidTy);
856 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy, PtrTy);
858 SetPropertyAtomic.init(&CGM,
"objc_setProperty_atomic", VoidTy, IdTy,
859 SelectorTy, IdTy, PtrDiffTy);
860 SetPropertyAtomicCopy.init(&CGM,
"objc_setProperty_atomic_copy", VoidTy,
861 IdTy, SelectorTy, IdTy, PtrDiffTy);
862 SetPropertyNonAtomic.init(&CGM,
"objc_setProperty_nonatomic", VoidTy,
863 IdTy, SelectorTy, IdTy, PtrDiffTy);
864 SetPropertyNonAtomicCopy.init(&CGM,
"objc_setProperty_nonatomic_copy",
865 VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy);
868 CxxAtomicObjectSetFn.init(&CGM,
"objc_setCppObjectAtomic", VoidTy, PtrTy,
872 CxxAtomicObjectGetFn.init(&CGM,
"objc_getCppObjectAtomic", VoidTy, PtrTy,
876 llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override {
881 return CxxAtomicObjectGetFn;
884 llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override {
889 return CxxAtomicObjectSetFn;
892 llvm::FunctionCallee GetOptimizedPropertySetFunction(
bool atomic,
893 bool copy)
override {
897 assert ((CGM.
getLangOpts().getGC() == LangOptions::NonGC));
904 if (copy)
return SetPropertyAtomicCopy;
905 return SetPropertyAtomic;
908 return copy ? SetPropertyNonAtomicCopy : SetPropertyNonAtomic;
915class CGObjCGNUstep2 :
public CGObjCGNUstep {
920 ClassReferenceSection,
923 ProtocolReferenceSection,
925 ConstantStringSection
930 ClassFlagMeta = (1 << 0),
933 ClassFlagInitialized = (1 << 8),
935 static const char *
const SectionsBaseNames[8];
936 static const char *
const PECOFFSectionsBaseNames[8];
937 template<SectionKind K>
938 std::string sectionName() {
939 if (CGM.
getTriple().isOSBinFormatCOFF()) {
940 std::string
name(PECOFFSectionsBaseNames[K]);
944 return SectionsBaseNames[K];
949 LazyRuntimeFunction MsgLookupSuperFn;
951 LazyRuntimeFunction SentInitializeFn;
955 bool EmittedProtocol =
false;
960 bool EmittedProtocolRef =
false;
964 bool EmittedClass =
false;
968 typedef std::pair<std::string, std::pair<llvm::GlobalVariable*, int>>
970 std::vector<EarlyInitPair> EarlyInitList;
972 std::string SymbolForClassRef(StringRef Name,
bool isWeak) {
974 return (ManglePublicSymbol(
"OBJC_WEAK_REF_CLASS_") + Name).str();
976 return (ManglePublicSymbol(
"OBJC_REF_CLASS_") + Name).str();
979 std::string SymbolForClass(StringRef Name) {
980 return (ManglePublicSymbol(
"OBJC_CLASS_") + Name).str();
982 void CallRuntimeFunction(
CGBuilderTy &B, StringRef FunctionName,
985 for (
auto *Arg : Args)
986 Types.push_back(Arg->getType());
987 llvm::FunctionType *FT = llvm::FunctionType::get(B.getVoidTy(), Types,
990 B.CreateCall(Fn, Args);
999 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
1000 if (old != ObjCStrings.end())
1008 (LiteralLength < 9) && !isNonASCII) {
1014 for (
unsigned i=0 ; i<LiteralLength ; i++)
1015 str |= ((uint64_t)SL->
getCodeUnit(i)) << ((64 - 4 - 3) - (i*7));
1017 str |= LiteralLength << 3;
1020 auto *ObjCStr = llvm::ConstantExpr::getIntToPtr(
1021 llvm::ConstantInt::get(Int64Ty, str), IdTy);
1022 ObjCStrings[Str] = ObjCStr;
1028 if (StringClass.empty()) StringClass =
"NSConstantString";
1030 std::string Sym = SymbolForClass(StringClass);
1032 llvm::Constant *
isa = TheModule.getNamedGlobal(Sym);
1035 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
1036 llvm::GlobalValue::ExternalLinkage,
nullptr, Sym);
1037 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1038 cast<llvm::GlobalValue>(isa)->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
1053 auto Fields = Builder.beginStruct();
1054 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
1057 Fields.addNullPointer(PtrTy);
1064 unsigned NumU8CodeUnits = Str.size();
1069 const llvm::UTF8 *FromPtr = (
const llvm::UTF8 *)Str.data();
1070 llvm::UTF16 *ToPtr = &ToBuf[0];
1071 (void)llvm::ConvertUTF8toUTF16(&FromPtr, FromPtr + NumU8CodeUnits,
1072 &ToPtr, ToPtr + NumU8CodeUnits, llvm::strictConversion);
1073 uint32_t StringLength = ToPtr - &ToBuf[0];
1077 Fields.addInt(Int32Ty, 2);
1079 Fields.addInt(Int32Ty, StringLength);
1081 Fields.addInt(Int32Ty, StringLength * 2);
1083 Fields.addInt(Int32Ty, 0);
1086 auto *
C = llvm::ConstantDataArray::get(VMContext, Arr);
1087 auto *Buffer =
new llvm::GlobalVariable(TheModule,
C->getType(),
1088 true, llvm::GlobalValue::PrivateLinkage,
C,
".str");
1089 Buffer->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1093 Fields.addInt(Int32Ty, 0);
1095 Fields.addInt(Int32Ty, Str.size());
1097 Fields.addInt(Int32Ty, Str.size());
1099 Fields.addInt(Int32Ty, 0);
1101 Fields.add(MakeConstantString(Str));
1103 std::string StringName;
1106 StringName =
".objc_str_";
1107 for (
int i=0,e=Str.size() ; i<e ; ++i) {
1108 unsigned char c = Str[i];
1119 llvm::GlobalVariable *ObjCStrGV =
1121 isNamed ? StringRef(StringName) :
".objc_string",
1122 Align,
false,
isNamed ? llvm::GlobalValue::LinkOnceODRLinkage
1123 : llvm::GlobalValue::PrivateLinkage);
1124 ObjCStrGV->setSection(sectionName<ConstantStringSection>());
1126 ObjCStrGV->setComdat(TheModule.getOrInsertComdat(StringName));
1127 ObjCStrGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1129 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1130 std::pair<llvm::GlobalVariable*, int>
v{ObjCStrGV, 0};
1131 EarlyInitList.emplace_back(Sym,
v);
1133 ObjCStrings[Str] = ObjCStrGV;
1134 ConstantStrings.push_back(ObjCStrGV);
1141 bool isSynthesized=
true,
bool
1142 isDynamic=
true)
override {
1151 auto Fields = PropertiesArray.
beginStruct(PropertyMetadataTy);
1154 std::string TypeStr =
1156 Fields.add(MakeConstantString(TypeStr));
1157 std::string typeStr;
1159 Fields.add(MakeConstantString(typeStr));
1163 Fields.add(GetConstantSelector(accessor->getSelector(), TypeStr));
1165 Fields.add(NULLPtr);
1180 llvm::StructType *ObjCMethodDescTy =
1182 { PtrToInt8Ty, PtrToInt8Ty });
1191 auto MethodList = Builder.beginStruct();
1193 MethodList.addInt(IntTy, Methods.size());
1195 llvm::DataLayout td(&TheModule);
1196 MethodList.addInt(IntTy, td.getTypeSizeInBits(ObjCMethodDescTy) /
1199 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
1200 for (
auto *M : Methods) {
1201 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
1202 Method.add(CGObjCGNU::GetConstantSelector(M));
1204 Method.finishAndAddTo(MethodArray);
1206 MethodArray.finishAndAddTo(MethodList);
1207 return MethodList.finishAndCreateGlobal(
".objc_protocol_method_list",
1213 auto RuntimeProtocols = GetRuntimeProtocolList(ReferencedProtocols.begin(),
1214 ReferencedProtocols.end());
1216 for (
const auto *PI : RuntimeProtocols)
1217 Protocols.push_back(GenerateProtocolRef(PI));
1218 return GenerateProtocolList(Protocols);
1222 llvm::Value *cmd, MessageSendInfo &MSI)
override {
1225 llvm::Value *lookupArgs[] = {
1232 llvm::GlobalVariable *GetClassVar(StringRef Name,
bool isWeak=
false) {
1233 std::string SymbolName = SymbolForClassRef(Name, isWeak);
1234 auto *ClassSymbol = TheModule.getNamedGlobal(SymbolName);
1237 ClassSymbol =
new llvm::GlobalVariable(TheModule,
1238 IdTy,
false, llvm::GlobalValue::ExternalLinkage,
1239 nullptr, SymbolName);
1245 ClassSymbol->setInitializer(
new llvm::GlobalVariable(TheModule,
1246 Int8Ty,
false, llvm::GlobalValue::ExternalWeakLinkage,
1247 nullptr, SymbolForClass(Name)));
1249 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1255 for (
const auto *Result : DC->
lookup(&II))
1256 if ((OID = dyn_cast<ObjCInterfaceDecl>(Result)))
1262 assert(OID &&
"Failed to find ObjCInterfaceDecl");
1264 if (OIDDef !=
nullptr)
1267 auto Storage = llvm::GlobalValue::DefaultStorageClass;
1268 if (OID->
hasAttr<DLLImportAttr>())
1269 Storage = llvm::GlobalValue::DLLImportStorageClass;
1270 else if (OID->
hasAttr<DLLExportAttr>())
1271 Storage = llvm::GlobalValue::DLLExportStorageClass;
1273 cast<llvm::GlobalValue>(ClassSymbol)->setDLLStorageClass(Storage);
1276 assert(ClassSymbol->getName() == SymbolName);
1280 const std::string &Name,
1281 bool isWeak)
override {
1293 switch (Ownership) {
1315 llvm_unreachable(
"Method should not be called!");
1318 llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName)
override {
1319 std::string Name = SymbolForProtocol(ProtocolName);
1320 auto *GV = TheModule.getGlobalVariable(Name);
1323 GV =
new llvm::GlobalVariable(TheModule, ProtocolTy,
false,
1324 llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
1331 llvm::StringMap<llvm::Constant*> ExistingProtocolRefs;
1336 auto *&Ref = ExistingProtocolRefs[Name];
1338 auto *&
Protocol = ExistingProtocols[Name];
1340 Protocol = GenerateProtocolRef(PD);
1341 std::string RefName = SymbolForProtocolRef(Name);
1342 assert(!TheModule.getGlobalVariable(RefName));
1344 auto GV =
new llvm::GlobalVariable(TheModule, ProtocolPtrTy,
false,
1345 llvm::GlobalValue::LinkOnceODRLinkage,
1347 GV->setComdat(TheModule.getOrInsertComdat(RefName));
1348 GV->setSection(sectionName<ProtocolReferenceSection>());
1352 EmittedProtocolRef =
true;
1358 llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(ProtocolPtrTy,
1360 llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
1363 auto ProtocolBuilder = builder.beginStruct();
1364 ProtocolBuilder.addNullPointer(PtrTy);
1365 ProtocolBuilder.addInt(SizeTy, Protocols.size());
1366 ProtocolBuilder.add(ProtocolArray);
1367 return ProtocolBuilder.finishAndCreateGlobal(
".objc_protocol_list",
1376 auto *&
Protocol = ExistingProtocols[ProtocolName];
1380 EmittedProtocol =
true;
1382 auto SymName = SymbolForProtocol(ProtocolName);
1383 auto *OldGV = TheModule.getGlobalVariable(SymName);
1393 Protocol =
new llvm::GlobalVariable(TheModule, ProtocolTy,
1395 llvm::GlobalValue::ExternalLinkage,
nullptr, SymName);
1400 auto RuntimeProtocols =
1402 for (
const auto *PI : RuntimeProtocols)
1403 Protocols.push_back(GenerateProtocolRef(PI));
1404 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
1407 llvm::Constant *InstanceMethodList, *OptionalInstanceMethodList;
1408 llvm::Constant *ClassMethodList, *OptionalClassMethodList;
1410 OptionalInstanceMethodList);
1411 EmitProtocolMethodList(PD->
class_methods(), ClassMethodList,
1412 OptionalClassMethodList);
1417 auto ProtocolBuilder = builder.beginStruct();
1418 ProtocolBuilder.add(llvm::ConstantExpr::getIntToPtr(
1419 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
1420 ProtocolBuilder.add(MakeConstantString(ProtocolName));
1421 ProtocolBuilder.add(ProtocolList);
1422 ProtocolBuilder.add(InstanceMethodList);
1423 ProtocolBuilder.add(ClassMethodList);
1424 ProtocolBuilder.add(OptionalInstanceMethodList);
1425 ProtocolBuilder.add(OptionalClassMethodList);
1427 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
false,
false));
1429 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
false,
true));
1431 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
true,
false));
1433 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
true,
true));
1435 auto *GV = ProtocolBuilder.finishAndCreateGlobal(SymName,
1437 GV->setSection(sectionName<ProtocolSection>());
1438 GV->setComdat(TheModule.getOrInsertComdat(SymName));
1440 OldGV->replaceAllUsesWith(GV);
1441 OldGV->removeFromParent();
1442 GV->setName(SymName);
1448 const std::string &TypeEncoding)
override {
1449 return GetConstantSelector(Sel, TypeEncoding);
1451 std::string GetSymbolNameForTypeEncoding(
const std::string &TypeEncoding) {
1452 std::string MangledTypes = std::string(TypeEncoding);
1458 std::replace(MangledTypes.begin(), MangledTypes.end(),
'@',
'\1');
1461 std::replace(MangledTypes.begin(), MangledTypes.end(),
'=',
'\2');
1462 return MangledTypes;
1464 llvm::Constant *GetTypeString(llvm::StringRef TypeEncoding) {
1465 if (TypeEncoding.empty())
1467 std::string MangledTypes =
1468 GetSymbolNameForTypeEncoding(std::string(TypeEncoding));
1469 std::string TypesVarName =
".objc_sel_types_" + MangledTypes;
1470 auto *TypesGlobal = TheModule.getGlobalVariable(TypesVarName);
1472 llvm::Constant *
Init = llvm::ConstantDataArray::getString(VMContext,
1474 auto *GV =
new llvm::GlobalVariable(TheModule,
Init->getType(),
1475 true, llvm::GlobalValue::LinkOnceODRLinkage,
Init, TypesVarName);
1476 GV->setComdat(TheModule.getOrInsertComdat(TypesVarName));
1477 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1480 return llvm::ConstantExpr::getGetElementPtr(TypesGlobal->getValueType(),
1481 TypesGlobal, Zeros);
1483 llvm::Constant *GetConstantSelector(
Selector Sel,
1484 const std::string &TypeEncoding)
override {
1485 std::string MangledTypes = GetSymbolNameForTypeEncoding(TypeEncoding);
1486 auto SelVarName = (StringRef(
".objc_selector_") + Sel.
getAsString() +
"_" +
1487 MangledTypes).str();
1488 if (
auto *GV = TheModule.getNamedGlobal(SelVarName))
1491 auto SelBuilder = builder.beginStruct();
1492 SelBuilder.add(ExportUniqueString(Sel.
getAsString(),
".objc_sel_name_",
1494 SelBuilder.add(GetTypeString(TypeEncoding));
1495 auto *GV = SelBuilder.finishAndCreateGlobal(SelVarName,
1497 GV->setComdat(TheModule.getOrInsertComdat(SelVarName));
1498 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1499 GV->setSection(sectionName<SelectorSection>());
1502 llvm::StructType *emptyStruct =
nullptr;
1511 std::pair<llvm::Constant*,llvm::Constant*>
1512 GetSectionBounds(StringRef Section) {
1513 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1514 if (emptyStruct ==
nullptr) {
1515 emptyStruct = llvm::StructType::create(VMContext,
".objc_section_sentinel");
1516 emptyStruct->setBody({},
true);
1518 auto ZeroInit = llvm::Constant::getNullValue(emptyStruct);
1519 auto Sym = [&](StringRef Prefix, StringRef SecSuffix) {
1520 auto *Sym =
new llvm::GlobalVariable(TheModule, emptyStruct,
1522 llvm::GlobalValue::LinkOnceODRLinkage, ZeroInit, Prefix +
1524 Sym->setVisibility(llvm::GlobalValue::HiddenVisibility);
1525 Sym->setSection((Section + SecSuffix).str());
1526 Sym->setComdat(TheModule.getOrInsertComdat((Prefix +
1531 return { Sym(
"__start_",
"$a"), Sym(
"__stop",
"$z") };
1533 auto *Start =
new llvm::GlobalVariable(TheModule, PtrTy,
1535 llvm::GlobalValue::ExternalLinkage,
nullptr, StringRef(
"__start_") +
1537 Start->setVisibility(llvm::GlobalValue::HiddenVisibility);
1538 auto *Stop =
new llvm::GlobalVariable(TheModule, PtrTy,
1540 llvm::GlobalValue::ExternalLinkage,
nullptr, StringRef(
"__stop_") +
1542 Stop->setVisibility(llvm::GlobalValue::HiddenVisibility);
1543 return { Start, Stop };
1548 llvm::Function *ModuleInitFunction()
override {
1549 llvm::Function *LoadFunction = llvm::Function::Create(
1550 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
1551 llvm::GlobalValue::LinkOnceODRLinkage,
".objcv2_load_function",
1553 LoadFunction->setVisibility(llvm::GlobalValue::HiddenVisibility);
1554 LoadFunction->setComdat(TheModule.getOrInsertComdat(
".objcv2_load_function"));
1556 llvm::BasicBlock *EntryBB =
1557 llvm::BasicBlock::Create(VMContext,
"entry", LoadFunction);
1559 B.SetInsertPoint(EntryBB);
1561 auto InitStructBuilder = builder.beginStruct();
1562 InitStructBuilder.addInt(Int64Ty, 0);
1563 auto §ionVec = CGM.
getTriple().isOSBinFormatCOFF() ? PECOFFSectionsBaseNames : SectionsBaseNames;
1564 for (
auto *
s : sectionVec) {
1565 auto bounds = GetSectionBounds(
s);
1566 InitStructBuilder.add(bounds.first);
1567 InitStructBuilder.add(bounds.second);
1569 auto *InitStruct = InitStructBuilder.finishAndCreateGlobal(
".objc_init",
1571 InitStruct->setVisibility(llvm::GlobalValue::HiddenVisibility);
1572 InitStruct->setComdat(TheModule.getOrInsertComdat(
".objc_init"));
1574 CallRuntimeFunction(B,
"__objc_load", {InitStruct});;
1581 auto *InitVar =
new llvm::GlobalVariable(TheModule, LoadFunction->getType(),
1582 false, llvm::GlobalValue::LinkOnceAnyLinkage,
1583 LoadFunction,
".objc_ctor");
1586 assert(InitVar->getName() ==
".objc_ctor");
1592 if (CGM.
getTriple().isOSBinFormatCOFF())
1593 InitVar->setSection(
".CRT$XCLz");
1597 InitVar->setSection(
".init_array");
1599 InitVar->setSection(
".ctors");
1601 InitVar->setVisibility(llvm::GlobalValue::HiddenVisibility);
1602 InitVar->setComdat(TheModule.getOrInsertComdat(
".objc_ctor"));
1604 for (
auto *
C : Categories) {
1605 auto *Cat = cast<llvm::GlobalVariable>(
C->stripPointerCasts());
1606 Cat->setSection(sectionName<CategorySection>());
1610 StringRef Section) {
1611 auto nullBuilder = builder.beginStruct();
1612 for (
auto *F :
Init)
1614 auto GV = nullBuilder.finishAndCreateGlobal(Name, CGM.
getPointerAlign(),
1615 false, llvm::GlobalValue::LinkOnceODRLinkage);
1616 GV->setSection(Section);
1617 GV->setComdat(TheModule.getOrInsertComdat(Name));
1618 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1622 for (
auto clsAlias : ClassAliases)
1623 createNullGlobal(std::string(
".objc_class_alias") +
1624 clsAlias.second, { MakeConstantString(clsAlias.second),
1625 GetClassVar(clsAlias.first) }, sectionName<ClassAliasSection>());
1630 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
1631 createNullGlobal(
".objc_null_selector", {NULLPtr, NULLPtr},
1632 sectionName<SelectorSection>());
1633 if (Categories.empty())
1634 createNullGlobal(
".objc_null_category", {NULLPtr, NULLPtr,
1635 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr},
1636 sectionName<CategorySection>());
1637 if (!EmittedClass) {
1638 createNullGlobal(
".objc_null_cls_init_ref", NULLPtr,
1639 sectionName<ClassSection>());
1640 createNullGlobal(
".objc_null_class_ref", { NULLPtr, NULLPtr },
1641 sectionName<ClassReferenceSection>());
1643 if (!EmittedProtocol)
1644 createNullGlobal(
".objc_null_protocol", {NULLPtr, NULLPtr, NULLPtr,
1645 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr,
1646 NULLPtr}, sectionName<ProtocolSection>());
1647 if (!EmittedProtocolRef)
1648 createNullGlobal(
".objc_null_protocol_ref", {NULLPtr},
1649 sectionName<ProtocolReferenceSection>());
1650 if (ClassAliases.empty())
1651 createNullGlobal(
".objc_null_class_alias", { NULLPtr, NULLPtr },
1652 sectionName<ClassAliasSection>());
1653 if (ConstantStrings.empty()) {
1654 auto i32Zero = llvm::ConstantInt::get(Int32Ty, 0);
1655 createNullGlobal(
".objc_null_constant_string", { NULLPtr, i32Zero,
1656 i32Zero, i32Zero, i32Zero, NULLPtr },
1657 sectionName<ConstantStringSection>());
1660 ConstantStrings.clear();
1664 if (EarlyInitList.size() > 0) {
1665 auto *
Init = llvm::Function::Create(llvm::FunctionType::get(CGM.
VoidTy,
1666 {}), llvm::GlobalValue::InternalLinkage,
".objc_early_init",
1668 llvm::IRBuilder<>
b(llvm::BasicBlock::Create(CGM.
getLLVMContext(),
"entry",
1670 for (
const auto &lateInit : EarlyInitList) {
1671 auto *global = TheModule.getGlobalVariable(lateInit.first);
1673 llvm::GlobalVariable *GV = lateInit.second.first;
1674 b.CreateAlignedStore(
1676 b.CreateStructGEP(GV->getValueType(), GV, lateInit.second.second),
1683 auto *InitVar =
new llvm::GlobalVariable(CGM.
getModule(),
Init->getType(),
1684 true, llvm::GlobalValue::InternalLinkage,
1685 Init,
".objc_early_init_ptr");
1686 InitVar->setSection(
".CRT$XCLb");
1695 std::string TypeEncoding;
1697 TypeEncoding = GetSymbolNameForTypeEncoding(TypeEncoding);
1698 const std::string Name =
"__objc_ivar_offset_" +
ID->getNameAsString()
1706 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
1707 if (!IvarOffsetPointer)
1708 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule, IntTy,
false,
1709 llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
1711 llvm::Value *Offset =
1713 if (Offset->getType() != PtrDiffTy)
1714 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
1719 bool IsCOFF = CGM.
getTriple().isOSBinFormatCOFF();
1725 auto *classNameConstant = MakeConstantString(className);
1728 auto metaclassFields = builder.beginStruct();
1730 metaclassFields.addNullPointer(PtrTy);
1732 metaclassFields.addNullPointer(PtrTy);
1734 metaclassFields.add(classNameConstant);
1736 metaclassFields.addInt(LongTy, 0);
1739 metaclassFields.addInt(LongTy, ClassFlags::ClassFlagMeta);
1743 metaclassFields.addInt(LongTy, 0);
1745 metaclassFields.addNullPointer(PtrTy);
1750 metaclassFields.addNullPointer(PtrTy);
1755 metaclassFields.add(
1756 GenerateMethodList(className,
"", ClassMethods,
true));
1759 metaclassFields.addNullPointer(PtrTy);
1761 metaclassFields.addNullPointer(PtrTy);
1763 metaclassFields.addNullPointer(PtrTy);
1765 metaclassFields.addNullPointer(PtrTy);
1767 metaclassFields.addNullPointer(PtrTy);
1769 metaclassFields.addNullPointer(PtrTy);
1771 metaclassFields.addNullPointer(PtrTy);
1773 metaclassFields.addInt(LongTy, 0);
1775 metaclassFields.add(GeneratePropertyList(OID, classDecl,
true));
1777 auto *metaclass = metaclassFields.finishAndCreateGlobal(
1778 ManglePublicSymbol(
"OBJC_METACLASS_") + className,
1781 auto classFields = builder.beginStruct();
1783 classFields.add(metaclass);
1788 llvm::Constant *SuperClass =
nullptr;
1789 if (SuperClassDecl) {
1790 auto SuperClassName = SymbolForClass(SuperClassDecl->
getNameAsString());
1791 SuperClass = TheModule.getNamedGlobal(SuperClassName);
1794 SuperClass =
new llvm::GlobalVariable(TheModule, PtrTy,
false,
1795 llvm::GlobalValue::ExternalLinkage,
nullptr, SuperClassName);
1797 auto Storage = llvm::GlobalValue::DefaultStorageClass;
1798 if (SuperClassDecl->
hasAttr<DLLImportAttr>())
1799 Storage = llvm::GlobalValue::DLLImportStorageClass;
1800 else if (SuperClassDecl->
hasAttr<DLLExportAttr>())
1801 Storage = llvm::GlobalValue::DLLExportStorageClass;
1803 cast<llvm::GlobalValue>(SuperClass)->setDLLStorageClass(Storage);
1807 classFields.add(SuperClass);
1809 classFields.addNullPointer(PtrTy);
1811 classFields.addNullPointer(PtrTy);
1813 classFields.add(classNameConstant);
1815 classFields.addInt(LongTy, 0);
1818 classFields.addInt(LongTy, 0);
1820 int superInstanceSize = !SuperClassDecl ? 0 :
1824 classFields.addInt(LongTy,
1826 superInstanceSize));
1829 classFields.addNullPointer(PtrTy);
1834 llvm::DataLayout td(&TheModule);
1837 auto ivarListBuilder =
b.beginStruct();
1839 ivarListBuilder.addInt(IntTy, ivar_count);
1841 llvm::StructType *ObjCIvarTy = llvm::StructType::get(
1847 ivarListBuilder.addInt(SizeTy, td.getTypeSizeInBits(ObjCIvarTy) /
1850 auto ivarArrayBuilder = ivarListBuilder.beginArray();
1853 auto ivarTy = IVD->getType();
1854 auto ivarBuilder = ivarArrayBuilder.beginStruct();
1856 ivarBuilder.add(MakeConstantString(IVD->getNameAsString()));
1858 std::string TypeStr;
1861 ivarBuilder.add(MakeConstantString(TypeStr));
1863 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
1864 uint64_t Offset = BaseOffset - superInstanceSize;
1865 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
1866 std::string OffsetName = GetIVarOffsetVariableName(classDecl, IVD);
1867 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
1869 OffsetVar->setInitializer(OffsetValue);
1871 OffsetVar =
new llvm::GlobalVariable(TheModule, IntTy,
1872 false, llvm::GlobalValue::ExternalLinkage,
1873 OffsetValue, OffsetName);
1874 auto ivarVisibility =
1878 llvm::GlobalValue::HiddenVisibility :
1879 llvm::GlobalValue::DefaultVisibility;
1880 OffsetVar->setVisibility(ivarVisibility);
1881 if (ivarVisibility != llvm::GlobalValue::HiddenVisibility)
1883 ivarBuilder.add(OffsetVar);
1885 ivarBuilder.addInt(Int32Ty,
1896 ivarBuilder.addInt(Int32Ty,
1897 (align << 3) | (1<<2) |
1898 FlagsForOwnership(ivarTy.getQualifiers().getObjCLifetime()));
1899 ivarBuilder.finishAndAddTo(ivarArrayBuilder);
1901 ivarArrayBuilder.finishAndAddTo(ivarListBuilder);
1902 auto ivarList = ivarListBuilder.finishAndCreateGlobal(
".objc_ivar_list",
1904 llvm::GlobalValue::PrivateLinkage);
1905 classFields.add(ivarList);
1909 InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
1912 if (propImpl->getPropertyImplementation() ==
1915 if (OMD && OMD->hasBody())
1916 InstanceMethods.push_back(OMD);
1918 addIfExists(propImpl->getGetterMethodDecl());
1919 addIfExists(propImpl->getSetterMethodDecl());
1922 if (InstanceMethods.size() == 0)
1923 classFields.addNullPointer(PtrTy);
1926 GenerateMethodList(className,
"", InstanceMethods,
false));
1929 classFields.addNullPointer(PtrTy);
1931 classFields.addNullPointer(PtrTy);
1933 classFields.addNullPointer(PtrTy);
1935 classFields.addNullPointer(PtrTy);
1937 classFields.addNullPointer(PtrTy);
1939 auto RuntimeProtocols = GetRuntimeProtocolList(classDecl->
protocol_begin(),
1942 for (
const auto *I : RuntimeProtocols)
1943 Protocols.push_back(GenerateProtocolRef(I));
1945 if (Protocols.empty())
1946 classFields.addNullPointer(PtrTy);
1948 classFields.add(GenerateProtocolList(Protocols));
1950 classFields.addNullPointer(PtrTy);
1952 classFields.addInt(LongTy, 0);
1954 classFields.add(GeneratePropertyList(OID, classDecl));
1956 llvm::GlobalVariable *classStruct =
1957 classFields.finishAndCreateGlobal(SymbolForClass(className),
1960 auto *classRefSymbol = GetClassVar(className);
1961 classRefSymbol->setSection(sectionName<ClassReferenceSection>());
1962 classRefSymbol->setInitializer(classStruct);
1967 classStruct->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1968 cast<llvm::GlobalValue>(classRefSymbol)->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1972 std::pair<llvm::GlobalVariable*, int>
v{classStruct, 1};
1973 EarlyInitList.emplace_back(std::string(SuperClass->getName()),
1982 if (ClassPtrAlias) {
1983 ClassPtrAlias->replaceAllUsesWith(classStruct);
1984 ClassPtrAlias->eraseFromParent();
1985 ClassPtrAlias =
nullptr;
1987 if (
auto Placeholder =
1988 TheModule.getNamedGlobal(SymbolForClass(className)))
1989 if (Placeholder != classStruct) {
1990 Placeholder->replaceAllUsesWith(classStruct);
1991 Placeholder->eraseFromParent();
1992 classStruct->setName(SymbolForClass(className));
1994 if (MetaClassPtrAlias) {
1995 MetaClassPtrAlias->replaceAllUsesWith(metaclass);
1996 MetaClassPtrAlias->eraseFromParent();
1997 MetaClassPtrAlias =
nullptr;
1999 assert(classStruct->getName() == SymbolForClass(className));
2001 auto classInitRef =
new llvm::GlobalVariable(TheModule,
2002 classStruct->getType(),
false, llvm::GlobalValue::ExternalLinkage,
2003 classStruct, ManglePublicSymbol(
"OBJC_INIT_CLASS_") + className);
2004 classInitRef->setSection(sectionName<ClassSection>());
2007 EmittedClass =
true;
2010 CGObjCGNUstep2(
CodeGenModule &Mod) : CGObjCGNUstep(Mod, 10, 4, 2) {
2011 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
2012 PtrToObjCSuperTy, SelectorTy);
2013 SentInitializeFn.init(&CGM,
"objc_send_initialize",
2014 llvm::Type::getVoidTy(VMContext), IdTy);
2023 PropertyMetadataTy =
2025 { PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty });
2028 void GenerateDirectMethodPrologue(
CodeGenFunction &CGF, llvm::Function *Fn,
2032 bool ReceiverCanBeNull =
true;
2034 auto selfValue = Builder.CreateLoad(selfAddr);
2059 ReceiverCanBeNull = isWeakLinkedClass(OID);
2063 if (ReceiverCanBeNull) {
2064 llvm::BasicBlock *SelfIsNilBlock =
2066 llvm::BasicBlock *ContBlock =
2070 auto selfTy = cast<llvm::PointerType>(selfValue->getType());
2071 auto Zero = llvm::ConstantPointerNull::get(selfTy);
2073 Builder.CreateCondBr(Builder.CreateICmpEQ(selfValue, Zero),
2074 SelfIsNilBlock, ContBlock,
2075 MDHelper.createBranchWeights(1, 1 << 20));
2081 Builder.SetInsertPoint(SelfIsNilBlock);
2082 if (!retTy->isVoidType()) {
2090 Builder.SetInsertPoint(ContBlock);
2096 llvm::StructType::get(PtrTy, PtrTy, PtrTy, LongTy, LongTy);
2098 auto flags = Builder.CreateLoad(
2099 Address{Builder.CreateStructGEP(classStart, selfValue, 4), LongTy,
2101 astContext.getTypeAlign(astContext.UnsignedLongTy))});
2102 auto isInitialized =
2103 Builder.CreateAnd(flags, ClassFlags::ClassFlagInitialized);
2104 llvm::BasicBlock *notInitializedBlock =
2106 llvm::BasicBlock *initializedBlock =
2108 Builder.CreateCondBr(Builder.CreateICmpEQ(isInitialized, Zeros[0]),
2109 notInitializedBlock, initializedBlock,
2110 MDHelper.createBranchWeights(1, 1 << 20));
2112 Builder.SetInsertPoint(notInitializedBlock);
2114 Builder.CreateBr(initializedBlock);
2116 Builder.SetInsertPoint(initializedBlock);
2124 Builder.CreateStore(GetSelector(CGF, OMD),
2130const char *
const CGObjCGNUstep2::SectionsBaseNames[8] =
2137"__objc_protocol_refs",
2138"__objc_class_aliases",
2139"__objc_constant_string"
2142const char *
const CGObjCGNUstep2::PECOFFSectionsBaseNames[8] =
2155class CGObjCObjFW:
public CGObjCGNU {
2159 LazyRuntimeFunction MsgLookupFn;
2162 LazyRuntimeFunction MsgLookupFnSRet;
2166 LazyRuntimeFunction MsgLookupSuperFn, MsgLookupSuperFnSRet;
2169 llvm::Value *cmd, llvm::MDNode *node,
2170 MessageSendInfo &MSI)
override {
2172 llvm::Value *args[] = {
2173 EnforceType(Builder, Receiver, IdTy),
2174 EnforceType(Builder, cmd, SelectorTy) };
2176 llvm::CallBase *imp;
2182 imp->setMetadata(msgSendMDKind, node);
2187 llvm::Value *cmd, MessageSendInfo &MSI)
override {
2189 llvm::Value *lookupArgs[] = {
2190 EnforceType(Builder, ObjCSuper.
emitRawPointer(CGF), PtrToObjCSuperTy),
2200 llvm::Value *GetClassNamed(
CodeGenFunction &CGF,
const std::string &Name,
2201 bool isWeak)
override {
2203 return CGObjCGNU::GetClassNamed(CGF, Name, isWeak);
2206 std::string SymbolName =
"_OBJC_CLASS_" + Name;
2207 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(SymbolName);
2209 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
2210 llvm::GlobalValue::ExternalLinkage,
2211 nullptr, SymbolName);
2218 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
2219 MsgLookupFnSRet.init(&CGM,
"objc_msg_lookup_stret", IMPTy, IdTy,
2222 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
2223 PtrToObjCSuperTy, SelectorTy);
2224 MsgLookupSuperFnSRet.init(&CGM,
"objc_msg_lookup_super_stret", IMPTy,
2225 PtrToObjCSuperTy, SelectorTy);
2233void CGObjCGNU::EmitClassRef(
const std::string &className) {
2234 std::string symbolRef =
"__objc_class_ref_" + className;
2236 if (TheModule.getGlobalVariable(symbolRef))
2238 std::string symbolName =
"__objc_class_name_" + className;
2239 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
2241 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
2242 llvm::GlobalValue::ExternalLinkage,
2243 nullptr, symbolName);
2245 new llvm::GlobalVariable(TheModule, ClassSymbol->getType(),
true,
2246 llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef);
2249CGObjCGNU::CGObjCGNU(
CodeGenModule &cgm,
unsigned runtimeABIVersion,
2250 unsigned protocolClassVersion,
unsigned classABI)
2252 VMContext(cgm.getLLVMContext()), ClassPtrAlias(nullptr),
2253 MetaClassPtrAlias(nullptr), RuntimeVersion(runtimeABIVersion),
2254 ProtocolVersion(protocolClassVersion), ClassABIVersion(classABI) {
2256 msgSendMDKind = VMContext.getMDKindID(
"GNUObjCMessageSend");
2264 IntTy = cast<llvm::IntegerType>(
2266 LongTy = cast<llvm::IntegerType>(
2268 SizeTy = cast<llvm::IntegerType>(
2270 PtrDiffTy = cast<llvm::IntegerType>(
2274 Int8Ty = llvm::Type::getInt8Ty(VMContext);
2276 PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
2277 ProtocolPtrTy = llvm::PointerType::getUnqual(
2280 Zeros[0] = llvm::ConstantInt::get(LongTy, 0);
2281 Zeros[1] = Zeros[0];
2282 NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty);
2286 SelectorTy = PtrToInt8Ty;
2287 SelectorElemTy = Int8Ty;
2293 PtrToIntTy = llvm::PointerType::getUnqual(IntTy);
2294 PtrTy = PtrToInt8Ty;
2296 Int32Ty = llvm::Type::getInt32Ty(VMContext);
2297 Int64Ty = llvm::Type::getInt64Ty(VMContext);
2300 CGM.
getDataLayout().getPointerSizeInBits() == 32 ? Int32Ty : Int64Ty;
2314 PtrToIdTy = llvm::PointerType::getUnqual(IdTy);
2315 ProtocolTy = llvm::StructType::get(IdTy,
2337 PropertyMetadataTy = llvm::StructType::get(CGM.
getLLVMContext(), {
2338 PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty,
2339 PtrToInt8Ty, PtrToInt8Ty });
2341 ObjCSuperTy = llvm::StructType::get(IdTy, IdTy);
2342 PtrToObjCSuperTy = llvm::PointerType::getUnqual(ObjCSuperTy);
2344 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
2347 ExceptionThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy);
2348 ExceptionReThrowFn.init(&CGM,
2349 usesCxxExceptions ?
"objc_exception_rethrow"
2350 :
"objc_exception_throw",
2353 SyncEnterFn.init(&CGM,
"objc_sync_enter", IntTy, IdTy);
2355 SyncExitFn.init(&CGM,
"objc_sync_exit", IntTy, IdTy);
2358 EnumerationMutationFn.init(&CGM,
"objc_enumerationMutation", VoidTy, IdTy);
2361 GetPropertyFn.init(&CGM,
"objc_getProperty", IdTy, IdTy, SelectorTy,
2364 SetPropertyFn.init(&CGM,
"objc_setProperty", VoidTy, IdTy, SelectorTy,
2365 PtrDiffTy, IdTy, BoolTy, BoolTy);
2367 GetStructPropertyFn.init(&CGM,
"objc_getPropertyStruct", VoidTy, PtrTy, PtrTy,
2368 PtrDiffTy, BoolTy, BoolTy);
2370 SetStructPropertyFn.init(&CGM,
"objc_setPropertyStruct", VoidTy, PtrTy, PtrTy,
2371 PtrDiffTy, BoolTy, BoolTy);
2374 llvm::Type *IMPArgs[] = { IdTy, SelectorTy };
2375 IMPTy = llvm::PointerType::getUnqual(llvm::FunctionType::get(IdTy, IMPArgs,
2379 if ((Opts.getGC() != LangOptions::NonGC) || Opts.ObjCAutoRefCount)
2380 RuntimeVersion = 10;
2383 if (Opts.getGC() != LangOptions::NonGC) {
2395 IvarAssignFn.init(&CGM,
"objc_assign_ivar", IdTy, IdTy, IdTy, PtrDiffTy);
2397 StrongCastAssignFn.init(&CGM,
"objc_assign_strongCast", IdTy, IdTy,
2400 GlobalAssignFn.init(&CGM,
"objc_assign_global", IdTy, IdTy, PtrToIdTy);
2402 WeakAssignFn.init(&CGM,
"objc_assign_weak", IdTy, IdTy, PtrToIdTy);
2404 WeakReadFn.init(&CGM,
"objc_read_weak", IdTy, PtrToIdTy);
2406 MemMoveFn.init(&CGM,
"objc_memmove_collectable", PtrTy, PtrTy, PtrTy,
2412 const std::string &Name,
bool isWeak) {
2413 llvm::Constant *ClassName = MakeConstantString(Name);
2425 llvm::FunctionType::get(IdTy, PtrToInt8Ty,
true),
"objc_lookup_class");
2435 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value))
2440llvm::Value *CGObjCGNU::EmitNSAutoreleasePoolClassRef(
CodeGenFunction &CGF) {
2441 auto *
Value = GetClassNamed(CGF,
"NSAutoreleasePool",
false);
2442 if (CGM.
getTriple().isOSBinFormatCOFF()) {
2443 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value)) {
2449 for (
const auto *Result : DC->
lookup(&II))
2450 if ((VD = dyn_cast<VarDecl>(Result)))
2460 const std::string &TypeEncoding) {
2462 llvm::GlobalAlias *SelValue =
nullptr;
2465 e = Types.end() ; i!=e ; i++) {
2466 if (i->first == TypeEncoding) {
2467 SelValue = i->second;
2472 SelValue = llvm::GlobalAlias::create(SelectorElemTy, 0,
2473 llvm::GlobalValue::PrivateLinkage,
2476 Types.emplace_back(TypeEncoding, SelValue);
2483 llvm::Value *SelValue = GetSelector(CGF, Sel);
2494 return GetTypedSelector(CGF, Sel, std::string());
2500 return GetTypedSelector(CGF, Method->
getSelector(), SelTypes);
2503llvm::Constant *CGObjCGNU::GetEHType(
QualType T) {
2510 return MakeConstantString(
"@id");
2518 assert(OPT &&
"Invalid @catch type.");
2520 assert(IDecl &&
"Invalid @catch type.");
2524llvm::Constant *CGObjCGNUstep::GetEHType(
QualType T) {
2525 if (usesSEHExceptions)
2528 if (!CGM.
getLangOpts().CPlusPlus && !usesCxxExceptions)
2529 return CGObjCGNU::GetEHType(
T);
2537 llvm::Constant *IDEHType =
2538 CGM.
getModule().getGlobalVariable(
"__objc_id_type_info");
2541 new llvm::GlobalVariable(CGM.
getModule(), PtrToInt8Ty,
2543 llvm::GlobalValue::ExternalLinkage,
2544 nullptr,
"__objc_id_type_info");
2550 assert(PT &&
"Invalid @catch type.");
2552 assert(IT &&
"Invalid @catch type.");
2553 std::string className =
2556 std::string typeinfoName =
"__objc_eh_typeinfo_" + className;
2559 if (llvm::Constant *typeinfo = TheModule.getGlobalVariable(typeinfoName))
2567 const char *vtableName =
"_ZTVN7gnustep7libobjc22__objc_class_type_infoE";
2568 auto *Vtable = TheModule.getGlobalVariable(vtableName);
2570 Vtable =
new llvm::GlobalVariable(TheModule, PtrToInt8Ty,
true,
2571 llvm::GlobalValue::ExternalLinkage,
2572 nullptr, vtableName);
2574 llvm::Constant *Two = llvm::ConstantInt::get(IntTy, 2);
2576 llvm::ConstantExpr::getGetElementPtr(Vtable->getValueType(), Vtable, Two);
2578 llvm::Constant *typeName =
2579 ExportUniqueString(className,
"__objc_eh_typename_");
2582 auto fields = builder.beginStruct();
2583 fields.add(BVtable);
2584 fields.add(typeName);
2585 llvm::Constant *TI =
2586 fields.finishAndCreateGlobal(
"__objc_eh_typeinfo_" + className,
2589 llvm::GlobalValue::LinkOnceODRLinkage);
2596 std::string Str = SL->
getString().str();
2600 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
2601 if (old != ObjCStrings.end())
2606 if (StringClass.empty()) StringClass =
"NSConstantString";
2608 std::string Sym =
"_OBJC_CLASS_";
2611 llvm::Constant *
isa = TheModule.getNamedGlobal(Sym);
2614 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
2615 llvm::GlobalValue::ExternalWeakLinkage,
2619 auto Fields = Builder.beginStruct();
2621 Fields.add(MakeConstantString(Str));
2622 Fields.addInt(IntTy, Str.size());
2624 ObjCStrings[Str] = ObjCStr;
2625 ConstantStrings.push_back(ObjCStr);
2638 bool isCategoryImpl,
2639 llvm::Value *Receiver,
2640 bool IsClassMessage,
2644 if (CGM.
getLangOpts().getGC() == LangOptions::GCOnly) {
2645 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2649 if (Sel == ReleaseSel) {
2654 llvm::Value *cmd = GetSelector(CGF, Sel);
2657 ActualArgs.
add(
RValue::get(EnforceType(Builder, Receiver, IdTy)), ASTIdTy);
2661 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2663 llvm::Value *ReceiverClass =
nullptr;
2666 ReceiverClass = GetClassNamed(CGF,
2667 Class->getSuperClass()->getNameAsString(),
false);
2668 if (IsClassMessage) {
2670 ReceiverClass = Builder.CreateBitCast(ReceiverClass,
2671 llvm::PointerType::getUnqual(IdTy));
2673 Builder.CreateAlignedLoad(IdTy, ReceiverClass, CGF.
getPointerAlign());
2675 ReceiverClass = EnforceType(Builder, ReceiverClass, IdTy);
2677 if (isCategoryImpl) {
2678 llvm::FunctionCallee classLookupFunction =
nullptr;
2679 if (IsClassMessage) {
2681 IdTy, PtrTy,
true),
"objc_get_meta_class");
2684 IdTy, PtrTy,
true),
"objc_get_class");
2686 ReceiverClass = Builder.CreateCall(classLookupFunction,
2687 MakeConstantString(
Class->getNameAsString()));
2694 if (IsClassMessage) {
2695 if (!MetaClassPtrAlias) {
2696 MetaClassPtrAlias = llvm::GlobalAlias::create(
2697 IdElemTy, 0, llvm::GlobalValue::InternalLinkage,
2698 ".objc_metaclass_ref" +
Class->getNameAsString(), &TheModule);
2700 ReceiverClass = MetaClassPtrAlias;
2702 if (!ClassPtrAlias) {
2703 ClassPtrAlias = llvm::GlobalAlias::create(
2704 IdElemTy, 0, llvm::GlobalValue::InternalLinkage,
2705 ".objc_class_ref" +
Class->getNameAsString(), &TheModule);
2707 ReceiverClass = ClassPtrAlias;
2711 llvm::Type *CastTy = llvm::StructType::get(IdTy, IdTy);
2712 ReceiverClass = Builder.CreateBitCast(ReceiverClass,
2713 llvm::PointerType::getUnqual(CastTy));
2715 ReceiverClass = Builder.CreateStructGEP(CastTy, ReceiverClass, 1);
2718 Builder.CreateAlignedLoad(IdTy, ReceiverClass, CGF.
getPointerAlign());
2721 llvm::StructType *ObjCSuperTy =
2722 llvm::StructType::get(Receiver->getType(), IdTy);
2727 Builder.CreateStore(Receiver, Builder.CreateStructGEP(ObjCSuper, 0));
2728 Builder.CreateStore(ReceiverClass, Builder.CreateStructGEP(ObjCSuper, 1));
2731 llvm::Value *imp = LookupIMPSuper(CGF, ObjCSuper, cmd, MSI);
2732 imp = EnforceType(Builder, imp, MSI.MessengerType);
2734 llvm::Metadata *impMD[] = {
2735 llvm::MDString::get(VMContext, Sel.
getAsString()),
2736 llvm::MDString::get(VMContext,
Class->getSuperClass()->getNameAsString()),
2737 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2738 llvm::Type::getInt1Ty(VMContext), IsClassMessage))};
2739 llvm::MDNode *
node = llvm::MDNode::get(VMContext, impMD);
2743 llvm::CallBase *call;
2744 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2745 call->setMetadata(msgSendMDKind, node);
2755 llvm::Value *Receiver,
2762 if (CGM.
getLangOpts().getGC() == LangOptions::GCOnly) {
2763 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2767 if (Sel == ReleaseSel) {
2778 cmd = GetSelector(CGF, Method);
2780 cmd = GetSelector(CGF, Sel);
2781 cmd = EnforceType(Builder, cmd, SelectorTy);
2784 Receiver = EnforceType(Builder, Receiver, IdTy);
2786 llvm::Metadata *impMD[] = {
2787 llvm::MDString::get(VMContext, Sel.
getAsString()),
2788 llvm::MDString::get(VMContext, Class ?
Class->getNameAsString() :
""),
2789 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2790 llvm::Type::getInt1Ty(VMContext), Class !=
nullptr))};
2791 llvm::MDNode *
node = llvm::MDNode::get(VMContext, impMD);
2799 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2820 bool hasParamDestroyedInCallee =
false;
2821 bool requiresExplicitZeroResult =
false;
2822 bool requiresNilReceiverCheck = [&] {
2824 if (!canMessageReceiverBeNull(CGF, Method,
false,
2830 hasParamDestroyedInCallee =
true;
2851 requiresExplicitZeroResult = !isDirect;
2855 return hasParamDestroyedInCallee || requiresExplicitZeroResult;
2861 bool requiresExplicitAggZeroing =
2865 llvm::BasicBlock *continueBB =
nullptr;
2867 llvm::BasicBlock *nilPathBB =
nullptr;
2869 llvm::BasicBlock *nilCleanupBB =
nullptr;
2872 if (requiresNilReceiverCheck) {
2879 if (requiresExplicitAggZeroing || hasParamDestroyedInCallee) {
2882 nilPathBB = Builder.GetInsertBlock();
2885 llvm::Value *isNil = Builder.CreateICmpEQ(Receiver,
2886 llvm::Constant::getNullValue(Receiver->getType()));
2887 Builder.CreateCondBr(isNil, nilCleanupBB ? nilCleanupBB : continueBB,
2904 imp = LookupIMP(CGF, Receiver, cmd, node, MSI);
2911 "objc_msgSend_fpret")
2918 "objc_msgSend_stret")
2922 llvm::FunctionType::get(IdTy, IdTy,
true),
"objc_msgSend")
2930 imp = EnforceType(Builder, imp, MSI.MessengerType);
2932 llvm::CallBase *call;
2934 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2936 call->setMetadata(msgSendMDKind, node);
2938 if (requiresNilReceiverCheck) {
2939 llvm::BasicBlock *nonNilPathBB = CGF.
Builder.GetInsertBlock();
2940 CGF.
Builder.CreateBr(continueBB);
2946 if (hasParamDestroyedInCallee) {
2947 destroyCalleeDestroyedArguments(CGF, Method, CallArgs);
2950 if (requiresExplicitAggZeroing) {
2956 nilPathBB = CGF.
Builder.GetInsertBlock();
2957 CGF.
Builder.CreateBr(continueBB);
2965 llvm::PHINode *phi = Builder.CreatePHI(
v->getType(), 2);
2966 phi->addIncoming(
v, nonNilPathBB);
2974 llvm::PHINode *phi = Builder.CreatePHI(
v.first->getType(), 2);
2975 phi->addIncoming(
v.first, nonNilPathBB);
2976 phi->addIncoming(llvm::Constant::getNullValue(
v.first->getType()),
2978 llvm::PHINode *phi2 = Builder.CreatePHI(
v.second->getType(), 2);
2979 phi2->addIncoming(
v.second, nonNilPathBB);
2980 phi2->addIncoming(llvm::Constant::getNullValue(
v.second->getType()),
2990llvm::Constant *CGObjCGNU::
2991GenerateMethodList(StringRef ClassName,
2992 StringRef CategoryName,
2994 bool isClassMethodList) {
2995 if (Methods.empty())
3000 auto MethodList = Builder.beginStruct();
3001 MethodList.addNullPointer(CGM.
Int8PtrTy);
3002 MethodList.addInt(Int32Ty, Methods.size());
3005 llvm::StructType *ObjCMethodTy =
3014 llvm::DataLayout td(&TheModule);
3015 MethodList.addInt(SizeTy, td.getTypeSizeInBits(ObjCMethodTy) /
3031 auto MethodArray = MethodList.beginArray();
3033 for (
const auto *OMD : Methods) {
3034 llvm::Constant *FnPtr =
3035 TheModule.getFunction(getSymbolNameForMethod(OMD));
3036 assert(FnPtr &&
"Can't generate metadata for method that doesn't exist");
3037 auto Method = MethodArray.beginStruct(ObjCMethodTy);
3048 Method.finishAndAddTo(MethodArray);
3050 MethodArray.finishAndAddTo(MethodList);
3053 return MethodList.finishAndCreateGlobal(
".objc_method_list",
3058llvm::Constant *CGObjCGNU::
3064 if (IvarNames.empty())
3070 auto IvarList = Builder.beginStruct();
3071 IvarList.addInt(IntTy, (
int)IvarNames.size());
3074 llvm::StructType *ObjCIvarTy =
3075 llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, IntTy);
3078 auto Ivars = IvarList.beginArray(ObjCIvarTy);
3079 for (
unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {
3080 auto Ivar = Ivars.beginStruct(ObjCIvarTy);
3081 Ivar.
add(IvarNames[i]);
3082 Ivar.
add(IvarTypes[i]);
3083 Ivar.
add(IvarOffsets[i]);
3084 Ivar.finishAndAddTo(Ivars);
3086 Ivars.finishAndAddTo(IvarList);
3089 return IvarList.finishAndCreateGlobal(
".objc_ivar_list",
3094llvm::Constant *CGObjCGNU::GenerateClassStructure(
3095 llvm::Constant *MetaClass,
3096 llvm::Constant *SuperClass,
3099 llvm::Constant *Version,
3100 llvm::Constant *InstanceSize,
3101 llvm::Constant *IVars,
3102 llvm::Constant *Methods,
3103 llvm::Constant *Protocols,
3104 llvm::Constant *IvarOffsets,
3105 llvm::Constant *Properties,
3106 llvm::Constant *StrongIvarBitmap,
3107 llvm::Constant *WeakIvarBitmap,
3116 llvm::StructType *ClassTy = llvm::StructType::get(
3133 IvarOffsets->getType(),
3134 Properties->getType(),
3140 auto Elements = Builder.beginStruct(ClassTy);
3145 Elements.add(MetaClass);
3147 Elements.add(SuperClass);
3149 Elements.add(MakeConstantString(Name,
".class_name"));
3151 Elements.addInt(LongTy, 0);
3153 Elements.addInt(LongTy, info);
3156 llvm::DataLayout td(&TheModule);
3157 Elements.addInt(LongTy,
3158 td.getTypeSizeInBits(ClassTy) /
3161 Elements.add(InstanceSize);
3163 Elements.add(IVars);
3165 Elements.add(Methods);
3168 Elements.add(NULLPtr);
3170 Elements.add(NULLPtr);
3172 Elements.add(NULLPtr);
3174 Elements.add(Protocols);
3176 Elements.add(NULLPtr);
3178 Elements.addInt(LongTy, ClassABIVersion);
3180 Elements.add(IvarOffsets);
3182 Elements.add(Properties);
3184 Elements.add(StrongIvarBitmap);
3186 Elements.add(WeakIvarBitmap);
3191 std::string ClassSym((isMeta ?
"_OBJC_METACLASS_":
"_OBJC_CLASS_") +
3193 llvm::GlobalVariable *ClassRef = TheModule.getNamedGlobal(ClassSym);
3194 llvm::Constant *
Class =
3195 Elements.finishAndCreateGlobal(ClassSym, CGM.
getPointerAlign(),
false,
3196 llvm::GlobalValue::ExternalLinkage);
3198 ClassRef->replaceAllUsesWith(Class);
3199 ClassRef->removeFromParent();
3200 Class->setName(ClassSym);
3205llvm::Constant *CGObjCGNU::
3208 llvm::StructType *ObjCMethodDescTy =
3209 llvm::StructType::get(CGM.
getLLVMContext(), { PtrToInt8Ty, PtrToInt8Ty });
3212 auto MethodList = Builder.beginStruct();
3213 MethodList.addInt(IntTy, Methods.size());
3214 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
3215 for (
auto *M : Methods) {
3216 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
3217 Method.
add(MakeConstantString(M->getSelector().getAsString()));
3219 Method.finishAndAddTo(MethodArray);
3221 MethodArray.finishAndAddTo(MethodList);
3222 return MethodList.finishAndCreateGlobal(
".objc_method_list",
3231 auto ProtocolList = Builder.beginStruct();
3232 ProtocolList.add(NULLPtr);
3233 ProtocolList.addInt(LongTy, Protocols.size());
3235 auto Elements = ProtocolList.beginArray(PtrToInt8Ty);
3236 for (
const std::string *iter = Protocols.begin(), *endIter = Protocols.end();
3237 iter != endIter ; iter++) {
3238 llvm::Constant *protocol =
nullptr;
3239 llvm::StringMap<llvm::Constant*>::iterator value =
3240 ExistingProtocols.find(*iter);
3241 if (value == ExistingProtocols.end()) {
3242 protocol = GenerateEmptyProtocol(*iter);
3244 protocol = value->getValue();
3246 Elements.add(protocol);
3248 Elements.finishAndAddTo(ProtocolList);
3249 return ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
3255 auto protocol = GenerateProtocolRef(PD);
3258 return CGF.
Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(
T));
3261llvm::Constant *CGObjCGNU::GenerateProtocolRef(
const ObjCProtocolDecl *PD) {
3264 GenerateProtocol(PD);
3265 assert(protocol &&
"Unknown protocol");
3270CGObjCGNU::GenerateEmptyProtocol(StringRef ProtocolName) {
3271 llvm::Constant *ProtocolList = GenerateProtocolList({});
3272 llvm::Constant *MethodList = GenerateProtocolMethodList({});
3276 auto Elements = Builder.beginStruct();
3280 Elements.add(llvm::ConstantExpr::getIntToPtr(
3281 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3283 Elements.add(MakeConstantString(ProtocolName,
".objc_protocol_name"));
3284 Elements.add(ProtocolList);
3285 Elements.add(MethodList);
3286 Elements.add(MethodList);
3287 Elements.add(MethodList);
3288 Elements.add(MethodList);
3289 Elements.add(NULLPtr);
3290 Elements.add(NULLPtr);
3291 return Elements.finishAndCreateGlobal(SymbolForProtocol(ProtocolName),
3307 Protocols.push_back(PI->getNameAsString());
3311 if (I->isOptional())
3312 OptionalInstanceMethods.push_back(I);
3314 InstanceMethods.push_back(I);
3319 if (I->isOptional())
3320 OptionalClassMethods.push_back(I);
3322 ClassMethods.push_back(I);
3324 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
3325 llvm::Constant *InstanceMethodList =
3326 GenerateProtocolMethodList(InstanceMethods);
3327 llvm::Constant *ClassMethodList =
3328 GenerateProtocolMethodList(ClassMethods);
3329 llvm::Constant *OptionalInstanceMethodList =
3330 GenerateProtocolMethodList(OptionalInstanceMethods);
3331 llvm::Constant *OptionalClassMethodList =
3332 GenerateProtocolMethodList(OptionalClassMethods);
3340 llvm::Constant *PropertyList =
3341 GeneratePropertyList(
nullptr, PD,
false,
false);
3342 llvm::Constant *OptionalPropertyList =
3343 GeneratePropertyList(
nullptr, PD,
false,
true);
3350 auto Elements = Builder.beginStruct();
3352 llvm::ConstantExpr::getIntToPtr(
3353 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3354 Elements.add(MakeConstantString(ProtocolName));
3355 Elements.add(ProtocolList);
3356 Elements.add(InstanceMethodList);
3357 Elements.add(ClassMethodList);
3358 Elements.add(OptionalInstanceMethodList);
3359 Elements.add(OptionalClassMethodList);
3360 Elements.add(PropertyList);
3361 Elements.add(OptionalPropertyList);
3362 ExistingProtocols[ProtocolName] =
3363 Elements.finishAndCreateGlobal(
".objc_protocol", CGM.
getPointerAlign());
3365void CGObjCGNU::GenerateProtocolHolderCategory() {
3369 auto Elements = Builder.beginStruct();
3371 const std::string ClassName =
"__ObjC_Protocol_Holder_Ugly_Hack";
3372 const std::string CategoryName =
"AnotherHack";
3373 Elements.add(MakeConstantString(CategoryName));
3374 Elements.add(MakeConstantString(ClassName));
3376 Elements.add(GenerateMethodList(ClassName, CategoryName, {},
false));
3378 Elements.add(GenerateMethodList(ClassName, CategoryName, {},
true));
3382 auto ProtocolList = ProtocolListBuilder.beginStruct();
3383 ProtocolList.add(NULLPtr);
3384 ProtocolList.addInt(LongTy, ExistingProtocols.size());
3385 auto ProtocolElements = ProtocolList.beginArray(PtrTy);
3386 for (
auto iter = ExistingProtocols.begin(), endIter = ExistingProtocols.end();
3387 iter != endIter ; iter++) {
3388 ProtocolElements.add(iter->getValue());
3390 ProtocolElements.finishAndAddTo(ProtocolList);
3391 Elements.add(ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
3393 Categories.push_back(
3409 int bitCount = bits.size();
3411 if (bitCount < ptrBits) {
3413 for (
int i=0 ; i<bitCount ; ++i) {
3414 if (bits[i]) val |= 1ULL<<(i+1);
3416 return llvm::ConstantInt::get(IntPtrTy, val);
3420 while (
v < bitCount) {
3422 for (
int i=0 ; (i<32) && (
v<bitCount) ; ++i) {
3423 if (bits[
v]) word |= 1<<i;
3426 values.push_back(llvm::ConstantInt::get(Int32Ty, word));
3430 auto fields = builder.beginStruct();
3431 fields.addInt(Int32Ty, values.size());
3432 auto array = fields.beginArray();
3433 for (
auto *
v : values) array.add(
v);
3434 array.finishAndAddTo(fields);
3436 llvm::Constant *GS =
3438 llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy);
3442llvm::Constant *CGObjCGNU::GenerateCategoryProtocolList(
const
3445 const auto RuntimeProtos =
3446 GetRuntimeProtocolList(RefPro.begin(), RefPro.end());
3448 for (
const auto *PD : RuntimeProtos)
3450 return GenerateProtocolList(Protocols);
3455 std::string ClassName =
Class->getNameAsString();
3462 auto Elements = Builder.beginStruct();
3463 Elements.add(MakeConstantString(CategoryName));
3464 Elements.add(MakeConstantString(ClassName));
3467 InstanceMethods.insert(InstanceMethods.begin(), OCD->
instmeth_begin(),
3470 GenerateMethodList(ClassName, CategoryName, InstanceMethods,
false));
3477 Elements.add(GenerateMethodList(ClassName, CategoryName, ClassMethods,
true));
3480 Elements.add(GenerateCategoryProtocolList(CatDecl));
3486 Elements.add(GeneratePropertyList(OCD,
Category,
false));
3488 Elements.add(GeneratePropertyList(OCD,
Category,
true));
3490 Elements.addNullPointer(PtrTy);
3491 Elements.addNullPointer(PtrTy);
3495 Categories.push_back(Elements.finishAndCreateGlobal(
3496 std::string(
".objc_category_") + ClassName + CategoryName,
3500llvm::Constant *CGObjCGNU::GeneratePropertyList(
const Decl *Container,
3502 bool isClassProperty,
3503 bool protocolOptionalProperties) {
3507 bool isProtocol = isa<ObjCProtocolDecl>(OCD);
3510 std::function<void(
const ObjCProtocolDecl *Proto)> collectProtocolProperties
3512 for (
const auto *
P : Proto->protocols())
3513 collectProtocolProperties(
P);
3514 for (
const auto *PD : Proto->properties()) {
3515 if (isClassProperty != PD->isClassProperty())
3523 Properties.push_back(PD);
3529 for (
auto *PD : ClassExt->properties()) {
3530 if (isClassProperty != PD->isClassProperty())
3533 Properties.push_back(PD);
3537 if (isClassProperty != PD->isClassProperty())
3541 if (isProtocol && (protocolOptionalProperties != PD->isOptional()))
3548 Properties.push_back(PD);
3553 collectProtocolProperties(
P);
3555 for (
const auto *
P : CD->protocols())
3556 collectProtocolProperties(
P);
3558 auto numProperties = Properties.size();
3560 if (numProperties == 0)
3564 auto propertyList = builder.beginStruct();
3565 auto properties = PushPropertyListHeader(propertyList, numProperties);
3569 for (
auto *property : Properties) {
3570 bool isSynthesized =
false;
3571 bool isDynamic =
false;
3575 isSynthesized = (propertyImpl->getPropertyImplementation() ==
3577 isDynamic = (propertyImpl->getPropertyImplementation() ==
3581 PushProperty(properties, property, Container, isSynthesized, isDynamic);
3583 properties.finishAndAddTo(propertyList);
3585 return propertyList.finishAndCreateGlobal(
".objc_property_list",
3603 std::string SuperClassName;
3604 if (SuperClassDecl) {
3606 EmitClassRef(SuperClassName);
3616 std::string classSymbolName =
"__objc_class_name_" + ClassName;
3617 if (
auto *symbol = TheModule.getGlobalVariable(classSymbolName)) {
3618 symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0));
3620 new llvm::GlobalVariable(TheModule, LongTy,
false,
3621 llvm::GlobalValue::ExternalLinkage,
3622 llvm::ConstantInt::get(LongTy, 0),
3638 auto IvarOffsetValues = IvarOffsetBuilder.beginArray(PtrToIntTy);
3642 int superInstanceSize = !SuperClassDecl ? 0 :
3647 instanceSize = 0 - (instanceSize - superInstanceSize);
3653 IvarNames.push_back(MakeConstantString(IVD->getNameAsString()));
3655 std::string TypeStr;
3657 IvarTypes.push_back(MakeConstantString(TypeStr));
3658 IvarAligns.push_back(llvm::ConstantInt::get(IntTy,
3661 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
3664 Offset = BaseOffset - superInstanceSize;
3666 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
3668 std::string OffsetName =
"__objc_ivar_offset_value_" + ClassName +
"." +
3669 IVD->getNameAsString();
3671 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
3673 OffsetVar->setInitializer(OffsetValue);
3677 OffsetVar->setLinkage(llvm::GlobalValue::ExternalLinkage);
3679 OffsetVar =
new llvm::GlobalVariable(TheModule, Int32Ty,
3680 false, llvm::GlobalValue::ExternalLinkage,
3681 OffsetValue, OffsetName);
3682 IvarOffsets.push_back(OffsetValue);
3683 IvarOffsetValues.add(OffsetVar);
3685 IvarOwnership.push_back(lt);
3688 StrongIvars.push_back(
true);
3689 WeakIvars.push_back(
false);
3692 StrongIvars.push_back(
false);
3693 WeakIvars.push_back(
true);
3696 StrongIvars.push_back(
false);
3697 WeakIvars.push_back(
false);
3700 llvm::Constant *StrongIvarBitmap = MakeBitField(StrongIvars);
3701 llvm::Constant *WeakIvarBitmap = MakeBitField(WeakIvars);
3702 llvm::GlobalVariable *IvarOffsetArray =
3703 IvarOffsetValues.finishAndCreateGlobal(
".ivar.offsets",
3708 InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
3715 llvm::Constant *Properties = GeneratePropertyList(OID, ClassDecl);
3718 auto RefProtocols = ClassDecl->
protocols();
3719 auto RuntimeProtocols =
3720 GetRuntimeProtocolList(RefProtocols.begin(), RefProtocols.end());
3722 for (
const auto *I : RuntimeProtocols)
3723 Protocols.push_back(I->getNameAsString());
3726 llvm::Constant *SuperClass;
3727 if (!SuperClassName.empty()) {
3728 SuperClass = MakeConstantString(SuperClassName,
".super_class_name");
3730 SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty);
3735 llvm::Constant *MethodList = GenerateMethodList(ClassName,
"",
3736 InstanceMethods,
false);
3737 llvm::Constant *ClassMethodList = GenerateMethodList(ClassName,
"",
3738 ClassMethods,
true);
3739 llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
3740 IvarOffsets, IvarAligns, IvarOwnership);
3751 llvm::Type *IndexTy = Int32Ty;
3752 llvm::Constant *offsetPointerIndexes[] = {Zeros[0],
3753 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 2 : 1),
nullptr,
3754 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 3 : 2) };
3756 unsigned ivarIndex = 0;
3759 const std::string Name = GetIVarOffsetVariableName(ClassDecl, IVD);
3760 offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, ivarIndex);
3762 llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr(
3763 cast<llvm::GlobalVariable>(IvarList)->getValueType(), IvarList,
3764 offsetPointerIndexes);
3766 llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name);
3768 offset->setInitializer(offsetValue);
3772 offset->setLinkage(llvm::GlobalValue::ExternalLinkage);
3775 new llvm::GlobalVariable(TheModule, offsetValue->getType(),
3776 false, llvm::GlobalValue::ExternalLinkage, offsetValue, Name);
3779 llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0);
3782 llvm::Constant *MetaClassStruct = GenerateClassStructure(
3783 NULLPtr, NULLPtr, 0x12L, ClassName.c_str(),
nullptr, Zeros[0],
3784 NULLPtr, ClassMethodList, NULLPtr, NULLPtr,
3785 GeneratePropertyList(OID, ClassDecl,
true), ZeroPtr, ZeroPtr,
true);
3790 llvm::Constant *ClassStruct = GenerateClassStructure(
3791 MetaClassStruct, SuperClass, 0x11L, ClassName.c_str(),
nullptr,
3792 llvm::ConstantInt::get(LongTy, instanceSize), IvarList, MethodList,
3793 GenerateProtocolList(Protocols), IvarOffsetArray, Properties,
3794 StrongIvarBitmap, WeakIvarBitmap);
3799 if (ClassPtrAlias) {
3800 ClassPtrAlias->replaceAllUsesWith(ClassStruct);
3801 ClassPtrAlias->eraseFromParent();
3802 ClassPtrAlias =
nullptr;
3804 if (MetaClassPtrAlias) {
3805 MetaClassPtrAlias->replaceAllUsesWith(MetaClassStruct);
3806 MetaClassPtrAlias->eraseFromParent();
3807 MetaClassPtrAlias =
nullptr;
3811 Classes.push_back(ClassStruct);
3814llvm::Function *CGObjCGNU::ModuleInitFunction() {
3816 if (Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
3821 GenerateProtocolHolderCategory();
3823 llvm::StructType *selStructTy = dyn_cast<llvm::StructType>(SelectorElemTy);
3826 { PtrToInt8Ty, PtrToInt8Ty });
3830 llvm::Constant *statics = NULLPtr;
3831 if (!ConstantStrings.empty()) {
3832 llvm::GlobalVariable *fileStatics = [&] {
3834 auto staticsStruct = builder.beginStruct();
3837 if (stringClass.empty()) stringClass =
"NXConstantString";
3838 staticsStruct.add(MakeConstantString(stringClass,
3839 ".objc_static_class_name"));
3841 auto array = staticsStruct.beginArray();
3842 array.addAll(ConstantStrings);
3844 array.finishAndAddTo(staticsStruct);
3846 return staticsStruct.finishAndCreateGlobal(
".objc_statics",
3851 auto allStaticsArray = builder.beginArray(fileStatics->getType());
3852 allStaticsArray.add(fileStatics);
3853 allStaticsArray.addNullPointer(fileStatics->getType());
3855 statics = allStaticsArray.finishAndCreateGlobal(
".objc_statics_ptr",
3862 unsigned selectorCount;
3865 llvm::GlobalVariable *selectorList = [&] {
3867 auto selectors = builder.beginArray(selStructTy);
3869 std::vector<Selector> allSelectors;
3870 for (
auto &entry : table)
3871 allSelectors.push_back(entry.first);
3872 llvm::sort(allSelectors);
3874 for (
auto &untypedSel : allSelectors) {
3875 std::string selNameStr = untypedSel.getAsString();
3876 llvm::Constant *selName = ExportUniqueString(selNameStr,
".objc_sel_name");
3878 for (TypedSelector &sel : table[untypedSel]) {
3879 llvm::Constant *selectorTypeEncoding = NULLPtr;
3880 if (!sel.first.empty())
3881 selectorTypeEncoding =
3882 MakeConstantString(sel.first,
".objc_sel_types");
3884 auto selStruct = selectors.beginStruct(selStructTy);
3885 selStruct.add(selName);
3886 selStruct.add(selectorTypeEncoding);
3887 selStruct.finishAndAddTo(selectors);
3890 selectorAliases.push_back(sel.second);
3895 selectorCount = selectors.size();
3901 auto selStruct = selectors.beginStruct(selStructTy);
3902 selStruct.add(NULLPtr);
3903 selStruct.add(NULLPtr);
3904 selStruct.finishAndAddTo(selectors);
3906 return selectors.finishAndCreateGlobal(
".objc_selector_list",
3911 for (
unsigned i = 0; i < selectorCount; ++i) {
3912 llvm::Constant *idxs[] = {
3914 llvm::ConstantInt::get(Int32Ty, i)
3917 llvm::Constant *selPtr = llvm::ConstantExpr::getGetElementPtr(
3918 selectorList->getValueType(), selectorList, idxs);
3919 selectorAliases[i]->replaceAllUsesWith(selPtr);
3920 selectorAliases[i]->eraseFromParent();
3923 llvm::GlobalVariable *symtab = [&] {
3925 auto symtab = builder.beginStruct();
3928 symtab.addInt(LongTy, selectorCount);
3930 symtab.add(selectorList);
3933 symtab.addInt(CGM.
Int16Ty, Classes.size());
3935 symtab.addInt(CGM.
Int16Ty, Categories.size());
3938 auto classList = symtab.beginArray(PtrToInt8Ty);
3939 classList.addAll(Classes);
3940 classList.addAll(Categories);
3942 classList.add(statics);
3943 classList.add(NULLPtr);
3944 classList.finishAndAddTo(symtab);
3952 llvm::Constant *module = [&] {
3953 llvm::Type *moduleEltTys[] = {
3954 LongTy, LongTy, PtrToInt8Ty, symtab->getType(), IntTy
3956 llvm::StructType *moduleTy = llvm::StructType::get(
3958 ArrayRef(moduleEltTys).drop_back(
unsigned(RuntimeVersion < 10)));
3961 auto module = builder.beginStruct(moduleTy);
3963 module.addInt(LongTy, RuntimeVersion);
3965 module.addInt(LongTy, CGM.
getDataLayout().getTypeStoreSize(moduleTy));
3972 module.add(MakeConstantString(path,
".objc_source_file_name"));
3975 if (RuntimeVersion >= 10) {
3977 case LangOptions::GCOnly:
3978 module.addInt(IntTy, 2);
3980 case LangOptions::NonGC:
3982 module.addInt(IntTy, 1);
3984 module.addInt(IntTy, 0);
3986 case LangOptions::HybridGC:
3987 module.addInt(IntTy, 1);
3997 llvm::Function * LoadFunction = llvm::Function::Create(
3998 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
3999 llvm::GlobalValue::InternalLinkage,
".objc_load_function",
4001 llvm::BasicBlock *EntryBB =
4002 llvm::BasicBlock::Create(VMContext,
"entry", LoadFunction);
4004 Builder.SetInsertPoint(EntryBB);
4006 llvm::FunctionType *FT =
4007 llvm::FunctionType::get(Builder.getVoidTy(), module->getType(),
true);
4008 llvm::FunctionCallee Register =
4010 Builder.CreateCall(Register, module);
4012 if (!ClassAliases.empty()) {
4013 llvm::Type *ArgTypes[2] = {PtrTy, PtrToInt8Ty};
4014 llvm::FunctionType *RegisterAliasTy =
4015 llvm::FunctionType::get(Builder.getVoidTy(),
4017 llvm::Function *RegisterAlias = llvm::Function::Create(
4019 llvm::GlobalValue::ExternalWeakLinkage,
"class_registerAlias_np",
4021 llvm::BasicBlock *AliasBB =
4022 llvm::BasicBlock::Create(VMContext,
"alias", LoadFunction);
4023 llvm::BasicBlock *NoAliasBB =
4024 llvm::BasicBlock::Create(VMContext,
"no_alias", LoadFunction);
4027 llvm::Value *HasRegisterAlias = Builder.CreateICmpNE(RegisterAlias,
4028 llvm::Constant::getNullValue(RegisterAlias->getType()));
4029 Builder.CreateCondBr(HasRegisterAlias, AliasBB, NoAliasBB);
4032 Builder.SetInsertPoint(AliasBB);
4034 for (std::vector<ClassAliasPair>::iterator iter = ClassAliases.begin();
4035 iter != ClassAliases.end(); ++iter) {
4036 llvm::Constant *TheClass =
4037 TheModule.getGlobalVariable(
"_OBJC_CLASS_" + iter->first,
true);
4039 Builder.CreateCall(RegisterAlias,
4040 {TheClass, MakeConstantString(iter->second)});
4044 Builder.CreateBr(NoAliasBB);
4047 Builder.SetInsertPoint(NoAliasBB);
4049 Builder.CreateRetVoid();
4051 return LoadFunction;
4054llvm::Function *CGObjCGNU::GenerateMethod(
const ObjCMethodDecl *OMD,
4057 llvm::FunctionType *MethodTy =
4058 Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
4061 std::string FunctionName =
4062 getSymbolNameForMethod(OMD, !isDirect);
4065 return llvm::Function::Create(MethodTy,
4066 llvm::GlobalVariable::InternalLinkage,
4067 FunctionName, &TheModule);
4070 auto I = DirectMethodDefinitions.find(COMD);
4071 llvm::Function *OldFn =
nullptr, *Fn =
nullptr;
4073 if (I == DirectMethodDefinitions.end()) {
4075 llvm::Function::Create(MethodTy, llvm::GlobalVariable::ExternalLinkage,
4076 FunctionName, &TheModule);
4077 DirectMethodDefinitions.insert(std::make_pair(COMD, F));
4094 Fn = llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,
"",
4096 Fn->takeName(OldFn);
4097 OldFn->replaceAllUsesWith(Fn);
4098 OldFn->eraseFromParent();
4112llvm::FunctionCallee CGObjCGNU::GetPropertyGetFunction() {
4113 return GetPropertyFn;
4116llvm::FunctionCallee CGObjCGNU::GetPropertySetFunction() {
4117 return SetPropertyFn;
4120llvm::FunctionCallee CGObjCGNU::GetOptimizedPropertySetFunction(
bool atomic,
4125llvm::FunctionCallee CGObjCGNU::GetGetStructFunction() {
4126 return GetStructPropertyFn;
4129llvm::FunctionCallee CGObjCGNU::GetSetStructFunction() {
4130 return SetStructPropertyFn;
4133llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectGetFunction() {
4137llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectSetFunction() {
4141llvm::FunctionCallee CGObjCGNU::EnumerationMutationFunction() {
4142 return EnumerationMutationFn;
4147 EmitAtSynchronizedStmt(CGF, S, SyncEnterFn, SyncExitFn);
4164 EmitTryCatchStmt(CGF, S, EnterCatchFn, ExitCatchFn, ExceptionReThrowFn);
4169 bool ClearInsertionPoint) {
4170 llvm::Value *ExceptionAsObject;
4171 bool isRethrow =
false;
4173 if (
const Expr *ThrowExpr = S.getThrowExpr()) {
4175 ExceptionAsObject = Exception;
4178 "Unexpected rethrow outside @catch block.");
4182 if (isRethrow && (usesSEHExceptions || usesCxxExceptions)) {
4191 Throw->setDoesNotReturn();
4193 ExceptionAsObject = CGF.
Builder.CreateBitCast(ExceptionAsObject, IdTy);
4194 llvm::CallBase *Throw =
4196 Throw->setDoesNotReturn();
4198 CGF.
Builder.CreateUnreachable();
4199 if (ClearInsertionPoint)
4200 CGF.
Builder.ClearInsertionPoint();
4206 return B.CreateCall(
4207 WeakReadFn, EnforceType(B, AddrWeakObj.
emitRawPointer(CGF), PtrToIdTy));
4211 llvm::Value *src,
Address dst) {
4213 src = EnforceType(B, src, IdTy);
4214 llvm::Value *dstVal = EnforceType(B, dst.
emitRawPointer(CGF), PtrToIdTy);
4215 B.CreateCall(WeakAssignFn, {src, dstVal});
4219 llvm::Value *src,
Address dst,
4222 src = EnforceType(B, src, IdTy);
4223 llvm::Value *dstVal = EnforceType(B, dst.
emitRawPointer(CGF), PtrToIdTy);
4225 assert(!threadlocal &&
"EmitObjCGlobalAssign - Threal Local API NYI");
4226 B.CreateCall(GlobalAssignFn, {src, dstVal});
4230 llvm::Value *src,
Address dst,
4231 llvm::Value *ivarOffset) {
4233 src = EnforceType(B, src, IdTy);
4234 llvm::Value *dstVal = EnforceType(B, dst.
emitRawPointer(CGF), IdTy);
4235 B.CreateCall(IvarAssignFn, {src, dstVal, ivarOffset});
4239 llvm::Value *src,
Address dst) {
4241 src = EnforceType(B, src, IdTy);
4242 llvm::Value *dstVal = EnforceType(B, dst.
emitRawPointer(CGF), PtrToIdTy);
4243 B.CreateCall(StrongCastAssignFn, {src, dstVal});
4249 llvm::Value *Size) {
4251 llvm::Value *DestPtrVal = EnforceType(B, DestPtr.
emitRawPointer(CGF), PtrTy);
4252 llvm::Value *SrcPtrVal = EnforceType(B, SrcPtr.
emitRawPointer(CGF), PtrTy);
4254 B.CreateCall(MemMoveFn, {DestPtrVal, SrcPtrVal,
Size});
4257llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
4260 const std::string Name = GetIVarOffsetVariableName(ID, Ivar);
4264 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
4265 if (!IvarOffsetPointer)
4266 IvarOffsetPointer =
new llvm::GlobalVariable(
4267 TheModule, llvm::PointerType::getUnqual(VMContext),
false,
4268 llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
4269 return IvarOffsetPointer;
4274 llvm::Value *BaseValue,
4276 unsigned CVRQualifiers) {
4279 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
4280 EmitIvarOffset(CGF, ID, Ivar));
4308 if (RuntimeVersion < 10 ||
4310 return CGF.
Builder.CreateZExtOrBitCast(
4314 llvm::PointerType::getUnqual(VMContext),
4315 ObjCIvarOffsetVariable(
Interface, Ivar),
4319 std::string
name =
"__objc_ivar_offset_value_" +
4322 llvm::Value *Offset = TheModule.getGlobalVariable(name);
4324 auto GV =
new llvm::GlobalVariable(TheModule, IntTy,
4325 false, llvm::GlobalValue::LinkOnceAnyLinkage,
4326 llvm::Constant::getNullValue(IntTy), name);
4331 if (Offset->getType() != PtrDiffTy)
4332 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
4336 return llvm::ConstantInt::get(PtrDiffTy, Offset,
true);
4342 switch (Runtime.getKind()) {
4344 if (Runtime.getVersion() >= VersionTuple(2, 0))
4345 return new CGObjCGNUstep2(CGM);
4346 return new CGObjCGNUstep(CGM);
4349 return new CGObjCGCC(CGM);
4352 return new CGObjCObjFW(CGM);
4358 llvm_unreachable(
"these runtimes are not GNU runtimes");
4360 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 clang::FileManager interface and associated types.
Defines the SourceManager interface.
Defines the Objective-C statement AST node classes.
__device__ __2f16 float __ockl_bool s
__device__ __2f16 float c
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
TranslationUnitDecl * getTranslationUnitDecl() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
void getObjCEncodingForType(QualType T, std::string &S, const FieldDecl *Field=nullptr, QualType *NotEncodedT=nullptr) const
Emit the Objective-CC type encoding for the given type T into S.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
std::string getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, bool Extended=false) const
Emit the encoded type for the method declaration Decl into S.
std::string getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD, const Decl *Container) const
getObjCEncodingForPropertyDecl - Return the encoded type for this method declaration.
const ASTRecordLayout & getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const
Get or compute information about the layout of the specified Objective-C implementation.
const ASTRecordLayout & getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const
Get or compute information about the layout of the specified Objective-C interface.
QualType getObjCProtoType() const
Retrieve the type of the Objective-C Protocol class.
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
ObjCPropertyImplDecl * getObjCPropertyImplDeclForPropertyDecl(const ObjCPropertyDecl *PD, const Decl *Container) const
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
QualType getObjCIdType() const
Represents the Objective-CC id type.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
void getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT, QualType T, std::string &S, bool Extended) const
getObjCEncodingForMethodParameter - Return the encoded type for a single method parameter or return t...
const TargetInfo & getTargetInfo() const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
CharUnits getSize() const
getSize - Get the record size in characters.
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
CharUnits - This is an opaque type for sizes expressed in character units.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
CGBlockInfo - Information to generate a block literal.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
virtual llvm::Constant * getAddrOfRTTIDescriptor(QualType Ty)=0
virtual CatchTypeInfo getCatchAllTypeInfo()
Abstract information about a function or function prototype.
All available information about a concrete callee.
Implements runtime-specific code generation functions.
virtual llvm::Constant * GetEHType(QualType T)=0
Get the type constant to catch for the given ObjC pointer type.
virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest, llvm::Value *ivarOffset)=0
virtual llvm::FunctionCallee GetCppAtomicObjectGetFunction()=0
API for atomic copying of qualified aggregates with non-trivial copy assignment (c++) in getter.
virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest)=0
virtual llvm::Constant * BuildByrefLayout(CodeGen::CodeGenModule &CGM, QualType T)=0
Returns an i8* which points to the byref layout information.
virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, Address DestPtr, Address SrcPtr, llvm::Value *Size)=0
virtual llvm::FunctionCallee GetPropertySetFunction()=0
Return the runtime function for setting properties.
virtual llvm::FunctionCallee GetCppAtomicObjectSetFunction()=0
API for atomic copying of qualified aggregates with non-trivial copy assignment (c++) in setter.
virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtTryStmt &S)=0
virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, ReturnValueSlot ReturnSlot, QualType ResultType, Selector Sel, llvm::Value *Receiver, const CallArgList &CallArgs, const ObjCInterfaceDecl *Class=nullptr, const ObjCMethodDecl *Method=nullptr)=0
Generate an Objective-C message send operation.
virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy, llvm::Value *BaseValue, const ObjCIvarDecl *Ivar, unsigned CVRQualifiers)=0
virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD)=0
Register an class alias.
virtual void GenerateCategory(const ObjCCategoryImplDecl *OCD)=0
Generate a category.
virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S, bool ClearInsertionPoint=true)=0
virtual llvm::Value * EmitIvarOffset(CodeGen::CodeGenFunction &CGF, const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar)=0
virtual llvm::Function * GenerateMethod(const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD)=0
Generate a function preamble for a method with the specified types.
virtual llvm::Value * GenerateProtocolRef(CodeGenFunction &CGF, const ObjCProtocolDecl *OPD)=0
Emit the code to return the named protocol as an object, as in a @protocol expression.
virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, Address AddrWeakObj)=0
virtual llvm::Function * ModuleInitFunction()=0
Generate the function required to register all Objective-C components in this compilation unit with t...
virtual CodeGen::RValue GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, ReturnValueSlot ReturnSlot, QualType ResultType, Selector Sel, const ObjCInterfaceDecl *Class, bool isCategoryImpl, llvm::Value *Self, bool IsClassMessage, const CallArgList &CallArgs, const ObjCMethodDecl *Method=nullptr)=0
Generate an Objective-C message send operation to the super class initiated in a method for Class and...
virtual void GenerateClass(const ObjCImplementationDecl *OID)=0
Generate a class structure for this class.
virtual llvm::FunctionCallee EnumerationMutationFunction()=0
EnumerationMutationFunction - Return the function that's called by the compiler when a mutation is de...
virtual llvm::Constant * BuildGCBlockLayout(CodeGen::CodeGenModule &CGM, const CodeGen::CGBlockInfo &blockInfo)=0
virtual llvm::FunctionCallee GetGetStructFunction()=0
virtual llvm::Constant * GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0
GetOrEmitProtocol - Get the protocol object for the given declaration, emitting it if necessary.
virtual ConstantAddress GenerateConstantString(const StringLiteral *)=0
Generate a constant string object.
virtual llvm::Value * GetClass(CodeGenFunction &CGF, const ObjCInterfaceDecl *OID)=0
GetClass - Return a reference to the class for the given interface decl.
virtual void GenerateProtocol(const ObjCProtocolDecl *OPD)=0
Generate the named protocol.
virtual llvm::Constant * BuildRCBlockLayout(CodeGen::CodeGenModule &CGM, const CodeGen::CGBlockInfo &blockInfo)=0
virtual llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic, bool copy)=0
Return the runtime function for optimized setting properties.
virtual llvm::Value * GetSelector(CodeGenFunction &CGF, Selector Sel)=0
Get a selector for the specified name and type values.
virtual void GenerateDirectMethodPrologue(CodeGenFunction &CGF, llvm::Function *Fn, const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD)=0
Generates prologue for direct Objective-C Methods.
virtual Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel)=0
Get the address of a selector for the specified name and type values.
virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest)=0
virtual llvm::Value * EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF)
virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest, bool threadlocal=false)=0
virtual llvm::FunctionCallee GetPropertyGetFunction()=0
Return the runtime function for getting properties.
virtual llvm::FunctionCallee GetSetStructFunction()=0
virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S)=0
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
void addFrom(const CallArgList &other)
Add all the arguments from another CallArgList to this one.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
SmallVector< llvm::Value *, 8 > ObjCEHValueStack
ObjCEHValueStack - Stack of Objective-C exception values, used for rethrows.
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **callOrInvoke, bool IsMustTail, SourceLocation Loc)
EmitCall - Generate a call of the given function, expecting the given result type,...
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
JumpDest ReturnBlock
ReturnBlock - Unified return block.
llvm::Value * EmitObjCThrowOperand(const Expr *expr)
llvm::Value * LoadObjCSelf()
LoadObjCSelf - Load the value of self.
void EmitVarDecl(const VarDecl &D)
EmitVarDecl - Emit a local variable declaration.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
static bool hasAggregateEvaluationKind(QualType T)
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
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
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.
bool isZeroInitializable(QualType T)
IsZeroInitializable - Return whether a type can be zero-initialized (in the C++ sense) with an LLVM z...
llvm::Type * ConvertTypeForMem(QualType T, bool ForBitField=false)
ConvertTypeForMem - Convert type T into a llvm::Type.
A specialization of Address that requires the address to be an LLVM Constant.
ArrayBuilder beginArray(llvm::Type *eltTy=nullptr)
llvm::GlobalVariable * finishAndCreateGlobal(As &&...args)
Given that this builder was created by beginning an array or struct directly on a ConstantInitBuilder...
StructBuilder beginStruct(llvm::StructType *ty=nullptr)
void finishAndAddTo(AggregateBuilderBase &parent)
Given that this builder was created by beginning an array or struct component on the given parent bui...
A helper class of ConstantInitBuilder, used for building constant array initializers.
The standard implementation of ConstantInitBuilder used in Clang.
A helper class of ConstantInitBuilder, used for building constant struct initializers.
LValue - This represents an lvalue references.
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
An abstract representation of an aligned address.
llvm::Value * getPointer() const
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
Decl - This represents one declaration (or definition), e.g.
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
StringRef getName() const
This represents one expression.
StringRef getName() const
The name of this FileEntry.
DirectoryEntryRef getDir() const
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
std::string ObjCConstantStringClass
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Visibility getVisibility() const
Determines the visibility of this entity.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
Represents Objective-C's @synchronized statement.
Represents Objective-C's @throw statement.
Represents Objective-C's @try ... @catch ... @finally statement.
ObjCCategoryDecl - Represents a category declaration.
const ObjCProtocolList & getReferencedProtocols() const
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
ObjCCategoryDecl * getCategoryDecl() const
ObjCCompatibleAliasDecl - Represents alias of a class.
const ObjCInterfaceDecl * getClassInterface() const
ObjCContainerDecl - Represents a container for method declarations.
classmeth_iterator classmeth_end() const
classmeth_iterator classmeth_begin() const
instmeth_range instance_methods() const
instmeth_iterator instmeth_end() const
instmeth_iterator instmeth_begin() const
prop_range properties() const
classmeth_range class_methods() const
propimpl_range property_impls() const
const ObjCInterfaceDecl * getClassInterface() const
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Represents an ObjC class declaration.
all_protocol_range all_referenced_protocols() const
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
protocol_range protocols() const
protocol_iterator protocol_end() const
protocol_iterator protocol_begin() const
ObjCInterfaceDecl * getSuperClass() const
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
known_extensions_range known_extensions() const
Interfaces are the core concept in Objective-C for object oriented design.
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
ObjCIvarDecl - Represents an ObjC instance variable.
ObjCInterfaceDecl * getContainingInterface()
Return the class interface that this ivar is logically contained in; this is either the interface whe...
ObjCIvarDecl * getNextIvar()
ObjCMethodDecl - Represents an instance or class method declaration.
ImplicitParamDecl * getSelfDecl() const
bool hasParamDestroyedInCallee() const
True if the method has a parameter that's destroyed in the callee.
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
ObjCMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Selector getSelector() const
ImplicitParamDecl * getCmdDecl() const
QualType getReturnType() const
bool isClassMethod() const
ObjCInterfaceDecl * getClassInterface()
Represents a pointer to an Objective C object.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
const ObjCInterfaceType * getInterfaceType() const
If this pointer points to an Objective C @interface type, gets the type for that interface.
Represents a class type in Objective C.
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface.
Represents one property declaration in an Objective-C interface.
ObjCMethodDecl * getGetterMethodDecl() const
ObjCMethodDecl * getSetterMethodDecl() const
Represents an Objective-C protocol declaration.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
bool isNonRuntimeProtocol() const
This is true iff the protocol is tagged with the objc_non_runtime_protocol attribute.
protocol_iterator protocol_begin() const
protocol_range protocols() const
protocol_iterator protocol_end() const
The basic abstraction for the target Objective-C runtime.
const VersionTuple & getVersion() const
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
Kind
The basic Objective-C runtimes that we know about.
@ MacOSX
'macosx' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the non-fragile AB...
@ FragileMacOSX
'macosx-fragile' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the fragil...
@ GNUstep
'gnustep' is the modern non-fragile GNUstep runtime.
@ ObjFW
'objfw' is the Objective-C runtime included in ObjFW
@ iOS
'ios' is the Apple-provided NeXT-derived runtime on iOS or the iOS simulator; it is always non-fragil...
@ GCC
'gcc' is the Objective-C runtime shipped with GCC, implementing a fragile Objective-C ABI
@ WatchOS
'watchos' is a variant of iOS for Apple's watchOS.
A (possibly-)qualified type.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
This table allows us to fully hide how we implement multi-keyword caching.
Smart pointer class that efficiently represents Objective-C method names.
std::string getAsString() const
Derive the full selector name (e.g.
This class handles loading and caching of source files into memory.
StringLiteral - This represents a string literal expression, e.g.
bool containsNonAscii() const
unsigned getLength() const
uint32_t getCodeUnit(size_t i) const
StringRef getString() const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
The top declaration context.
static DeclContext * castToDeclContext(const TranslationUnitDecl *D)
const T * castAs() const
Member-template castAs<specific type>.
bool isObjCQualifiedIdType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isObjCIdType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
Represents a variable declaration or definition.
CGObjCRuntime * CreateGNUObjCRuntime(CodeGenModule &CGM)
Creates an instance of an Objective-C runtime class.
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
bool Zero(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
const FunctionProtoType * T
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ HiddenVisibility
Objects with "hidden" visibility are not seen by the dynamic linker.
The MS C++ ABI needs a pointer to RTTI data plus some flags to describe the type of a catch handler,...
CharUnits getIntAlign() const
llvm::IntegerType * Int16Ty
llvm::PointerType * Int8PtrTy
CharUnits getPointerAlign() const