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 Array.getPointer();
209 llvm::Constant *ExportUniqueString(
const std::string &Str,
210 const std::string &prefix,
211 bool Private=
false) {
212 std::string
name = prefix + Str;
213 auto *ConstStr = TheModule.getGlobalVariable(name);
215 llvm::Constant *value = llvm::ConstantDataArray::getString(VMContext,Str);
216 auto *GV =
new llvm::GlobalVariable(TheModule, value->getType(),
true,
217 llvm::GlobalValue::LinkOnceODRLinkage, value, name);
218 GV->setComdat(TheModule.getOrInsertComdat(name));
220 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
228 const Decl *Container) {
231 std::string NameAndAttributes;
232 std::string TypeStr =
234 NameAndAttributes +=
'\0';
235 NameAndAttributes += TypeStr.length() + 3;
236 NameAndAttributes += TypeStr;
237 NameAndAttributes +=
'\0';
239 return MakeConstantString(NameAndAttributes);
248 int attrs =
property->getPropertyAttributes();
251 attrs &= ~ObjCPropertyAttribute::kind_copy;
252 attrs &= ~ObjCPropertyAttribute::kind_retain;
253 attrs &= ~ObjCPropertyAttribute::kind_weak;
254 attrs &= ~ObjCPropertyAttribute::kind_strong;
257 Fields.addInt(Int8Ty, attrs & 0xff);
263 attrs |= isSynthesized ? (1<<0) : 0;
264 attrs |= isDynamic ? (1<<1) : 0;
267 Fields.addInt(Int8Ty, attrs & 0xff);
269 Fields.addInt(Int8Ty, 0);
270 Fields.addInt(Int8Ty, 0);
273 virtual llvm::Constant *GenerateCategoryProtocolList(
const
278 Fields.addInt(IntTy, count);
281 const llvm::DataLayout &DL = TheModule.getDataLayout();
282 Fields.addInt(IntTy, DL.getTypeSizeInBits(PropertyMetadataTy) /
293 bool isSynthesized=
true,
bool
295 auto Fields = PropertiesArray.
beginStruct(PropertyMetadataTy);
297 Fields.add(MakePropertyEncodingString(property, OCD));
298 PushPropertyAttributes(Fields, property, isSynthesized, isDynamic);
302 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
303 Fields.add(MakeConstantString(accessor->getSelector().getAsString()));
304 Fields.add(TypeEncoding);
318 llvm::Value *EnforceType(
CGBuilderTy &B, llvm::Value *
V, llvm::Type *Ty) {
319 if (
V->getType() == Ty)
321 return B.CreateBitCast(
V, Ty);
325 llvm::Constant *Zeros[2];
327 llvm::Constant *NULLPtr;
329 llvm::LLVMContext &VMContext;
337 llvm::GlobalAlias *ClassPtrAlias;
342 llvm::GlobalAlias *MetaClassPtrAlias;
344 std::vector<llvm::Constant*> Classes;
346 std::vector<llvm::Constant*> Categories;
349 std::vector<llvm::Constant*> ConstantStrings;
353 llvm::StringMap<llvm::Constant*> ObjCStrings;
355 llvm::StringMap<llvm::Constant*> ExistingProtocols;
361 typedef std::pair<std::string, llvm::GlobalAlias*> TypedSelector;
365 typedef llvm::DenseMap<Selector, SmallVector<TypedSelector, 2> >
373 Selector RetainSel, ReleaseSel, AutoreleaseSel;
377 LazyRuntimeFunction IvarAssignFn, StrongCastAssignFn, MemMoveFn, WeakReadFn,
378 WeakAssignFn, GlobalAssignFn;
380 typedef std::pair<std::string, std::string> ClassAliasPair;
382 std::vector<ClassAliasPair> ClassAliases;
386 LazyRuntimeFunction ExceptionThrowFn;
389 LazyRuntimeFunction ExceptionReThrowFn;
392 LazyRuntimeFunction EnterCatchFn;
395 LazyRuntimeFunction ExitCatchFn;
397 LazyRuntimeFunction SyncEnterFn;
399 LazyRuntimeFunction SyncExitFn;
404 LazyRuntimeFunction EnumerationMutationFn;
407 LazyRuntimeFunction GetPropertyFn;
410 LazyRuntimeFunction SetPropertyFn;
412 LazyRuntimeFunction GetStructPropertyFn;
414 LazyRuntimeFunction SetStructPropertyFn;
426 const int ProtocolVersion;
429 const int ClassABIVersion;
445 llvm::Constant *GenerateMethodList(StringRef ClassName,
446 StringRef CategoryName,
448 bool isClassMethodList);
453 virtual llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName);
457 llvm::Constant *GeneratePropertyList(
const Decl *Container,
459 bool isClassProperty=
false,
460 bool protocolOptionalProperties=
false);
470 void GenerateProtocolHolderCategory();
473 llvm::Constant *GenerateClassStructure(
474 llvm::Constant *MetaClass,
475 llvm::Constant *SuperClass,
478 llvm::Constant *Version,
479 llvm::Constant *InstanceSize,
480 llvm::Constant *IVars,
481 llvm::Constant *Methods,
482 llvm::Constant *Protocols,
483 llvm::Constant *IvarOffsets,
484 llvm::Constant *Properties,
485 llvm::Constant *StrongIvarBitmap,
486 llvm::Constant *WeakIvarBitmap,
491 virtual llvm::Constant *GenerateProtocolMethodList(
495 void EmitProtocolMethodList(
T &&Methods, llvm::Constant *&
Required,
499 for (
const auto *I : Methods)
501 OptionalMethods.push_back(I);
503 RequiredMethods.push_back(I);
504 Required = GenerateProtocolMethodList(RequiredMethods);
505 Optional = GenerateProtocolMethodList(OptionalMethods);
511 const std::string &TypeEncoding);
518 const std::string Name =
"__objc_ivar_offset_" +
ID->getNameAsString()
527 void EmitClassRef(
const std::string &className);
531 const std::string &Name,
bool isWeak);
537 llvm::Value *&Receiver,
540 MessageSendInfo &MSI) = 0;
548 MessageSendInfo &MSI) = 0;
565 unsigned protocolClassVersion,
unsigned classABI=1);
572 llvm::Value *Receiver,
const CallArgList &CallArgs,
579 bool isCategoryImpl, llvm::Value *Receiver,
588 virtual llvm::Constant *GetConstantSelector(
Selector Sel,
589 const std::string &TypeEncoding) {
590 llvm_unreachable(
"Runtime unable to generate constant selector");
602 llvm::DenseMap<const ObjCMethodDecl *, llvm::Function *>
603 DirectMethodDefinitions;
637 bool ClearInsertionPoint=
true)
override;
641 llvm::Value *src,
Address dst)
override;
643 llvm::Value *src,
Address dest,
644 bool threadlocal=
false)
override;
646 Address dest, llvm::Value *ivarOffset)
override;
648 llvm::Value *src,
Address dest)
override;
651 llvm::Value *Size)
override;
654 unsigned CVRQualifiers)
override;
681class CGObjCGCC :
public CGObjCGNU {
684 LazyRuntimeFunction MsgLookupFn;
688 LazyRuntimeFunction MsgLookupSuperFn;
692 llvm::Value *cmd, llvm::MDNode *node,
693 MessageSendInfo &MSI)
override {
695 llvm::Value *args[] = {
696 EnforceType(Builder, Receiver, IdTy),
697 EnforceType(Builder, cmd, SelectorTy) };
699 imp->setMetadata(msgSendMDKind, node);
704 llvm::Value *cmd, MessageSendInfo &MSI)
override {
706 llvm::Value *lookupArgs[] = {
707 EnforceType(Builder, ObjCSuper.
emitRawPointer(CGF), PtrToObjCSuperTy),
715 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
717 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
718 PtrToObjCSuperTy, SelectorTy);
723class CGObjCGNUstep :
public CGObjCGNU {
726 LazyRuntimeFunction SlotLookupFn;
731 LazyRuntimeFunction SlotLookupSuperFn;
733 LazyRuntimeFunction SetPropertyAtomic;
735 LazyRuntimeFunction SetPropertyAtomicCopy;
737 LazyRuntimeFunction SetPropertyNonAtomic;
739 LazyRuntimeFunction SetPropertyNonAtomicCopy;
742 LazyRuntimeFunction CxxAtomicObjectGetFn;
745 LazyRuntimeFunction CxxAtomicObjectSetFn;
750 llvm::Type *SlotStructTy;
753 llvm::Constant *GetEHType(
QualType T)
override;
757 llvm::Value *cmd, llvm::MDNode *node,
758 MessageSendInfo &MSI)
override {
760 llvm::FunctionCallee LookupFn = SlotLookupFn;
765 Builder.CreateStore(Receiver, ReceiverPtr);
772 self = llvm::ConstantPointerNull::get(IdTy);
776 if (
auto *LookupFn2 = dyn_cast<llvm::Function>(LookupFn.getCallee()))
777 LookupFn2->addParamAttr(0, llvm::Attribute::NoCapture);
779 llvm::Value *args[] = {
780 EnforceType(Builder, ReceiverPtr.
getPointer(), PtrToIdTy),
781 EnforceType(Builder, cmd, SelectorTy),
782 EnforceType(Builder, self, IdTy)};
784 slot->setOnlyReadsMemory();
785 slot->setMetadata(msgSendMDKind, node);
788 llvm::Value *imp = Builder.CreateAlignedLoad(
789 IMPTy, Builder.CreateStructGEP(SlotStructTy, slot, 4),
794 Receiver = Builder.CreateLoad(ReceiverPtr,
true);
800 MessageSendInfo &MSI)
override {
804 llvm::CallInst *slot =
806 slot->setOnlyReadsMemory();
808 return Builder.CreateAlignedLoad(
809 IMPTy, Builder.CreateStructGEP(SlotStructTy, slot, 4),
814 CGObjCGNUstep(
CodeGenModule &Mod) : CGObjCGNUstep(Mod, 9, 3, 1) {}
815 CGObjCGNUstep(
CodeGenModule &Mod,
unsigned ABI,
unsigned ProtocolABI,
817 CGObjCGNU(Mod, ABI, ProtocolABI, ClassABI) {
820 SlotStructTy = llvm::StructType::get(PtrTy, PtrTy, PtrTy, IntTy, IMPTy);
821 SlotTy = llvm::PointerType::getUnqual(SlotStructTy);
823 SlotLookupFn.init(&CGM,
"objc_msg_lookup_sender", SlotTy, PtrToIdTy,
826 SlotLookupSuperFn.init(&CGM,
"objc_slot_lookup_super", SlotTy,
827 PtrToObjCSuperTy, SelectorTy);
829 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
830 if (usesCxxExceptions) {
832 EnterCatchFn.init(&CGM,
"__cxa_begin_catch", PtrTy, PtrTy);
834 ExitCatchFn.init(&CGM,
"__cxa_end_catch", VoidTy);
836 ExceptionReThrowFn.init(&CGM,
"__cxa_rethrow", PtrTy);
837 }
else if (usesSEHExceptions) {
839 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy);
842 EnterCatchFn.init(&CGM,
"__cxa_begin_catch", PtrTy, PtrTy);
844 ExitCatchFn.init(&CGM,
"__cxa_end_catch", VoidTy);
846 ExceptionReThrowFn.init(&CGM,
"_Unwind_Resume_or_Rethrow", VoidTy,
848 }
else if (R.
getVersion() >= VersionTuple(1, 7)) {
850 EnterCatchFn.init(&CGM,
"objc_begin_catch", IdTy, PtrTy);
852 ExitCatchFn.init(&CGM,
"objc_end_catch", VoidTy);
854 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy, PtrTy);
856 SetPropertyAtomic.init(&CGM,
"objc_setProperty_atomic", VoidTy, IdTy,
857 SelectorTy, IdTy, PtrDiffTy);
858 SetPropertyAtomicCopy.init(&CGM,
"objc_setProperty_atomic_copy", VoidTy,
859 IdTy, SelectorTy, IdTy, PtrDiffTy);
860 SetPropertyNonAtomic.init(&CGM,
"objc_setProperty_nonatomic", VoidTy,
861 IdTy, SelectorTy, IdTy, PtrDiffTy);
862 SetPropertyNonAtomicCopy.init(&CGM,
"objc_setProperty_nonatomic_copy",
863 VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy);
866 CxxAtomicObjectSetFn.init(&CGM,
"objc_setCppObjectAtomic", VoidTy, PtrTy,
870 CxxAtomicObjectGetFn.init(&CGM,
"objc_getCppObjectAtomic", VoidTy, PtrTy,
874 llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override {
879 return CxxAtomicObjectGetFn;
882 llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override {
887 return CxxAtomicObjectSetFn;
890 llvm::FunctionCallee GetOptimizedPropertySetFunction(
bool atomic,
891 bool copy)
override {
895 assert ((CGM.
getLangOpts().getGC() == LangOptions::NonGC));
902 if (copy)
return SetPropertyAtomicCopy;
903 return SetPropertyAtomic;
906 return copy ? SetPropertyNonAtomicCopy : SetPropertyNonAtomic;
913class CGObjCGNUstep2 :
public CGObjCGNUstep {
918 ClassReferenceSection,
921 ProtocolReferenceSection,
923 ConstantStringSection
928 ClassFlagMeta = (1 << 0),
931 ClassFlagInitialized = (1 << 8),
933 static const char *
const SectionsBaseNames[8];
934 static const char *
const PECOFFSectionsBaseNames[8];
935 template<SectionKind K>
936 std::string sectionName() {
937 if (CGM.
getTriple().isOSBinFormatCOFF()) {
938 std::string
name(PECOFFSectionsBaseNames[K]);
942 return SectionsBaseNames[K];
947 LazyRuntimeFunction MsgLookupSuperFn;
949 LazyRuntimeFunction SentInitializeFn;
953 bool EmittedProtocol =
false;
958 bool EmittedProtocolRef =
false;
962 bool EmittedClass =
false;
966 typedef std::pair<std::string, std::pair<llvm::GlobalVariable*, int>>
968 std::vector<EarlyInitPair> EarlyInitList;
970 std::string SymbolForClassRef(StringRef Name,
bool isWeak) {
972 return (ManglePublicSymbol(
"OBJC_WEAK_REF_CLASS_") + Name).str();
974 return (ManglePublicSymbol(
"OBJC_REF_CLASS_") + Name).str();
977 std::string SymbolForClass(StringRef Name) {
978 return (ManglePublicSymbol(
"OBJC_CLASS_") + Name).str();
980 void CallRuntimeFunction(
CGBuilderTy &B, StringRef FunctionName,
983 for (
auto *Arg : Args)
984 Types.push_back(Arg->getType());
985 llvm::FunctionType *FT = llvm::FunctionType::get(B.getVoidTy(), Types,
988 B.CreateCall(Fn, Args);
997 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
998 if (old != ObjCStrings.end())
1006 (LiteralLength < 9) && !isNonASCII) {
1012 for (
unsigned i=0 ; i<LiteralLength ; i++)
1013 str |= ((uint64_t)SL->
getCodeUnit(i)) << ((64 - 4 - 3) - (i*7));
1015 str |= LiteralLength << 3;
1018 auto *ObjCStr = llvm::ConstantExpr::getIntToPtr(
1019 llvm::ConstantInt::get(Int64Ty, str), IdTy);
1020 ObjCStrings[Str] = ObjCStr;
1026 if (StringClass.empty()) StringClass =
"NSConstantString";
1028 std::string Sym = SymbolForClass(StringClass);
1030 llvm::Constant *
isa = TheModule.getNamedGlobal(Sym);
1033 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
1034 llvm::GlobalValue::ExternalLinkage,
nullptr, Sym);
1035 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1036 cast<llvm::GlobalValue>(isa)->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
1051 auto Fields = Builder.beginStruct();
1052 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
1055 Fields.addNullPointer(PtrTy);
1062 unsigned NumU8CodeUnits = Str.size();
1067 const llvm::UTF8 *FromPtr = (
const llvm::UTF8 *)Str.data();
1068 llvm::UTF16 *ToPtr = &ToBuf[0];
1069 (void)llvm::ConvertUTF8toUTF16(&FromPtr, FromPtr + NumU8CodeUnits,
1070 &ToPtr, ToPtr + NumU8CodeUnits, llvm::strictConversion);
1071 uint32_t StringLength = ToPtr - &ToBuf[0];
1075 Fields.addInt(Int32Ty, 2);
1077 Fields.addInt(Int32Ty, StringLength);
1079 Fields.addInt(Int32Ty, StringLength * 2);
1081 Fields.addInt(Int32Ty, 0);
1084 auto *
C = llvm::ConstantDataArray::get(VMContext, Arr);
1085 auto *Buffer =
new llvm::GlobalVariable(TheModule,
C->getType(),
1086 true, llvm::GlobalValue::PrivateLinkage,
C,
".str");
1087 Buffer->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1091 Fields.addInt(Int32Ty, 0);
1093 Fields.addInt(Int32Ty, Str.size());
1095 Fields.addInt(Int32Ty, Str.size());
1097 Fields.addInt(Int32Ty, 0);
1099 Fields.add(MakeConstantString(Str));
1101 std::string StringName;
1104 StringName =
".objc_str_";
1105 for (
int i=0,e=Str.size() ; i<e ; ++i) {
1106 unsigned char c = Str[i];
1117 llvm::GlobalVariable *ObjCStrGV =
1119 isNamed ? StringRef(StringName) :
".objc_string",
1120 Align,
false,
isNamed ? llvm::GlobalValue::LinkOnceODRLinkage
1121 : llvm::GlobalValue::PrivateLinkage);
1122 ObjCStrGV->setSection(sectionName<ConstantStringSection>());
1124 ObjCStrGV->setComdat(TheModule.getOrInsertComdat(StringName));
1125 ObjCStrGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1127 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1128 std::pair<llvm::GlobalVariable*, int>
v{ObjCStrGV, 0};
1129 EarlyInitList.emplace_back(Sym,
v);
1131 ObjCStrings[Str] = ObjCStrGV;
1132 ConstantStrings.push_back(ObjCStrGV);
1139 bool isSynthesized=
true,
bool
1140 isDynamic=
true)
override {
1149 auto Fields = PropertiesArray.
beginStruct(PropertyMetadataTy);
1152 std::string TypeStr =
1154 Fields.add(MakeConstantString(TypeStr));
1155 std::string typeStr;
1157 Fields.add(MakeConstantString(typeStr));
1161 Fields.add(GetConstantSelector(accessor->getSelector(), TypeStr));
1163 Fields.add(NULLPtr);
1178 llvm::StructType *ObjCMethodDescTy =
1180 { PtrToInt8Ty, PtrToInt8Ty });
1189 auto MethodList = Builder.beginStruct();
1191 MethodList.addInt(IntTy, Methods.size());
1193 const llvm::DataLayout &DL = TheModule.getDataLayout();
1194 MethodList.addInt(IntTy, DL.getTypeSizeInBits(ObjCMethodDescTy) /
1197 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
1198 for (
auto *M : Methods) {
1199 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
1200 Method.add(CGObjCGNU::GetConstantSelector(M));
1202 Method.finishAndAddTo(MethodArray);
1204 MethodArray.finishAndAddTo(MethodList);
1205 return MethodList.finishAndCreateGlobal(
".objc_protocol_method_list",
1211 auto RuntimeProtocols = GetRuntimeProtocolList(ReferencedProtocols.begin(),
1212 ReferencedProtocols.end());
1214 for (
const auto *PI : RuntimeProtocols)
1215 Protocols.push_back(GenerateProtocolRef(PI));
1216 return GenerateProtocolList(Protocols);
1220 llvm::Value *cmd, MessageSendInfo &MSI)
override {
1223 llvm::Value *lookupArgs[] = {
1230 llvm::GlobalVariable *GetClassVar(StringRef Name,
bool isWeak=
false) {
1231 std::string SymbolName = SymbolForClassRef(Name, isWeak);
1232 auto *ClassSymbol = TheModule.getNamedGlobal(SymbolName);
1235 ClassSymbol =
new llvm::GlobalVariable(TheModule,
1236 IdTy,
false, llvm::GlobalValue::ExternalLinkage,
1237 nullptr, SymbolName);
1243 ClassSymbol->setInitializer(
new llvm::GlobalVariable(TheModule,
1244 Int8Ty,
false, llvm::GlobalValue::ExternalWeakLinkage,
1245 nullptr, SymbolForClass(Name)));
1247 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1253 for (
const auto *Result : DC->
lookup(&II))
1254 if ((OID = dyn_cast<ObjCInterfaceDecl>(Result)))
1260 assert(OID &&
"Failed to find ObjCInterfaceDecl");
1262 if (OIDDef !=
nullptr)
1265 auto Storage = llvm::GlobalValue::DefaultStorageClass;
1266 if (OID->
hasAttr<DLLImportAttr>())
1267 Storage = llvm::GlobalValue::DLLImportStorageClass;
1268 else if (OID->
hasAttr<DLLExportAttr>())
1269 Storage = llvm::GlobalValue::DLLExportStorageClass;
1271 cast<llvm::GlobalValue>(ClassSymbol)->setDLLStorageClass(Storage);
1274 assert(ClassSymbol->getName() == SymbolName);
1278 const std::string &Name,
1279 bool isWeak)
override {
1291 switch (Ownership) {
1313 llvm_unreachable(
"Method should not be called!");
1316 llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName)
override {
1317 std::string Name = SymbolForProtocol(ProtocolName);
1318 auto *GV = TheModule.getGlobalVariable(Name);
1321 GV =
new llvm::GlobalVariable(TheModule, ProtocolTy,
false,
1322 llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
1329 llvm::StringMap<llvm::Constant*> ExistingProtocolRefs;
1334 auto *&Ref = ExistingProtocolRefs[Name];
1336 auto *&
Protocol = ExistingProtocols[Name];
1338 Protocol = GenerateProtocolRef(PD);
1339 std::string RefName = SymbolForProtocolRef(Name);
1340 assert(!TheModule.getGlobalVariable(RefName));
1342 auto GV =
new llvm::GlobalVariable(TheModule, ProtocolPtrTy,
false,
1343 llvm::GlobalValue::LinkOnceODRLinkage,
1345 GV->setComdat(TheModule.getOrInsertComdat(RefName));
1346 GV->setSection(sectionName<ProtocolReferenceSection>());
1350 EmittedProtocolRef =
true;
1356 llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(ProtocolPtrTy,
1358 llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
1361 auto ProtocolBuilder = builder.beginStruct();
1362 ProtocolBuilder.addNullPointer(PtrTy);
1363 ProtocolBuilder.addInt(SizeTy, Protocols.size());
1364 ProtocolBuilder.add(ProtocolArray);
1365 return ProtocolBuilder.finishAndCreateGlobal(
".objc_protocol_list",
1374 auto *&
Protocol = ExistingProtocols[ProtocolName];
1378 EmittedProtocol =
true;
1380 auto SymName = SymbolForProtocol(ProtocolName);
1381 auto *OldGV = TheModule.getGlobalVariable(SymName);
1391 Protocol =
new llvm::GlobalVariable(TheModule, ProtocolTy,
1393 llvm::GlobalValue::ExternalLinkage,
nullptr, SymName);
1398 auto RuntimeProtocols =
1400 for (
const auto *PI : RuntimeProtocols)
1401 Protocols.push_back(GenerateProtocolRef(PI));
1402 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
1405 llvm::Constant *InstanceMethodList, *OptionalInstanceMethodList;
1406 llvm::Constant *ClassMethodList, *OptionalClassMethodList;
1408 OptionalInstanceMethodList);
1409 EmitProtocolMethodList(PD->
class_methods(), ClassMethodList,
1410 OptionalClassMethodList);
1415 auto ProtocolBuilder = builder.beginStruct();
1416 ProtocolBuilder.add(llvm::ConstantExpr::getIntToPtr(
1417 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
1418 ProtocolBuilder.add(MakeConstantString(ProtocolName));
1419 ProtocolBuilder.add(ProtocolList);
1420 ProtocolBuilder.add(InstanceMethodList);
1421 ProtocolBuilder.add(ClassMethodList);
1422 ProtocolBuilder.add(OptionalInstanceMethodList);
1423 ProtocolBuilder.add(OptionalClassMethodList);
1425 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
false,
false));
1427 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
false,
true));
1429 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
true,
false));
1431 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
true,
true));
1433 auto *GV = ProtocolBuilder.finishAndCreateGlobal(SymName,
1435 GV->setSection(sectionName<ProtocolSection>());
1436 GV->setComdat(TheModule.getOrInsertComdat(SymName));
1438 OldGV->replaceAllUsesWith(GV);
1439 OldGV->removeFromParent();
1440 GV->setName(SymName);
1446 const std::string &TypeEncoding)
override {
1447 return GetConstantSelector(Sel, TypeEncoding);
1449 std::string GetSymbolNameForTypeEncoding(
const std::string &TypeEncoding) {
1450 std::string MangledTypes = std::string(TypeEncoding);
1456 std::replace(MangledTypes.begin(), MangledTypes.end(),
'@',
'\1');
1459 std::replace(MangledTypes.begin(), MangledTypes.end(),
'=',
'\2');
1460 return MangledTypes;
1462 llvm::Constant *GetTypeString(llvm::StringRef TypeEncoding) {
1463 if (TypeEncoding.empty())
1465 std::string MangledTypes =
1466 GetSymbolNameForTypeEncoding(std::string(TypeEncoding));
1467 std::string TypesVarName =
".objc_sel_types_" + MangledTypes;
1468 auto *TypesGlobal = TheModule.getGlobalVariable(TypesVarName);
1470 llvm::Constant *
Init = llvm::ConstantDataArray::getString(VMContext,
1472 auto *GV =
new llvm::GlobalVariable(TheModule,
Init->getType(),
1473 true, llvm::GlobalValue::LinkOnceODRLinkage,
Init, TypesVarName);
1474 GV->setComdat(TheModule.getOrInsertComdat(TypesVarName));
1475 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1480 llvm::Constant *GetConstantSelector(
Selector Sel,
1481 const std::string &TypeEncoding)
override {
1482 std::string MangledTypes = GetSymbolNameForTypeEncoding(TypeEncoding);
1483 auto SelVarName = (StringRef(
".objc_selector_") + Sel.
getAsString() +
"_" +
1484 MangledTypes).str();
1485 if (
auto *GV = TheModule.getNamedGlobal(SelVarName))
1488 auto SelBuilder = builder.beginStruct();
1489 SelBuilder.add(ExportUniqueString(Sel.
getAsString(),
".objc_sel_name_",
1491 SelBuilder.add(GetTypeString(TypeEncoding));
1492 auto *GV = SelBuilder.finishAndCreateGlobal(SelVarName,
1494 GV->setComdat(TheModule.getOrInsertComdat(SelVarName));
1495 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1496 GV->setSection(sectionName<SelectorSection>());
1499 llvm::StructType *emptyStruct =
nullptr;
1508 std::pair<llvm::Constant*,llvm::Constant*>
1509 GetSectionBounds(StringRef Section) {
1510 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1511 if (emptyStruct ==
nullptr) {
1512 emptyStruct = llvm::StructType::create(VMContext,
".objc_section_sentinel");
1513 emptyStruct->setBody({},
true);
1515 auto ZeroInit = llvm::Constant::getNullValue(emptyStruct);
1516 auto Sym = [&](StringRef Prefix, StringRef SecSuffix) {
1517 auto *Sym =
new llvm::GlobalVariable(TheModule, emptyStruct,
1519 llvm::GlobalValue::LinkOnceODRLinkage, ZeroInit, Prefix +
1521 Sym->setVisibility(llvm::GlobalValue::HiddenVisibility);
1522 Sym->setSection((Section + SecSuffix).str());
1523 Sym->setComdat(TheModule.getOrInsertComdat((Prefix +
1528 return { Sym(
"__start_",
"$a"), Sym(
"__stop",
"$z") };
1530 auto *Start =
new llvm::GlobalVariable(TheModule, PtrTy,
1532 llvm::GlobalValue::ExternalLinkage,
nullptr, StringRef(
"__start_") +
1534 Start->setVisibility(llvm::GlobalValue::HiddenVisibility);
1535 auto *Stop =
new llvm::GlobalVariable(TheModule, PtrTy,
1537 llvm::GlobalValue::ExternalLinkage,
nullptr, StringRef(
"__stop_") +
1539 Stop->setVisibility(llvm::GlobalValue::HiddenVisibility);
1540 return { Start, Stop };
1545 llvm::Function *ModuleInitFunction()
override {
1546 llvm::Function *LoadFunction = llvm::Function::Create(
1547 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
1548 llvm::GlobalValue::LinkOnceODRLinkage,
".objcv2_load_function",
1550 LoadFunction->setVisibility(llvm::GlobalValue::HiddenVisibility);
1551 LoadFunction->setComdat(TheModule.getOrInsertComdat(
".objcv2_load_function"));
1553 llvm::BasicBlock *EntryBB =
1554 llvm::BasicBlock::Create(VMContext,
"entry", LoadFunction);
1556 B.SetInsertPoint(EntryBB);
1558 auto InitStructBuilder = builder.beginStruct();
1559 InitStructBuilder.addInt(Int64Ty, 0);
1560 auto §ionVec = CGM.
getTriple().isOSBinFormatCOFF() ? PECOFFSectionsBaseNames : SectionsBaseNames;
1561 for (
auto *
s : sectionVec) {
1562 auto bounds = GetSectionBounds(
s);
1563 InitStructBuilder.add(bounds.first);
1564 InitStructBuilder.add(bounds.second);
1566 auto *InitStruct = InitStructBuilder.finishAndCreateGlobal(
".objc_init",
1568 InitStruct->setVisibility(llvm::GlobalValue::HiddenVisibility);
1569 InitStruct->setComdat(TheModule.getOrInsertComdat(
".objc_init"));
1571 CallRuntimeFunction(B,
"__objc_load", {InitStruct});;
1578 auto *InitVar =
new llvm::GlobalVariable(TheModule, LoadFunction->getType(),
1579 false, llvm::GlobalValue::LinkOnceAnyLinkage,
1580 LoadFunction,
".objc_ctor");
1583 assert(InitVar->getName() ==
".objc_ctor");
1589 if (CGM.
getTriple().isOSBinFormatCOFF())
1590 InitVar->setSection(
".CRT$XCLz");
1594 InitVar->setSection(
".init_array");
1596 InitVar->setSection(
".ctors");
1598 InitVar->setVisibility(llvm::GlobalValue::HiddenVisibility);
1599 InitVar->setComdat(TheModule.getOrInsertComdat(
".objc_ctor"));
1601 for (
auto *
C : Categories) {
1602 auto *Cat = cast<llvm::GlobalVariable>(
C->stripPointerCasts());
1603 Cat->setSection(sectionName<CategorySection>());
1607 StringRef Section) {
1608 auto nullBuilder = builder.beginStruct();
1609 for (
auto *F :
Init)
1611 auto GV = nullBuilder.finishAndCreateGlobal(Name, CGM.
getPointerAlign(),
1612 false, llvm::GlobalValue::LinkOnceODRLinkage);
1613 GV->setSection(Section);
1614 GV->setComdat(TheModule.getOrInsertComdat(Name));
1615 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1619 for (
auto clsAlias : ClassAliases)
1620 createNullGlobal(std::string(
".objc_class_alias") +
1621 clsAlias.second, { MakeConstantString(clsAlias.second),
1622 GetClassVar(clsAlias.first) }, sectionName<ClassAliasSection>());
1627 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
1628 createNullGlobal(
".objc_null_selector", {NULLPtr, NULLPtr},
1629 sectionName<SelectorSection>());
1630 if (Categories.empty())
1631 createNullGlobal(
".objc_null_category", {NULLPtr, NULLPtr,
1632 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr},
1633 sectionName<CategorySection>());
1634 if (!EmittedClass) {
1635 createNullGlobal(
".objc_null_cls_init_ref", NULLPtr,
1636 sectionName<ClassSection>());
1637 createNullGlobal(
".objc_null_class_ref", { NULLPtr, NULLPtr },
1638 sectionName<ClassReferenceSection>());
1640 if (!EmittedProtocol)
1641 createNullGlobal(
".objc_null_protocol", {NULLPtr, NULLPtr, NULLPtr,
1642 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr,
1643 NULLPtr}, sectionName<ProtocolSection>());
1644 if (!EmittedProtocolRef)
1645 createNullGlobal(
".objc_null_protocol_ref", {NULLPtr},
1646 sectionName<ProtocolReferenceSection>());
1647 if (ClassAliases.empty())
1648 createNullGlobal(
".objc_null_class_alias", { NULLPtr, NULLPtr },
1649 sectionName<ClassAliasSection>());
1650 if (ConstantStrings.empty()) {
1651 auto i32Zero = llvm::ConstantInt::get(Int32Ty, 0);
1652 createNullGlobal(
".objc_null_constant_string", { NULLPtr, i32Zero,
1653 i32Zero, i32Zero, i32Zero, NULLPtr },
1654 sectionName<ConstantStringSection>());
1657 ConstantStrings.clear();
1661 if (EarlyInitList.size() > 0) {
1662 auto *
Init = llvm::Function::Create(llvm::FunctionType::get(CGM.
VoidTy,
1663 {}), llvm::GlobalValue::InternalLinkage,
".objc_early_init",
1665 llvm::IRBuilder<>
b(llvm::BasicBlock::Create(CGM.
getLLVMContext(),
"entry",
1667 for (
const auto &lateInit : EarlyInitList) {
1668 auto *global = TheModule.getGlobalVariable(lateInit.first);
1670 llvm::GlobalVariable *GV = lateInit.second.first;
1671 b.CreateAlignedStore(
1673 b.CreateStructGEP(GV->getValueType(), GV, lateInit.second.second),
1680 auto *InitVar =
new llvm::GlobalVariable(CGM.
getModule(),
Init->getType(),
1681 true, llvm::GlobalValue::InternalLinkage,
1682 Init,
".objc_early_init_ptr");
1683 InitVar->setSection(
".CRT$XCLb");
1692 std::string TypeEncoding;
1694 TypeEncoding = GetSymbolNameForTypeEncoding(TypeEncoding);
1695 const std::string Name =
"__objc_ivar_offset_" +
ID->getNameAsString()
1703 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
1704 if (!IvarOffsetPointer)
1705 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule, IntTy,
false,
1706 llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
1708 llvm::Value *Offset =
1710 if (Offset->getType() != PtrDiffTy)
1711 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
1716 bool IsCOFF = CGM.
getTriple().isOSBinFormatCOFF();
1722 auto *classNameConstant = MakeConstantString(className);
1725 auto metaclassFields = builder.beginStruct();
1727 metaclassFields.addNullPointer(PtrTy);
1729 metaclassFields.addNullPointer(PtrTy);
1731 metaclassFields.add(classNameConstant);
1733 metaclassFields.addInt(LongTy, 0);
1736 metaclassFields.addInt(LongTy, ClassFlags::ClassFlagMeta);
1740 metaclassFields.addInt(LongTy, 0);
1742 metaclassFields.addNullPointer(PtrTy);
1747 metaclassFields.addNullPointer(PtrTy);
1752 metaclassFields.add(
1753 GenerateMethodList(className,
"", ClassMethods,
true));
1756 metaclassFields.addNullPointer(PtrTy);
1758 metaclassFields.addNullPointer(PtrTy);
1760 metaclassFields.addNullPointer(PtrTy);
1762 metaclassFields.addNullPointer(PtrTy);
1764 metaclassFields.addNullPointer(PtrTy);
1766 metaclassFields.addNullPointer(PtrTy);
1768 metaclassFields.addNullPointer(PtrTy);
1770 metaclassFields.addInt(LongTy, 0);
1772 metaclassFields.add(GeneratePropertyList(OID, classDecl,
true));
1774 auto *metaclass = metaclassFields.finishAndCreateGlobal(
1775 ManglePublicSymbol(
"OBJC_METACLASS_") + className,
1778 auto classFields = builder.beginStruct();
1780 classFields.add(metaclass);
1785 llvm::Constant *SuperClass =
nullptr;
1786 if (SuperClassDecl) {
1787 auto SuperClassName = SymbolForClass(SuperClassDecl->
getNameAsString());
1788 SuperClass = TheModule.getNamedGlobal(SuperClassName);
1791 SuperClass =
new llvm::GlobalVariable(TheModule, PtrTy,
false,
1792 llvm::GlobalValue::ExternalLinkage,
nullptr, SuperClassName);
1794 auto Storage = llvm::GlobalValue::DefaultStorageClass;
1795 if (SuperClassDecl->
hasAttr<DLLImportAttr>())
1796 Storage = llvm::GlobalValue::DLLImportStorageClass;
1797 else if (SuperClassDecl->
hasAttr<DLLExportAttr>())
1798 Storage = llvm::GlobalValue::DLLExportStorageClass;
1800 cast<llvm::GlobalValue>(SuperClass)->setDLLStorageClass(Storage);
1804 classFields.add(SuperClass);
1806 classFields.addNullPointer(PtrTy);
1808 classFields.addNullPointer(PtrTy);
1810 classFields.add(classNameConstant);
1812 classFields.addInt(LongTy, 0);
1815 classFields.addInt(LongTy, 0);
1817 int superInstanceSize = !SuperClassDecl ? 0 :
1821 classFields.addInt(LongTy,
1823 superInstanceSize));
1826 classFields.addNullPointer(PtrTy);
1831 const llvm::DataLayout &DL = TheModule.getDataLayout();
1834 auto ivarListBuilder =
b.beginStruct();
1836 ivarListBuilder.addInt(IntTy, ivar_count);
1838 llvm::StructType *ObjCIvarTy = llvm::StructType::get(
1844 ivarListBuilder.addInt(SizeTy, DL.getTypeSizeInBits(ObjCIvarTy) /
1847 auto ivarArrayBuilder = ivarListBuilder.beginArray();
1850 auto ivarTy = IVD->getType();
1851 auto ivarBuilder = ivarArrayBuilder.beginStruct();
1853 ivarBuilder.add(MakeConstantString(IVD->getNameAsString()));
1855 std::string TypeStr;
1858 ivarBuilder.add(MakeConstantString(TypeStr));
1860 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
1861 uint64_t Offset = BaseOffset - superInstanceSize;
1862 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
1863 std::string OffsetName = GetIVarOffsetVariableName(classDecl, IVD);
1864 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
1866 OffsetVar->setInitializer(OffsetValue);
1868 OffsetVar =
new llvm::GlobalVariable(TheModule, IntTy,
1869 false, llvm::GlobalValue::ExternalLinkage,
1870 OffsetValue, OffsetName);
1871 auto ivarVisibility =
1875 llvm::GlobalValue::HiddenVisibility :
1876 llvm::GlobalValue::DefaultVisibility;
1877 OffsetVar->setVisibility(ivarVisibility);
1878 if (ivarVisibility != llvm::GlobalValue::HiddenVisibility)
1880 ivarBuilder.add(OffsetVar);
1882 ivarBuilder.addInt(Int32Ty,
1893 ivarBuilder.addInt(Int32Ty,
1894 (align << 3) | (1<<2) |
1895 FlagsForOwnership(ivarTy.getQualifiers().getObjCLifetime()));
1896 ivarBuilder.finishAndAddTo(ivarArrayBuilder);
1898 ivarArrayBuilder.finishAndAddTo(ivarListBuilder);
1899 auto ivarList = ivarListBuilder.finishAndCreateGlobal(
".objc_ivar_list",
1901 llvm::GlobalValue::PrivateLinkage);
1902 classFields.add(ivarList);
1906 InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
1909 if (propImpl->getPropertyImplementation() ==
1912 if (OMD && OMD->hasBody())
1913 InstanceMethods.push_back(OMD);
1915 addIfExists(propImpl->getGetterMethodDecl());
1916 addIfExists(propImpl->getSetterMethodDecl());
1919 if (InstanceMethods.size() == 0)
1920 classFields.addNullPointer(PtrTy);
1923 GenerateMethodList(className,
"", InstanceMethods,
false));
1926 classFields.addNullPointer(PtrTy);
1928 classFields.addNullPointer(PtrTy);
1930 classFields.addNullPointer(PtrTy);
1932 classFields.addNullPointer(PtrTy);
1934 classFields.addNullPointer(PtrTy);
1936 auto RuntimeProtocols = GetRuntimeProtocolList(classDecl->
protocol_begin(),
1939 for (
const auto *I : RuntimeProtocols)
1940 Protocols.push_back(GenerateProtocolRef(I));
1942 if (Protocols.empty())
1943 classFields.addNullPointer(PtrTy);
1945 classFields.add(GenerateProtocolList(Protocols));
1947 classFields.addNullPointer(PtrTy);
1949 classFields.addInt(LongTy, 0);
1951 classFields.add(GeneratePropertyList(OID, classDecl));
1953 llvm::GlobalVariable *classStruct =
1954 classFields.finishAndCreateGlobal(SymbolForClass(className),
1957 auto *classRefSymbol = GetClassVar(className);
1958 classRefSymbol->setSection(sectionName<ClassReferenceSection>());
1959 classRefSymbol->setInitializer(classStruct);
1964 classStruct->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1965 cast<llvm::GlobalValue>(classRefSymbol)->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1969 std::pair<llvm::GlobalVariable*, int>
v{classStruct, 1};
1970 EarlyInitList.emplace_back(std::string(SuperClass->getName()),
1979 if (ClassPtrAlias) {
1980 ClassPtrAlias->replaceAllUsesWith(classStruct);
1981 ClassPtrAlias->eraseFromParent();
1982 ClassPtrAlias =
nullptr;
1984 if (
auto Placeholder =
1985 TheModule.getNamedGlobal(SymbolForClass(className)))
1986 if (Placeholder != classStruct) {
1987 Placeholder->replaceAllUsesWith(classStruct);
1988 Placeholder->eraseFromParent();
1989 classStruct->setName(SymbolForClass(className));
1991 if (MetaClassPtrAlias) {
1992 MetaClassPtrAlias->replaceAllUsesWith(metaclass);
1993 MetaClassPtrAlias->eraseFromParent();
1994 MetaClassPtrAlias =
nullptr;
1996 assert(classStruct->getName() == SymbolForClass(className));
1998 auto classInitRef =
new llvm::GlobalVariable(TheModule,
1999 classStruct->getType(),
false, llvm::GlobalValue::ExternalLinkage,
2000 classStruct, ManglePublicSymbol(
"OBJC_INIT_CLASS_") + className);
2001 classInitRef->setSection(sectionName<ClassSection>());
2004 EmittedClass =
true;
2007 CGObjCGNUstep2(
CodeGenModule &Mod) : CGObjCGNUstep(Mod, 10, 4, 2) {
2008 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
2009 PtrToObjCSuperTy, SelectorTy);
2010 SentInitializeFn.init(&CGM,
"objc_send_initialize",
2011 llvm::Type::getVoidTy(VMContext), IdTy);
2020 PropertyMetadataTy =
2022 { PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty });
2025 void GenerateDirectMethodPrologue(
CodeGenFunction &CGF, llvm::Function *Fn,
2029 bool ReceiverCanBeNull =
true;
2031 auto selfValue = Builder.CreateLoad(selfAddr);
2056 ReceiverCanBeNull = isWeakLinkedClass(OID);
2060 if (ReceiverCanBeNull) {
2061 llvm::BasicBlock *SelfIsNilBlock =
2063 llvm::BasicBlock *ContBlock =
2067 auto selfTy = cast<llvm::PointerType>(selfValue->getType());
2068 auto Zero = llvm::ConstantPointerNull::get(selfTy);
2070 Builder.CreateCondBr(Builder.CreateICmpEQ(selfValue, Zero),
2071 SelfIsNilBlock, ContBlock,
2072 MDHelper.createUnlikelyBranchWeights());
2078 Builder.SetInsertPoint(SelfIsNilBlock);
2079 if (!retTy->isVoidType()) {
2087 Builder.SetInsertPoint(ContBlock);
2093 llvm::StructType::get(PtrTy, PtrTy, PtrTy, LongTy, LongTy);
2100 llvm::Value *Val = Builder.CreateStructGEP(classStart, selfValue, 4);
2102 astContext.getTypeAlign(astContext.UnsignedLongTy));
2103 auto flags = Builder.CreateLoad(
Address{Val, LongTy, Align});
2104 auto isInitialized =
2105 Builder.CreateAnd(flags, ClassFlags::ClassFlagInitialized);
2106 llvm::BasicBlock *notInitializedBlock =
2108 llvm::BasicBlock *initializedBlock =
2110 Builder.CreateCondBr(Builder.CreateICmpEQ(isInitialized, Zeros[0]),
2111 notInitializedBlock, initializedBlock,
2112 MDHelper.createUnlikelyBranchWeights());
2114 Builder.SetInsertPoint(notInitializedBlock);
2116 Builder.CreateBr(initializedBlock);
2118 Builder.SetInsertPoint(initializedBlock);
2126 Builder.CreateStore(GetSelector(CGF, OMD),
2132const char *
const CGObjCGNUstep2::SectionsBaseNames[8] =
2139"__objc_protocol_refs",
2140"__objc_class_aliases",
2141"__objc_constant_string"
2144const char *
const CGObjCGNUstep2::PECOFFSectionsBaseNames[8] =
2157class CGObjCObjFW:
public CGObjCGNU {
2161 LazyRuntimeFunction MsgLookupFn;
2164 LazyRuntimeFunction MsgLookupFnSRet;
2168 LazyRuntimeFunction MsgLookupSuperFn, MsgLookupSuperFnSRet;
2171 llvm::Value *cmd, llvm::MDNode *node,
2172 MessageSendInfo &MSI)
override {
2174 llvm::Value *args[] = {
2175 EnforceType(Builder, Receiver, IdTy),
2176 EnforceType(Builder, cmd, SelectorTy) };
2178 llvm::CallBase *imp;
2184 imp->setMetadata(msgSendMDKind, node);
2189 llvm::Value *cmd, MessageSendInfo &MSI)
override {
2191 llvm::Value *lookupArgs[] = {
2192 EnforceType(Builder, ObjCSuper.
emitRawPointer(CGF), PtrToObjCSuperTy),
2202 llvm::Value *GetClassNamed(
CodeGenFunction &CGF,
const std::string &Name,
2203 bool isWeak)
override {
2205 return CGObjCGNU::GetClassNamed(CGF, Name, isWeak);
2208 std::string SymbolName =
"_OBJC_CLASS_" + Name;
2209 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(SymbolName);
2211 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
2212 llvm::GlobalValue::ExternalLinkage,
2213 nullptr, SymbolName);
2220 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
2221 MsgLookupFnSRet.init(&CGM,
"objc_msg_lookup_stret", IMPTy, IdTy,
2224 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
2225 PtrToObjCSuperTy, SelectorTy);
2226 MsgLookupSuperFnSRet.init(&CGM,
"objc_msg_lookup_super_stret", IMPTy,
2227 PtrToObjCSuperTy, SelectorTy);
2235void CGObjCGNU::EmitClassRef(
const std::string &className) {
2236 std::string symbolRef =
"__objc_class_ref_" + className;
2238 if (TheModule.getGlobalVariable(symbolRef))
2240 std::string symbolName =
"__objc_class_name_" + className;
2241 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
2243 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
2244 llvm::GlobalValue::ExternalLinkage,
2245 nullptr, symbolName);
2247 new llvm::GlobalVariable(TheModule, ClassSymbol->getType(),
true,
2248 llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef);
2251CGObjCGNU::CGObjCGNU(
CodeGenModule &cgm,
unsigned runtimeABIVersion,
2252 unsigned protocolClassVersion,
unsigned classABI)
2254 VMContext(cgm.getLLVMContext()), ClassPtrAlias(nullptr),
2255 MetaClassPtrAlias(nullptr), RuntimeVersion(runtimeABIVersion),
2256 ProtocolVersion(protocolClassVersion), ClassABIVersion(classABI) {
2258 msgSendMDKind = VMContext.getMDKindID(
"GNUObjCMessageSend");
2266 IntTy = cast<llvm::IntegerType>(
2268 LongTy = cast<llvm::IntegerType>(
2270 SizeTy = cast<llvm::IntegerType>(
2272 PtrDiffTy = cast<llvm::IntegerType>(
2276 Int8Ty = llvm::Type::getInt8Ty(VMContext);
2278 PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
2279 ProtocolPtrTy = llvm::PointerType::getUnqual(
2282 Zeros[0] = llvm::ConstantInt::get(LongTy, 0);
2283 Zeros[1] = Zeros[0];
2284 NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty);
2288 SelectorTy = PtrToInt8Ty;
2289 SelectorElemTy = Int8Ty;
2295 PtrToIntTy = llvm::PointerType::getUnqual(IntTy);
2296 PtrTy = PtrToInt8Ty;
2298 Int32Ty = llvm::Type::getInt32Ty(VMContext);
2299 Int64Ty = llvm::Type::getInt64Ty(VMContext);
2302 CGM.
getDataLayout().getPointerSizeInBits() == 32 ? Int32Ty : Int64Ty;
2316 PtrToIdTy = llvm::PointerType::getUnqual(IdTy);
2317 ProtocolTy = llvm::StructType::get(IdTy,
2339 PropertyMetadataTy = llvm::StructType::get(CGM.
getLLVMContext(), {
2340 PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty,
2341 PtrToInt8Ty, PtrToInt8Ty });
2343 ObjCSuperTy = llvm::StructType::get(IdTy, IdTy);
2344 PtrToObjCSuperTy = llvm::PointerType::getUnqual(ObjCSuperTy);
2346 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
2349 ExceptionThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy);
2350 ExceptionReThrowFn.init(&CGM,
2351 usesCxxExceptions ?
"objc_exception_rethrow"
2352 :
"objc_exception_throw",
2355 SyncEnterFn.init(&CGM,
"objc_sync_enter", IntTy, IdTy);
2357 SyncExitFn.init(&CGM,
"objc_sync_exit", IntTy, IdTy);
2360 EnumerationMutationFn.init(&CGM,
"objc_enumerationMutation", VoidTy, IdTy);
2363 GetPropertyFn.init(&CGM,
"objc_getProperty", IdTy, IdTy, SelectorTy,
2366 SetPropertyFn.init(&CGM,
"objc_setProperty", VoidTy, IdTy, SelectorTy,
2367 PtrDiffTy, IdTy, BoolTy, BoolTy);
2369 GetStructPropertyFn.init(&CGM,
"objc_getPropertyStruct", VoidTy, PtrTy, PtrTy,
2370 PtrDiffTy, BoolTy, BoolTy);
2372 SetStructPropertyFn.init(&CGM,
"objc_setPropertyStruct", VoidTy, PtrTy, PtrTy,
2373 PtrDiffTy, BoolTy, BoolTy);
2376 llvm::Type *IMPArgs[] = { IdTy, SelectorTy };
2377 IMPTy = llvm::PointerType::getUnqual(llvm::FunctionType::get(IdTy, IMPArgs,
2381 if ((Opts.getGC() != LangOptions::NonGC) || Opts.ObjCAutoRefCount)
2382 RuntimeVersion = 10;
2385 if (Opts.getGC() != LangOptions::NonGC) {
2397 IvarAssignFn.init(&CGM,
"objc_assign_ivar", IdTy, IdTy, IdTy, PtrDiffTy);
2399 StrongCastAssignFn.init(&CGM,
"objc_assign_strongCast", IdTy, IdTy,
2402 GlobalAssignFn.init(&CGM,
"objc_assign_global", IdTy, IdTy, PtrToIdTy);
2404 WeakAssignFn.init(&CGM,
"objc_assign_weak", IdTy, IdTy, PtrToIdTy);
2406 WeakReadFn.init(&CGM,
"objc_read_weak", IdTy, PtrToIdTy);
2408 MemMoveFn.init(&CGM,
"objc_memmove_collectable", PtrTy, PtrTy, PtrTy,
2414 const std::string &Name,
bool isWeak) {
2415 llvm::Constant *ClassName = MakeConstantString(Name);
2427 llvm::FunctionType::get(IdTy, PtrToInt8Ty,
true),
"objc_lookup_class");
2437 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value))
2442llvm::Value *CGObjCGNU::EmitNSAutoreleasePoolClassRef(
CodeGenFunction &CGF) {
2443 auto *
Value = GetClassNamed(CGF,
"NSAutoreleasePool",
false);
2444 if (CGM.
getTriple().isOSBinFormatCOFF()) {
2445 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value)) {
2451 for (
const auto *Result : DC->
lookup(&II))
2452 if ((VD = dyn_cast<VarDecl>(Result)))
2462 const std::string &TypeEncoding) {
2464 llvm::GlobalAlias *SelValue =
nullptr;
2467 e = Types.end() ; i!=e ; i++) {
2468 if (i->first == TypeEncoding) {
2469 SelValue = i->second;
2474 SelValue = llvm::GlobalAlias::create(SelectorElemTy, 0,
2475 llvm::GlobalValue::PrivateLinkage,
2478 Types.emplace_back(TypeEncoding, SelValue);
2485 llvm::Value *SelValue = GetSelector(CGF, Sel);
2496 return GetTypedSelector(CGF, Sel, std::string());
2502 return GetTypedSelector(CGF, Method->
getSelector(), SelTypes);
2505llvm::Constant *CGObjCGNU::GetEHType(
QualType T) {
2512 return MakeConstantString(
"@id");
2520 assert(OPT &&
"Invalid @catch type.");
2522 assert(IDecl &&
"Invalid @catch type.");
2526llvm::Constant *CGObjCGNUstep::GetEHType(
QualType T) {
2527 if (usesSEHExceptions)
2530 if (!CGM.
getLangOpts().CPlusPlus && !usesCxxExceptions)
2531 return CGObjCGNU::GetEHType(
T);
2539 llvm::Constant *IDEHType =
2540 CGM.
getModule().getGlobalVariable(
"__objc_id_type_info");
2543 new llvm::GlobalVariable(CGM.
getModule(), PtrToInt8Ty,
2545 llvm::GlobalValue::ExternalLinkage,
2546 nullptr,
"__objc_id_type_info");
2552 assert(PT &&
"Invalid @catch type.");
2554 assert(IT &&
"Invalid @catch type.");
2555 std::string className =
2558 std::string typeinfoName =
"__objc_eh_typeinfo_" + className;
2561 if (llvm::Constant *typeinfo = TheModule.getGlobalVariable(typeinfoName))
2569 const char *vtableName =
"_ZTVN7gnustep7libobjc22__objc_class_type_infoE";
2570 auto *Vtable = TheModule.getGlobalVariable(vtableName);
2572 Vtable =
new llvm::GlobalVariable(TheModule, PtrToInt8Ty,
true,
2573 llvm::GlobalValue::ExternalLinkage,
2574 nullptr, vtableName);
2576 llvm::Constant *Two = llvm::ConstantInt::get(IntTy, 2);
2578 llvm::ConstantExpr::getGetElementPtr(Vtable->getValueType(), Vtable, Two);
2580 llvm::Constant *typeName =
2581 ExportUniqueString(className,
"__objc_eh_typename_");
2584 auto fields = builder.beginStruct();
2585 fields.add(BVtable);
2586 fields.add(typeName);
2587 llvm::Constant *TI =
2588 fields.finishAndCreateGlobal(
"__objc_eh_typeinfo_" + className,
2591 llvm::GlobalValue::LinkOnceODRLinkage);
2598 std::string Str = SL->
getString().str();
2602 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
2603 if (old != ObjCStrings.end())
2608 if (StringClass.empty()) StringClass =
"NSConstantString";
2610 std::string Sym =
"_OBJC_CLASS_";
2613 llvm::Constant *
isa = TheModule.getNamedGlobal(Sym);
2616 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
2617 llvm::GlobalValue::ExternalWeakLinkage,
2621 auto Fields = Builder.beginStruct();
2623 Fields.add(MakeConstantString(Str));
2624 Fields.addInt(IntTy, Str.size());
2626 ObjCStrings[Str] = ObjCStr;
2627 ConstantStrings.push_back(ObjCStr);
2640 bool isCategoryImpl,
2641 llvm::Value *Receiver,
2642 bool IsClassMessage,
2646 if (CGM.
getLangOpts().getGC() == LangOptions::GCOnly) {
2647 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2651 if (Sel == ReleaseSel) {
2656 llvm::Value *cmd = GetSelector(CGF, Sel);
2659 ActualArgs.
add(
RValue::get(EnforceType(Builder, Receiver, IdTy)), ASTIdTy);
2663 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2665 llvm::Value *ReceiverClass =
nullptr;
2668 ReceiverClass = GetClassNamed(CGF,
2669 Class->getSuperClass()->getNameAsString(),
false);
2670 if (IsClassMessage) {
2672 ReceiverClass = Builder.CreateBitCast(ReceiverClass,
2673 llvm::PointerType::getUnqual(IdTy));
2675 Builder.CreateAlignedLoad(IdTy, ReceiverClass, CGF.
getPointerAlign());
2677 ReceiverClass = EnforceType(Builder, ReceiverClass, IdTy);
2679 if (isCategoryImpl) {
2680 llvm::FunctionCallee classLookupFunction =
nullptr;
2681 if (IsClassMessage) {
2683 IdTy, PtrTy,
true),
"objc_get_meta_class");
2686 IdTy, PtrTy,
true),
"objc_get_class");
2688 ReceiverClass = Builder.CreateCall(classLookupFunction,
2689 MakeConstantString(
Class->getNameAsString()));
2696 if (IsClassMessage) {
2697 if (!MetaClassPtrAlias) {
2698 MetaClassPtrAlias = llvm::GlobalAlias::create(
2699 IdElemTy, 0, llvm::GlobalValue::InternalLinkage,
2700 ".objc_metaclass_ref" +
Class->getNameAsString(), &TheModule);
2702 ReceiverClass = MetaClassPtrAlias;
2704 if (!ClassPtrAlias) {
2705 ClassPtrAlias = llvm::GlobalAlias::create(
2706 IdElemTy, 0, llvm::GlobalValue::InternalLinkage,
2707 ".objc_class_ref" +
Class->getNameAsString(), &TheModule);
2709 ReceiverClass = ClassPtrAlias;
2713 llvm::Type *CastTy = llvm::StructType::get(IdTy, IdTy);
2714 ReceiverClass = Builder.CreateBitCast(ReceiverClass,
2715 llvm::PointerType::getUnqual(CastTy));
2717 ReceiverClass = Builder.CreateStructGEP(CastTy, ReceiverClass, 1);
2720 Builder.CreateAlignedLoad(IdTy, ReceiverClass, CGF.
getPointerAlign());
2723 llvm::StructType *ObjCSuperTy =
2724 llvm::StructType::get(Receiver->getType(), IdTy);
2729 Builder.CreateStore(Receiver, Builder.CreateStructGEP(ObjCSuper, 0));
2730 Builder.CreateStore(ReceiverClass, Builder.CreateStructGEP(ObjCSuper, 1));
2733 llvm::Value *imp = LookupIMPSuper(CGF, ObjCSuper, cmd, MSI);
2734 imp = EnforceType(Builder, imp, MSI.MessengerType);
2736 llvm::Metadata *impMD[] = {
2737 llvm::MDString::get(VMContext, Sel.
getAsString()),
2738 llvm::MDString::get(VMContext,
Class->getSuperClass()->getNameAsString()),
2739 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2740 llvm::Type::getInt1Ty(VMContext), IsClassMessage))};
2741 llvm::MDNode *
node = llvm::MDNode::get(VMContext, impMD);
2745 llvm::CallBase *call;
2746 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2747 call->setMetadata(msgSendMDKind, node);
2757 llvm::Value *Receiver,
2764 if (CGM.
getLangOpts().getGC() == LangOptions::GCOnly) {
2765 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2769 if (Sel == ReleaseSel) {
2780 cmd = GetSelector(CGF, Method);
2782 cmd = GetSelector(CGF, Sel);
2783 cmd = EnforceType(Builder, cmd, SelectorTy);
2786 Receiver = EnforceType(Builder, Receiver, IdTy);
2788 llvm::Metadata *impMD[] = {
2789 llvm::MDString::get(VMContext, Sel.
getAsString()),
2790 llvm::MDString::get(VMContext, Class ?
Class->getNameAsString() :
""),
2791 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2792 llvm::Type::getInt1Ty(VMContext), Class !=
nullptr))};
2793 llvm::MDNode *
node = llvm::MDNode::get(VMContext, impMD);
2801 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2822 bool hasParamDestroyedInCallee =
false;
2823 bool requiresExplicitZeroResult =
false;
2824 bool requiresNilReceiverCheck = [&] {
2826 if (!canMessageReceiverBeNull(CGF, Method,
false,
2832 hasParamDestroyedInCallee =
true;
2853 requiresExplicitZeroResult = !isDirect;
2857 return hasParamDestroyedInCallee || requiresExplicitZeroResult;
2863 bool requiresExplicitAggZeroing =
2867 llvm::BasicBlock *continueBB =
nullptr;
2869 llvm::BasicBlock *nilPathBB =
nullptr;
2871 llvm::BasicBlock *nilCleanupBB =
nullptr;
2874 if (requiresNilReceiverCheck) {
2881 if (requiresExplicitAggZeroing || hasParamDestroyedInCallee) {
2884 nilPathBB = Builder.GetInsertBlock();
2887 llvm::Value *isNil = Builder.CreateICmpEQ(Receiver,
2888 llvm::Constant::getNullValue(Receiver->getType()));
2889 Builder.CreateCondBr(isNil, nilCleanupBB ? nilCleanupBB : continueBB,
2906 imp = LookupIMP(CGF, Receiver, cmd, node, MSI);
2910 StringRef
name =
"objc_msgSend";
2912 name =
"objc_msgSend_fpret";
2914 name =
"objc_msgSend_stret";
2918 bool shouldCheckForInReg =
2922 .isWindowsMSVCEnvironment() &&
2925 name =
"objc_msgSend_stret2";
2938 imp = EnforceType(Builder, imp, MSI.MessengerType);
2940 llvm::CallBase *call;
2942 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2944 call->setMetadata(msgSendMDKind, node);
2946 if (requiresNilReceiverCheck) {
2947 llvm::BasicBlock *nonNilPathBB = CGF.
Builder.GetInsertBlock();
2948 CGF.
Builder.CreateBr(continueBB);
2954 if (hasParamDestroyedInCallee) {
2955 destroyCalleeDestroyedArguments(CGF, Method, CallArgs);
2958 if (requiresExplicitAggZeroing) {
2964 nilPathBB = CGF.
Builder.GetInsertBlock();
2965 CGF.
Builder.CreateBr(continueBB);
2973 llvm::PHINode *phi = Builder.CreatePHI(
v->getType(), 2);
2974 phi->addIncoming(
v, nonNilPathBB);
2982 llvm::PHINode *phi = Builder.CreatePHI(
v.first->getType(), 2);
2983 phi->addIncoming(
v.first, nonNilPathBB);
2984 phi->addIncoming(llvm::Constant::getNullValue(
v.first->getType()),
2986 llvm::PHINode *phi2 = Builder.CreatePHI(
v.second->getType(), 2);
2987 phi2->addIncoming(
v.second, nonNilPathBB);
2988 phi2->addIncoming(llvm::Constant::getNullValue(
v.second->getType()),
2998llvm::Constant *CGObjCGNU::
2999GenerateMethodList(StringRef ClassName,
3000 StringRef CategoryName,
3002 bool isClassMethodList) {
3003 if (Methods.empty())
3008 auto MethodList = Builder.beginStruct();
3009 MethodList.addNullPointer(CGM.
Int8PtrTy);
3010 MethodList.addInt(Int32Ty, Methods.size());
3013 llvm::StructType *ObjCMethodTy =
3022 const llvm::DataLayout &DL = TheModule.getDataLayout();
3023 MethodList.addInt(SizeTy, DL.getTypeSizeInBits(ObjCMethodTy) /
3039 auto MethodArray = MethodList.beginArray();
3041 for (
const auto *OMD : Methods) {
3042 llvm::Constant *FnPtr =
3043 TheModule.getFunction(getSymbolNameForMethod(OMD));
3044 assert(FnPtr &&
"Can't generate metadata for method that doesn't exist");
3045 auto Method = MethodArray.beginStruct(ObjCMethodTy);
3056 Method.finishAndAddTo(MethodArray);
3058 MethodArray.finishAndAddTo(MethodList);
3061 return MethodList.finishAndCreateGlobal(
".objc_method_list",
3066llvm::Constant *CGObjCGNU::
3072 if (IvarNames.empty())
3078 auto IvarList = Builder.beginStruct();
3079 IvarList.addInt(IntTy, (
int)IvarNames.size());
3082 llvm::StructType *ObjCIvarTy =
3083 llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, IntTy);
3086 auto Ivars = IvarList.beginArray(ObjCIvarTy);
3087 for (
unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {
3088 auto Ivar = Ivars.beginStruct(ObjCIvarTy);
3089 Ivar.
add(IvarNames[i]);
3090 Ivar.
add(IvarTypes[i]);
3091 Ivar.
add(IvarOffsets[i]);
3092 Ivar.finishAndAddTo(Ivars);
3094 Ivars.finishAndAddTo(IvarList);
3097 return IvarList.finishAndCreateGlobal(
".objc_ivar_list",
3102llvm::Constant *CGObjCGNU::GenerateClassStructure(
3103 llvm::Constant *MetaClass,
3104 llvm::Constant *SuperClass,
3107 llvm::Constant *Version,
3108 llvm::Constant *InstanceSize,
3109 llvm::Constant *IVars,
3110 llvm::Constant *Methods,
3111 llvm::Constant *Protocols,
3112 llvm::Constant *IvarOffsets,
3113 llvm::Constant *Properties,
3114 llvm::Constant *StrongIvarBitmap,
3115 llvm::Constant *WeakIvarBitmap,
3124 llvm::StructType *ClassTy = llvm::StructType::get(
3141 IvarOffsets->getType(),
3142 Properties->getType(),
3148 auto Elements = Builder.beginStruct(ClassTy);
3153 Elements.add(MetaClass);
3155 Elements.add(SuperClass);
3157 Elements.add(MakeConstantString(Name,
".class_name"));
3159 Elements.addInt(LongTy, 0);
3161 Elements.addInt(LongTy, info);
3164 const llvm::DataLayout &DL = TheModule.getDataLayout();
3165 Elements.addInt(LongTy, DL.getTypeSizeInBits(ClassTy) /
3168 Elements.add(InstanceSize);
3170 Elements.add(IVars);
3172 Elements.add(Methods);
3175 Elements.add(NULLPtr);
3177 Elements.add(NULLPtr);
3179 Elements.add(NULLPtr);
3181 Elements.add(Protocols);
3183 Elements.add(NULLPtr);
3185 Elements.addInt(LongTy, ClassABIVersion);
3187 Elements.add(IvarOffsets);
3189 Elements.add(Properties);
3191 Elements.add(StrongIvarBitmap);
3193 Elements.add(WeakIvarBitmap);
3198 std::string ClassSym((isMeta ?
"_OBJC_METACLASS_":
"_OBJC_CLASS_") +
3200 llvm::GlobalVariable *ClassRef = TheModule.getNamedGlobal(ClassSym);
3201 llvm::Constant *
Class =
3202 Elements.finishAndCreateGlobal(ClassSym, CGM.
getPointerAlign(),
false,
3203 llvm::GlobalValue::ExternalLinkage);
3205 ClassRef->replaceAllUsesWith(Class);
3206 ClassRef->removeFromParent();
3207 Class->setName(ClassSym);
3212llvm::Constant *CGObjCGNU::
3215 llvm::StructType *ObjCMethodDescTy =
3216 llvm::StructType::get(CGM.
getLLVMContext(), { PtrToInt8Ty, PtrToInt8Ty });
3219 auto MethodList = Builder.beginStruct();
3220 MethodList.addInt(IntTy, Methods.size());
3221 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
3222 for (
auto *M : Methods) {
3223 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
3224 Method.
add(MakeConstantString(M->getSelector().getAsString()));
3226 Method.finishAndAddTo(MethodArray);
3228 MethodArray.finishAndAddTo(MethodList);
3229 return MethodList.finishAndCreateGlobal(
".objc_method_list",
3238 auto ProtocolList = Builder.beginStruct();
3239 ProtocolList.add(NULLPtr);
3240 ProtocolList.addInt(LongTy, Protocols.size());
3242 auto Elements = ProtocolList.beginArray(PtrToInt8Ty);
3243 for (
const std::string *iter = Protocols.begin(), *endIter = Protocols.end();
3244 iter != endIter ; iter++) {
3245 llvm::Constant *protocol =
nullptr;
3246 llvm::StringMap<llvm::Constant*>::iterator value =
3247 ExistingProtocols.find(*iter);
3248 if (value == ExistingProtocols.end()) {
3249 protocol = GenerateEmptyProtocol(*iter);
3251 protocol = value->getValue();
3253 Elements.add(protocol);
3255 Elements.finishAndAddTo(ProtocolList);
3256 return ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
3262 auto protocol = GenerateProtocolRef(PD);
3265 return CGF.
Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(
T));
3268llvm::Constant *CGObjCGNU::GenerateProtocolRef(
const ObjCProtocolDecl *PD) {
3271 GenerateProtocol(PD);
3272 assert(protocol &&
"Unknown protocol");
3277CGObjCGNU::GenerateEmptyProtocol(StringRef ProtocolName) {
3278 llvm::Constant *ProtocolList = GenerateProtocolList({});
3279 llvm::Constant *MethodList = GenerateProtocolMethodList({});
3283 auto Elements = Builder.beginStruct();
3287 Elements.add(llvm::ConstantExpr::getIntToPtr(
3288 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3290 Elements.add(MakeConstantString(ProtocolName,
".objc_protocol_name"));
3291 Elements.add(ProtocolList);
3292 Elements.add(MethodList);
3293 Elements.add(MethodList);
3294 Elements.add(MethodList);
3295 Elements.add(MethodList);
3296 Elements.add(NULLPtr);
3297 Elements.add(NULLPtr);
3298 return Elements.finishAndCreateGlobal(SymbolForProtocol(ProtocolName),
3314 Protocols.push_back(PI->getNameAsString());
3318 if (I->isOptional())
3319 OptionalInstanceMethods.push_back(I);
3321 InstanceMethods.push_back(I);
3326 if (I->isOptional())
3327 OptionalClassMethods.push_back(I);
3329 ClassMethods.push_back(I);
3331 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
3332 llvm::Constant *InstanceMethodList =
3333 GenerateProtocolMethodList(InstanceMethods);
3334 llvm::Constant *ClassMethodList =
3335 GenerateProtocolMethodList(ClassMethods);
3336 llvm::Constant *OptionalInstanceMethodList =
3337 GenerateProtocolMethodList(OptionalInstanceMethods);
3338 llvm::Constant *OptionalClassMethodList =
3339 GenerateProtocolMethodList(OptionalClassMethods);
3347 llvm::Constant *PropertyList =
3348 GeneratePropertyList(
nullptr, PD,
false,
false);
3349 llvm::Constant *OptionalPropertyList =
3350 GeneratePropertyList(
nullptr, PD,
false,
true);
3357 auto Elements = Builder.beginStruct();
3359 llvm::ConstantExpr::getIntToPtr(
3360 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3361 Elements.add(MakeConstantString(ProtocolName));
3362 Elements.add(ProtocolList);
3363 Elements.add(InstanceMethodList);
3364 Elements.add(ClassMethodList);
3365 Elements.add(OptionalInstanceMethodList);
3366 Elements.add(OptionalClassMethodList);
3367 Elements.add(PropertyList);
3368 Elements.add(OptionalPropertyList);
3369 ExistingProtocols[ProtocolName] =
3370 Elements.finishAndCreateGlobal(
".objc_protocol", CGM.
getPointerAlign());
3372void CGObjCGNU::GenerateProtocolHolderCategory() {
3376 auto Elements = Builder.beginStruct();
3378 const std::string ClassName =
"__ObjC_Protocol_Holder_Ugly_Hack";
3379 const std::string CategoryName =
"AnotherHack";
3380 Elements.add(MakeConstantString(CategoryName));
3381 Elements.add(MakeConstantString(ClassName));
3383 Elements.add(GenerateMethodList(ClassName, CategoryName, {},
false));
3385 Elements.add(GenerateMethodList(ClassName, CategoryName, {},
true));
3389 auto ProtocolList = ProtocolListBuilder.beginStruct();
3390 ProtocolList.add(NULLPtr);
3391 ProtocolList.addInt(LongTy, ExistingProtocols.size());
3392 auto ProtocolElements = ProtocolList.beginArray(PtrTy);
3393 for (
auto iter = ExistingProtocols.begin(), endIter = ExistingProtocols.end();
3394 iter != endIter ; iter++) {
3395 ProtocolElements.add(iter->getValue());
3397 ProtocolElements.finishAndAddTo(ProtocolList);
3398 Elements.add(ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
3400 Categories.push_back(
3416 int bitCount = bits.size();
3418 if (bitCount < ptrBits) {
3420 for (
int i=0 ; i<bitCount ; ++i) {
3421 if (bits[i]) val |= 1ULL<<(i+1);
3423 return llvm::ConstantInt::get(IntPtrTy, val);
3427 while (
v < bitCount) {
3429 for (
int i=0 ; (i<32) && (
v<bitCount) ; ++i) {
3430 if (bits[
v]) word |= 1<<i;
3433 values.push_back(llvm::ConstantInt::get(Int32Ty, word));
3437 auto fields = builder.beginStruct();
3438 fields.addInt(Int32Ty, values.size());
3439 auto array = fields.beginArray();
3440 for (
auto *
v : values) array.add(
v);
3441 array.finishAndAddTo(fields);
3443 llvm::Constant *GS =
3445 llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy);
3449llvm::Constant *CGObjCGNU::GenerateCategoryProtocolList(
const
3452 const auto RuntimeProtos =
3453 GetRuntimeProtocolList(RefPro.begin(), RefPro.end());
3455 for (
const auto *PD : RuntimeProtos)
3457 return GenerateProtocolList(Protocols);
3462 std::string ClassName =
Class->getNameAsString();
3469 auto Elements = Builder.beginStruct();
3470 Elements.add(MakeConstantString(CategoryName));
3471 Elements.add(MakeConstantString(ClassName));
3474 InstanceMethods.insert(InstanceMethods.begin(), OCD->
instmeth_begin(),
3477 GenerateMethodList(ClassName, CategoryName, InstanceMethods,
false));
3484 Elements.add(GenerateMethodList(ClassName, CategoryName, ClassMethods,
true));
3487 Elements.add(GenerateCategoryProtocolList(CatDecl));
3493 Elements.add(GeneratePropertyList(OCD,
Category,
false));
3495 Elements.add(GeneratePropertyList(OCD,
Category,
true));
3497 Elements.addNullPointer(PtrTy);
3498 Elements.addNullPointer(PtrTy);
3502 Categories.push_back(Elements.finishAndCreateGlobal(
3503 std::string(
".objc_category_") + ClassName + CategoryName,
3507llvm::Constant *CGObjCGNU::GeneratePropertyList(
const Decl *Container,
3509 bool isClassProperty,
3510 bool protocolOptionalProperties) {
3514 bool isProtocol = isa<ObjCProtocolDecl>(OCD);
3517 std::function<void(
const ObjCProtocolDecl *Proto)> collectProtocolProperties
3519 for (
const auto *
P : Proto->protocols())
3520 collectProtocolProperties(
P);
3521 for (
const auto *PD : Proto->properties()) {
3522 if (isClassProperty != PD->isClassProperty())
3530 Properties.push_back(PD);
3536 for (
auto *PD : ClassExt->properties()) {
3537 if (isClassProperty != PD->isClassProperty())
3540 Properties.push_back(PD);
3544 if (isClassProperty != PD->isClassProperty())
3548 if (isProtocol && (protocolOptionalProperties != PD->isOptional()))
3555 Properties.push_back(PD);
3560 collectProtocolProperties(
P);
3562 for (
const auto *
P : CD->protocols())
3563 collectProtocolProperties(
P);
3565 auto numProperties = Properties.size();
3567 if (numProperties == 0)
3571 auto propertyList = builder.beginStruct();
3572 auto properties = PushPropertyListHeader(propertyList, numProperties);
3576 for (
auto *property : Properties) {
3577 bool isSynthesized =
false;
3578 bool isDynamic =
false;
3582 isSynthesized = (propertyImpl->getPropertyImplementation() ==
3584 isDynamic = (propertyImpl->getPropertyImplementation() ==
3588 PushProperty(properties, property, Container, isSynthesized, isDynamic);
3590 properties.finishAndAddTo(propertyList);
3592 return propertyList.finishAndCreateGlobal(
".objc_property_list",
3610 std::string SuperClassName;
3611 if (SuperClassDecl) {
3613 EmitClassRef(SuperClassName);
3623 std::string classSymbolName =
"__objc_class_name_" + ClassName;
3624 if (
auto *symbol = TheModule.getGlobalVariable(classSymbolName)) {
3625 symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0));
3627 new llvm::GlobalVariable(TheModule, LongTy,
false,
3628 llvm::GlobalValue::ExternalLinkage,
3629 llvm::ConstantInt::get(LongTy, 0),
3645 auto IvarOffsetValues = IvarOffsetBuilder.beginArray(PtrToIntTy);
3649 int superInstanceSize = !SuperClassDecl ? 0 :
3654 instanceSize = 0 - (instanceSize - superInstanceSize);
3660 IvarNames.push_back(MakeConstantString(IVD->getNameAsString()));
3662 std::string TypeStr;
3664 IvarTypes.push_back(MakeConstantString(TypeStr));
3665 IvarAligns.push_back(llvm::ConstantInt::get(IntTy,
3668 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
3671 Offset = BaseOffset - superInstanceSize;
3673 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
3675 std::string OffsetName =
"__objc_ivar_offset_value_" + ClassName +
"." +
3676 IVD->getNameAsString();
3678 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
3680 OffsetVar->setInitializer(OffsetValue);
3684 OffsetVar->setLinkage(llvm::GlobalValue::ExternalLinkage);
3686 OffsetVar =
new llvm::GlobalVariable(TheModule, Int32Ty,
3687 false, llvm::GlobalValue::ExternalLinkage,
3688 OffsetValue, OffsetName);
3689 IvarOffsets.push_back(OffsetValue);
3690 IvarOffsetValues.add(OffsetVar);
3692 IvarOwnership.push_back(lt);
3695 StrongIvars.push_back(
true);
3696 WeakIvars.push_back(
false);
3699 StrongIvars.push_back(
false);
3700 WeakIvars.push_back(
true);
3703 StrongIvars.push_back(
false);
3704 WeakIvars.push_back(
false);
3707 llvm::Constant *StrongIvarBitmap = MakeBitField(StrongIvars);
3708 llvm::Constant *WeakIvarBitmap = MakeBitField(WeakIvars);
3709 llvm::GlobalVariable *IvarOffsetArray =
3710 IvarOffsetValues.finishAndCreateGlobal(
".ivar.offsets",
3715 InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
3722 llvm::Constant *Properties = GeneratePropertyList(OID, ClassDecl);
3725 auto RefProtocols = ClassDecl->
protocols();
3726 auto RuntimeProtocols =
3727 GetRuntimeProtocolList(RefProtocols.begin(), RefProtocols.end());
3729 for (
const auto *I : RuntimeProtocols)
3730 Protocols.push_back(I->getNameAsString());
3733 llvm::Constant *SuperClass;
3734 if (!SuperClassName.empty()) {
3735 SuperClass = MakeConstantString(SuperClassName,
".super_class_name");
3737 SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty);
3742 llvm::Constant *MethodList = GenerateMethodList(ClassName,
"",
3743 InstanceMethods,
false);
3744 llvm::Constant *ClassMethodList = GenerateMethodList(ClassName,
"",
3745 ClassMethods,
true);
3746 llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
3747 IvarOffsets, IvarAligns, IvarOwnership);
3758 llvm::Type *IndexTy = Int32Ty;
3759 llvm::Constant *offsetPointerIndexes[] = {Zeros[0],
3760 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 2 : 1),
nullptr,
3761 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 3 : 2) };
3763 unsigned ivarIndex = 0;
3766 const std::string Name = GetIVarOffsetVariableName(ClassDecl, IVD);
3767 offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, ivarIndex);
3769 llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr(
3770 cast<llvm::GlobalVariable>(IvarList)->getValueType(), IvarList,
3771 offsetPointerIndexes);
3773 llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name);
3775 offset->setInitializer(offsetValue);
3779 offset->setLinkage(llvm::GlobalValue::ExternalLinkage);
3782 new llvm::GlobalVariable(TheModule, offsetValue->getType(),
3783 false, llvm::GlobalValue::ExternalLinkage, offsetValue, Name);
3786 llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0);
3789 llvm::Constant *MetaClassStruct = GenerateClassStructure(
3790 NULLPtr, NULLPtr, 0x12L, ClassName.c_str(),
nullptr, Zeros[0],
3791 NULLPtr, ClassMethodList, NULLPtr, NULLPtr,
3792 GeneratePropertyList(OID, ClassDecl,
true), ZeroPtr, ZeroPtr,
true);
3797 llvm::Constant *ClassStruct = GenerateClassStructure(
3798 MetaClassStruct, SuperClass, 0x11L, ClassName.c_str(),
nullptr,
3799 llvm::ConstantInt::get(LongTy, instanceSize), IvarList, MethodList,
3800 GenerateProtocolList(Protocols), IvarOffsetArray, Properties,
3801 StrongIvarBitmap, WeakIvarBitmap);
3806 if (ClassPtrAlias) {
3807 ClassPtrAlias->replaceAllUsesWith(ClassStruct);
3808 ClassPtrAlias->eraseFromParent();
3809 ClassPtrAlias =
nullptr;
3811 if (MetaClassPtrAlias) {
3812 MetaClassPtrAlias->replaceAllUsesWith(MetaClassStruct);
3813 MetaClassPtrAlias->eraseFromParent();
3814 MetaClassPtrAlias =
nullptr;
3818 Classes.push_back(ClassStruct);
3821llvm::Function *CGObjCGNU::ModuleInitFunction() {
3823 if (Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
3828 GenerateProtocolHolderCategory();
3830 llvm::StructType *selStructTy = dyn_cast<llvm::StructType>(SelectorElemTy);
3833 { PtrToInt8Ty, PtrToInt8Ty });
3837 llvm::Constant *statics = NULLPtr;
3838 if (!ConstantStrings.empty()) {
3839 llvm::GlobalVariable *fileStatics = [&] {
3841 auto staticsStruct = builder.beginStruct();
3844 if (stringClass.empty()) stringClass =
"NXConstantString";
3845 staticsStruct.add(MakeConstantString(stringClass,
3846 ".objc_static_class_name"));
3848 auto array = staticsStruct.beginArray();
3849 array.addAll(ConstantStrings);
3851 array.finishAndAddTo(staticsStruct);
3853 return staticsStruct.finishAndCreateGlobal(
".objc_statics",
3858 auto allStaticsArray = builder.beginArray(fileStatics->getType());
3859 allStaticsArray.add(fileStatics);
3860 allStaticsArray.addNullPointer(fileStatics->getType());
3862 statics = allStaticsArray.finishAndCreateGlobal(
".objc_statics_ptr",
3869 unsigned selectorCount;
3872 llvm::GlobalVariable *selectorList = [&] {
3874 auto selectors = builder.beginArray(selStructTy);
3876 std::vector<Selector> allSelectors;
3877 for (
auto &entry : table)
3878 allSelectors.push_back(entry.first);
3879 llvm::sort(allSelectors);
3881 for (
auto &untypedSel : allSelectors) {
3882 std::string selNameStr = untypedSel.getAsString();
3883 llvm::Constant *selName = ExportUniqueString(selNameStr,
".objc_sel_name");
3885 for (TypedSelector &sel : table[untypedSel]) {
3886 llvm::Constant *selectorTypeEncoding = NULLPtr;
3887 if (!sel.first.empty())
3888 selectorTypeEncoding =
3889 MakeConstantString(sel.first,
".objc_sel_types");
3891 auto selStruct = selectors.beginStruct(selStructTy);
3892 selStruct.add(selName);
3893 selStruct.add(selectorTypeEncoding);
3894 selStruct.finishAndAddTo(selectors);
3897 selectorAliases.push_back(sel.second);
3902 selectorCount = selectors.size();
3908 auto selStruct = selectors.beginStruct(selStructTy);
3909 selStruct.add(NULLPtr);
3910 selStruct.add(NULLPtr);
3911 selStruct.finishAndAddTo(selectors);
3913 return selectors.finishAndCreateGlobal(
".objc_selector_list",
3918 for (
unsigned i = 0; i < selectorCount; ++i) {
3919 llvm::Constant *idxs[] = {
3921 llvm::ConstantInt::get(Int32Ty, i)
3924 llvm::Constant *selPtr = llvm::ConstantExpr::getGetElementPtr(
3925 selectorList->getValueType(), selectorList, idxs);
3926 selectorAliases[i]->replaceAllUsesWith(selPtr);
3927 selectorAliases[i]->eraseFromParent();
3930 llvm::GlobalVariable *symtab = [&] {
3932 auto symtab = builder.beginStruct();
3935 symtab.addInt(LongTy, selectorCount);
3937 symtab.add(selectorList);
3940 symtab.addInt(CGM.
Int16Ty, Classes.size());
3942 symtab.addInt(CGM.
Int16Ty, Categories.size());
3945 auto classList = symtab.beginArray(PtrToInt8Ty);
3946 classList.addAll(Classes);
3947 classList.addAll(Categories);
3949 classList.add(statics);
3950 classList.add(NULLPtr);
3951 classList.finishAndAddTo(symtab);
3959 llvm::Constant *module = [&] {
3960 llvm::Type *moduleEltTys[] = {
3961 LongTy, LongTy, PtrToInt8Ty, symtab->getType(), IntTy
3963 llvm::StructType *moduleTy = llvm::StructType::get(
3965 ArrayRef(moduleEltTys).drop_back(
unsigned(RuntimeVersion < 10)));
3968 auto module = builder.beginStruct(moduleTy);
3970 module.addInt(LongTy, RuntimeVersion);
3972 module.addInt(LongTy, CGM.
getDataLayout().getTypeStoreSize(moduleTy));
3979 module.add(MakeConstantString(path,
".objc_source_file_name"));
3982 if (RuntimeVersion >= 10) {
3984 case LangOptions::GCOnly:
3985 module.addInt(IntTy, 2);
3987 case LangOptions::NonGC:
3989 module.addInt(IntTy, 1);
3991 module.addInt(IntTy, 0);
3993 case LangOptions::HybridGC:
3994 module.addInt(IntTy, 1);
4004 llvm::Function * LoadFunction = llvm::Function::Create(
4005 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
4006 llvm::GlobalValue::InternalLinkage,
".objc_load_function",
4008 llvm::BasicBlock *EntryBB =
4009 llvm::BasicBlock::Create(VMContext,
"entry", LoadFunction);
4011 Builder.SetInsertPoint(EntryBB);
4013 llvm::FunctionType *FT =
4014 llvm::FunctionType::get(Builder.getVoidTy(), module->getType(),
true);
4015 llvm::FunctionCallee Register =
4017 Builder.CreateCall(Register, module);
4019 if (!ClassAliases.empty()) {
4020 llvm::Type *ArgTypes[2] = {PtrTy, PtrToInt8Ty};
4021 llvm::FunctionType *RegisterAliasTy =
4022 llvm::FunctionType::get(Builder.getVoidTy(),
4024 llvm::Function *RegisterAlias = llvm::Function::Create(
4026 llvm::GlobalValue::ExternalWeakLinkage,
"class_registerAlias_np",
4028 llvm::BasicBlock *AliasBB =
4029 llvm::BasicBlock::Create(VMContext,
"alias", LoadFunction);
4030 llvm::BasicBlock *NoAliasBB =
4031 llvm::BasicBlock::Create(VMContext,
"no_alias", LoadFunction);
4034 llvm::Value *HasRegisterAlias = Builder.CreateICmpNE(RegisterAlias,
4035 llvm::Constant::getNullValue(RegisterAlias->getType()));
4036 Builder.CreateCondBr(HasRegisterAlias, AliasBB, NoAliasBB);
4039 Builder.SetInsertPoint(AliasBB);
4041 for (std::vector<ClassAliasPair>::iterator iter = ClassAliases.begin();
4042 iter != ClassAliases.end(); ++iter) {
4043 llvm::Constant *TheClass =
4044 TheModule.getGlobalVariable(
"_OBJC_CLASS_" + iter->first,
true);
4046 Builder.CreateCall(RegisterAlias,
4047 {TheClass, MakeConstantString(iter->second)});
4051 Builder.CreateBr(NoAliasBB);
4054 Builder.SetInsertPoint(NoAliasBB);
4056 Builder.CreateRetVoid();
4058 return LoadFunction;
4061llvm::Function *CGObjCGNU::GenerateMethod(
const ObjCMethodDecl *OMD,
4064 llvm::FunctionType *MethodTy =
4065 Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
4068 std::string FunctionName =
4069 getSymbolNameForMethod(OMD, !isDirect);
4072 return llvm::Function::Create(MethodTy,
4073 llvm::GlobalVariable::InternalLinkage,
4074 FunctionName, &TheModule);
4077 auto I = DirectMethodDefinitions.find(COMD);
4078 llvm::Function *OldFn =
nullptr, *
Fn =
nullptr;
4080 if (I == DirectMethodDefinitions.end()) {
4082 llvm::Function::Create(MethodTy, llvm::GlobalVariable::ExternalLinkage,
4083 FunctionName, &TheModule);
4084 DirectMethodDefinitions.insert(std::make_pair(COMD, F));
4101 Fn = llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,
"",
4103 Fn->takeName(OldFn);
4104 OldFn->replaceAllUsesWith(Fn);
4105 OldFn->eraseFromParent();
4119llvm::FunctionCallee CGObjCGNU::GetPropertyGetFunction() {
4120 return GetPropertyFn;
4123llvm::FunctionCallee CGObjCGNU::GetPropertySetFunction() {
4124 return SetPropertyFn;
4127llvm::FunctionCallee CGObjCGNU::GetOptimizedPropertySetFunction(
bool atomic,
4132llvm::FunctionCallee CGObjCGNU::GetGetStructFunction() {
4133 return GetStructPropertyFn;
4136llvm::FunctionCallee CGObjCGNU::GetSetStructFunction() {
4137 return SetStructPropertyFn;
4140llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectGetFunction() {
4144llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectSetFunction() {
4148llvm::FunctionCallee CGObjCGNU::EnumerationMutationFunction() {
4149 return EnumerationMutationFn;
4154 EmitAtSynchronizedStmt(CGF, S, SyncEnterFn, SyncExitFn);
4171 EmitTryCatchStmt(CGF, S, EnterCatchFn, ExitCatchFn, ExceptionReThrowFn);
4176 bool ClearInsertionPoint) {
4177 llvm::Value *ExceptionAsObject;
4178 bool isRethrow =
false;
4180 if (
const Expr *ThrowExpr = S.getThrowExpr()) {
4182 ExceptionAsObject = Exception;
4185 "Unexpected rethrow outside @catch block.");
4189 if (isRethrow && (usesSEHExceptions || usesCxxExceptions)) {
4198 Throw->setDoesNotReturn();
4200 ExceptionAsObject = CGF.
Builder.CreateBitCast(ExceptionAsObject, IdTy);
4201 llvm::CallBase *Throw =
4203 Throw->setDoesNotReturn();
4205 CGF.
Builder.CreateUnreachable();
4206 if (ClearInsertionPoint)
4207 CGF.
Builder.ClearInsertionPoint();
4213 return B.CreateCall(
4214 WeakReadFn, EnforceType(B, AddrWeakObj.
emitRawPointer(CGF), PtrToIdTy));
4218 llvm::Value *src,
Address dst) {
4220 src = EnforceType(B, src, IdTy);
4221 llvm::Value *dstVal = EnforceType(B, dst.
emitRawPointer(CGF), PtrToIdTy);
4222 B.CreateCall(WeakAssignFn, {src, dstVal});
4226 llvm::Value *src,
Address dst,
4229 src = EnforceType(B, src, IdTy);
4230 llvm::Value *dstVal = EnforceType(B, dst.
emitRawPointer(CGF), PtrToIdTy);
4232 assert(!threadlocal &&
"EmitObjCGlobalAssign - Threal Local API NYI");
4233 B.CreateCall(GlobalAssignFn, {src, dstVal});
4237 llvm::Value *src,
Address dst,
4238 llvm::Value *ivarOffset) {
4240 src = EnforceType(B, src, IdTy);
4241 llvm::Value *dstVal = EnforceType(B, dst.
emitRawPointer(CGF), IdTy);
4242 B.CreateCall(IvarAssignFn, {src, dstVal, ivarOffset});
4246 llvm::Value *src,
Address dst) {
4248 src = EnforceType(B, src, IdTy);
4249 llvm::Value *dstVal = EnforceType(B, dst.
emitRawPointer(CGF), PtrToIdTy);
4250 B.CreateCall(StrongCastAssignFn, {src, dstVal});
4256 llvm::Value *Size) {
4258 llvm::Value *DestPtrVal = EnforceType(B, DestPtr.
emitRawPointer(CGF), PtrTy);
4259 llvm::Value *SrcPtrVal = EnforceType(B, SrcPtr.
emitRawPointer(CGF), PtrTy);
4261 B.CreateCall(MemMoveFn, {DestPtrVal, SrcPtrVal,
Size});
4264llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
4267 const std::string Name = GetIVarOffsetVariableName(ID, Ivar);
4271 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
4272 if (!IvarOffsetPointer)
4273 IvarOffsetPointer =
new llvm::GlobalVariable(
4274 TheModule, llvm::PointerType::getUnqual(VMContext),
false,
4275 llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
4276 return IvarOffsetPointer;
4281 llvm::Value *BaseValue,
4283 unsigned CVRQualifiers) {
4286 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
4287 EmitIvarOffset(CGF, ID, Ivar));
4315 if (RuntimeVersion < 10 ||
4317 return CGF.
Builder.CreateZExtOrBitCast(
4321 llvm::PointerType::getUnqual(VMContext),
4322 ObjCIvarOffsetVariable(
Interface, Ivar),
4326 std::string
name =
"__objc_ivar_offset_value_" +
4329 llvm::Value *Offset = TheModule.getGlobalVariable(name);
4331 auto GV =
new llvm::GlobalVariable(TheModule, IntTy,
4332 false, llvm::GlobalValue::LinkOnceAnyLinkage,
4333 llvm::Constant::getNullValue(IntTy), name);
4338 if (Offset->getType() != PtrDiffTy)
4339 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
4343 return llvm::ConstantInt::get(PtrDiffTy, Offset,
true);
4349 switch (Runtime.getKind()) {
4351 if (Runtime.getVersion() >= VersionTuple(2, 0))
4352 return new CGObjCGNUstep2(CGM);
4353 return new CGObjCGNUstep(CGM);
4356 return new CGObjCGCC(CGM);
4359 return new CGObjCObjFW(CGM);
4365 llvm_unreachable(
"these runtimes are not GNU runtimes");
4367 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, bool IsVirtualFunctionPointerThunk=false)
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
bool ReturnTypeHasInReg(const CGFunctionInfo &FI)
Return true iff the given type has inreg set.
ASTContext & getContext() const
bool ReturnTypeUsesSRet(const CGFunctionInfo &FI)
Return true iff the given type uses 'sret' when used as a return type.
const CodeGenOptions & getCodeGenOpts() const
llvm::LLVMContext & getLLVMContext()
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
ConstantAddress GetAddrOfConstantCString(const std::string &Str, const char *GlobalName=nullptr)
Returns a pointer to a character array containing the literal and a terminating '\0' character.
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
bool isZeroInitializable(QualType T)
IsZeroInitializable - Return whether a type can be zero-initialized (in the C++ sense) with an LLVM z...
A specialization of Address that requires the address to be an LLVM Constant.
ArrayBuilder beginArray(llvm::Type *eltTy=nullptr)
llvm::GlobalVariable * finishAndCreateGlobal(As &&...args)
Given that this builder was created by beginning an array or struct directly on a ConstantInitBuilder...
StructBuilder beginStruct(llvm::StructType *ty=nullptr)
void finishAndAddTo(AggregateBuilderBase &parent)
Given that this builder was created by beginning an array or struct component on the given parent bui...
A helper class of ConstantInitBuilder, used for building constant array initializers.
The standard implementation of ConstantInitBuilder used in Clang.
A helper class of ConstantInitBuilder, used for building constant struct initializers.
LValue - This represents an lvalue references.
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
An abstract representation of an aligned address.
llvm::Value * getPointer() const
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
Decl - This represents one declaration (or definition), e.g.
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
StringRef getName() const
This represents one expression.
StringRef getName() const
The name of this FileEntry.
DirectoryEntryRef getDir() const
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
std::string ObjCConstantStringClass
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Visibility getVisibility() const
Determines the visibility of this entity.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
Represents Objective-C's @synchronized statement.
Represents Objective-C's @throw statement.
Represents Objective-C's @try ... @catch ... @finally statement.
ObjCCategoryDecl - Represents a category declaration.
const ObjCProtocolList & getReferencedProtocols() const
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
ObjCCategoryDecl * getCategoryDecl() const
ObjCCompatibleAliasDecl - Represents alias of a class.
const ObjCInterfaceDecl * getClassInterface() const
ObjCContainerDecl - Represents a container for method declarations.
classmeth_iterator classmeth_end() const
classmeth_iterator classmeth_begin() const
instmeth_range instance_methods() const
instmeth_iterator instmeth_end() const
instmeth_iterator instmeth_begin() const
prop_range properties() const
classmeth_range class_methods() const
propimpl_range property_impls() const
const ObjCInterfaceDecl * getClassInterface() const
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Represents an ObjC class declaration.
all_protocol_range all_referenced_protocols() const
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
protocol_range protocols() const
protocol_iterator protocol_end() const
protocol_iterator protocol_begin() const
ObjCInterfaceDecl * getSuperClass() const
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
known_extensions_range known_extensions() const
Interfaces are the core concept in Objective-C for object oriented design.
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
ObjCIvarDecl - Represents an ObjC instance variable.
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