31#include "llvm/ADT/SmallVector.h"
32#include "llvm/ADT/StringMap.h"
33#include "llvm/IR/DataLayout.h"
34#include "llvm/IR/Intrinsics.h"
35#include "llvm/IR/LLVMContext.h"
36#include "llvm/IR/Module.h"
37#include "llvm/Support/Compiler.h"
38#include "llvm/Support/ConvertUTF.h"
42using namespace CodeGen;
49class LazyRuntimeFunction {
51 llvm::FunctionType *FTy =
nullptr;
52 const char *FunctionName =
nullptr;
53 llvm::FunctionCallee
Function =
nullptr;
56 LazyRuntimeFunction() =
default;
60 template <
typename... Tys>
61 void init(
CodeGenModule *Mod,
const char *name, llvm::Type *RetTy,
68 FTy = llvm::FunctionType::get(RetTy, ArgTys,
false);
71 FTy = llvm::FunctionType::get(RetTy, {},
false);
75 llvm::FunctionType *getType() {
return FTy; }
79 operator llvm::FunctionCallee() {
96 llvm::Module &TheModule;
99 llvm::StructType *ObjCSuperTy;
102 llvm::PointerType *PtrToObjCSuperTy;
106 llvm::PointerType *SelectorTy;
108 llvm::Type *SelectorElemTy;
111 llvm::IntegerType *Int8Ty;
114 llvm::PointerType *PtrToInt8Ty;
116 llvm::StructType *ProtocolTy;
118 llvm::PointerType *ProtocolPtrTy;
124 llvm::PointerType *IMPTy;
129 llvm::PointerType *IdTy;
131 llvm::Type *IdElemTy;
134 llvm::PointerType *PtrToIdTy;
139 llvm::IntegerType *IntTy;
143 llvm::PointerType *PtrTy;
147 llvm::IntegerType *LongTy;
149 llvm::IntegerType *SizeTy;
151 llvm::IntegerType *IntPtrTy;
153 llvm::IntegerType *PtrDiffTy;
156 llvm::PointerType *PtrToIntTy;
160 llvm::IntegerType *Int32Ty;
162 llvm::IntegerType *Int64Ty;
164 llvm::StructType *PropertyMetadataTy;
168 unsigned msgSendMDKind;
171 bool usesSEHExceptions;
173 bool usesCxxExceptions;
178 return (R.
getKind() == kind) &&
179 (R.
getVersion() >= VersionTuple(major, minor));
182 std::string ManglePublicSymbol(StringRef Name) {
183 return (StringRef(CGM.
getTriple().isOSBinFormatCOFF() ?
"$_" :
"._") + Name).str();
186 std::string SymbolForProtocol(Twine Name) {
187 return (ManglePublicSymbol(
"OBJC_PROTOCOL_") + Name).str();
190 std::string SymbolForProtocolRef(StringRef Name) {
191 return (ManglePublicSymbol(
"OBJC_REF_PROTOCOL_") + Name).str();
198 llvm::Constant *MakeConstantString(StringRef Str,
const char *Name =
"") {
201 return Array.getPointer();
208 llvm::Constant *ExportUniqueString(
const std::string &Str,
209 const std::string &prefix,
210 bool Private=
false) {
211 std::string
name = prefix + Str;
212 auto *ConstStr = TheModule.getGlobalVariable(name);
214 llvm::Constant *value = llvm::ConstantDataArray::getString(VMContext,Str);
215 auto *GV =
new llvm::GlobalVariable(TheModule, value->getType(),
true,
216 llvm::GlobalValue::LinkOnceODRLinkage, value, name);
217 GV->setComdat(TheModule.getOrInsertComdat(name));
219 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
227 const Decl *Container) {
230 std::string NameAndAttributes;
231 std::string TypeStr =
233 NameAndAttributes +=
'\0';
234 NameAndAttributes += TypeStr.length() + 3;
235 NameAndAttributes += TypeStr;
236 NameAndAttributes +=
'\0';
238 return MakeConstantString(NameAndAttributes);
247 int attrs =
property->getPropertyAttributes();
250 attrs &= ~ObjCPropertyAttribute::kind_copy;
251 attrs &= ~ObjCPropertyAttribute::kind_retain;
252 attrs &= ~ObjCPropertyAttribute::kind_weak;
253 attrs &= ~ObjCPropertyAttribute::kind_strong;
256 Fields.addInt(Int8Ty, attrs & 0xff);
262 attrs |= isSynthesized ? (1<<0) : 0;
263 attrs |= isDynamic ? (1<<1) : 0;
266 Fields.addInt(Int8Ty, attrs & 0xff);
268 Fields.addInt(Int8Ty, 0);
269 Fields.addInt(Int8Ty, 0);
272 virtual llvm::Constant *GenerateCategoryProtocolList(
const
277 Fields.addInt(IntTy, count);
280 const llvm::DataLayout &DL = TheModule.getDataLayout();
281 Fields.addInt(IntTy, DL.getTypeSizeInBits(PropertyMetadataTy) /
292 bool isSynthesized=
true,
bool
294 auto Fields = PropertiesArray.
beginStruct(PropertyMetadataTy);
296 Fields.add(MakePropertyEncodingString(property, OCD));
297 PushPropertyAttributes(Fields, property, isSynthesized, isDynamic);
301 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
302 Fields.add(MakeConstantString(accessor->getSelector().getAsString()));
303 Fields.add(TypeEncoding);
317 llvm::Value *EnforceType(
CGBuilderTy &B, llvm::Value *
V, llvm::Type *Ty) {
318 if (
V->getType() == Ty)
320 return B.CreateBitCast(
V, Ty);
324 llvm::Constant *Zeros[2];
326 llvm::Constant *NULLPtr;
328 llvm::LLVMContext &VMContext;
336 llvm::GlobalAlias *ClassPtrAlias;
341 llvm::GlobalAlias *MetaClassPtrAlias;
343 std::vector<llvm::Constant*> Classes;
345 std::vector<llvm::Constant*> Categories;
348 std::vector<llvm::Constant*> ConstantStrings;
352 llvm::StringMap<llvm::Constant*> ObjCStrings;
354 llvm::StringMap<llvm::Constant*> ExistingProtocols;
360 typedef std::pair<std::string, llvm::GlobalAlias*> TypedSelector;
364 typedef llvm::DenseMap<Selector, SmallVector<TypedSelector, 2> >
372 Selector RetainSel, ReleaseSel, AutoreleaseSel;
376 LazyRuntimeFunction IvarAssignFn, StrongCastAssignFn, MemMoveFn, WeakReadFn,
377 WeakAssignFn, GlobalAssignFn;
379 typedef std::pair<std::string, std::string> ClassAliasPair;
381 std::vector<ClassAliasPair> ClassAliases;
385 LazyRuntimeFunction ExceptionThrowFn;
388 LazyRuntimeFunction ExceptionReThrowFn;
391 LazyRuntimeFunction EnterCatchFn;
394 LazyRuntimeFunction ExitCatchFn;
396 LazyRuntimeFunction SyncEnterFn;
398 LazyRuntimeFunction SyncExitFn;
403 LazyRuntimeFunction EnumerationMutationFn;
406 LazyRuntimeFunction GetPropertyFn;
409 LazyRuntimeFunction SetPropertyFn;
411 LazyRuntimeFunction GetStructPropertyFn;
413 LazyRuntimeFunction SetStructPropertyFn;
425 const int ProtocolVersion;
428 const int ClassABIVersion;
444 llvm::Constant *GenerateMethodList(StringRef ClassName,
445 StringRef CategoryName,
447 bool isClassMethodList);
452 virtual llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName);
456 llvm::Constant *GeneratePropertyList(
const Decl *Container,
458 bool isClassProperty=
false,
459 bool protocolOptionalProperties=
false);
469 void GenerateProtocolHolderCategory();
472 llvm::Constant *GenerateClassStructure(
473 llvm::Constant *MetaClass,
474 llvm::Constant *SuperClass,
477 llvm::Constant *Version,
478 llvm::Constant *InstanceSize,
479 llvm::Constant *IVars,
480 llvm::Constant *Methods,
481 llvm::Constant *Protocols,
482 llvm::Constant *IvarOffsets,
483 llvm::Constant *Properties,
484 llvm::Constant *StrongIvarBitmap,
485 llvm::Constant *WeakIvarBitmap,
490 virtual llvm::Constant *GenerateProtocolMethodList(
494 void EmitProtocolMethodList(
T &&Methods, llvm::Constant *&
Required,
498 for (
const auto *I : Methods)
500 OptionalMethods.push_back(I);
502 RequiredMethods.push_back(I);
503 Required = GenerateProtocolMethodList(RequiredMethods);
504 Optional = GenerateProtocolMethodList(OptionalMethods);
510 const std::string &TypeEncoding);
517 const std::string Name =
"__objc_ivar_offset_" +
ID->getNameAsString()
526 void EmitClassRef(
const std::string &className);
530 const std::string &Name,
bool isWeak);
536 llvm::Value *&Receiver,
539 MessageSendInfo &MSI) = 0;
547 MessageSendInfo &MSI) = 0;
564 unsigned protocolClassVersion,
unsigned classABI=1);
571 llvm::Value *Receiver,
const CallArgList &CallArgs,
578 bool isCategoryImpl, llvm::Value *Receiver,
587 virtual llvm::Constant *GetConstantSelector(
Selector Sel,
588 const std::string &TypeEncoding) {
589 llvm_unreachable(
"Runtime unable to generate constant selector");
601 llvm::DenseMap<const ObjCMethodDecl *, llvm::Function *>
602 DirectMethodDefinitions;
636 bool ClearInsertionPoint=
true)
override;
640 llvm::Value *src,
Address dst)
override;
642 llvm::Value *src,
Address dest,
643 bool threadlocal=
false)
override;
645 Address dest, llvm::Value *ivarOffset)
override;
647 llvm::Value *src,
Address dest)
override;
650 llvm::Value *Size)
override;
653 unsigned CVRQualifiers)
override;
680class CGObjCGCC :
public CGObjCGNU {
683 LazyRuntimeFunction MsgLookupFn;
687 LazyRuntimeFunction MsgLookupSuperFn;
691 llvm::Value *cmd, llvm::MDNode *node,
692 MessageSendInfo &MSI)
override {
694 llvm::Value *args[] = {
695 EnforceType(Builder, Receiver, IdTy),
696 EnforceType(Builder, cmd, SelectorTy) };
698 imp->setMetadata(msgSendMDKind, node);
703 llvm::Value *cmd, MessageSendInfo &MSI)
override {
705 llvm::Value *lookupArgs[] = {
706 EnforceType(Builder, ObjCSuper.
emitRawPointer(CGF), PtrToObjCSuperTy),
714 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
716 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
717 PtrToObjCSuperTy, SelectorTy);
722class CGObjCGNUstep :
public CGObjCGNU {
725 LazyRuntimeFunction SlotLookupFn;
730 LazyRuntimeFunction SlotLookupSuperFn;
732 LazyRuntimeFunction SetPropertyAtomic;
734 LazyRuntimeFunction SetPropertyAtomicCopy;
736 LazyRuntimeFunction SetPropertyNonAtomic;
738 LazyRuntimeFunction SetPropertyNonAtomicCopy;
741 LazyRuntimeFunction CxxAtomicObjectGetFn;
744 LazyRuntimeFunction CxxAtomicObjectSetFn;
749 llvm::Type *SlotStructTy;
752 llvm::Constant *GetEHType(
QualType T)
override;
756 llvm::Value *cmd, llvm::MDNode *node,
757 MessageSendInfo &MSI)
override {
759 llvm::FunctionCallee LookupFn = SlotLookupFn;
764 Builder.CreateStore(Receiver, ReceiverPtr);
771 self = llvm::ConstantPointerNull::get(IdTy);
775 if (
auto *LookupFn2 = dyn_cast<llvm::Function>(LookupFn.getCallee()))
776 LookupFn2->addParamAttr(0, llvm::Attribute::NoCapture);
778 llvm::Value *args[] = {
779 EnforceType(Builder, ReceiverPtr.
getPointer(), PtrToIdTy),
780 EnforceType(Builder, cmd, SelectorTy),
781 EnforceType(Builder, self, IdTy)};
783 slot->setOnlyReadsMemory();
784 slot->setMetadata(msgSendMDKind, node);
787 llvm::Value *imp = Builder.CreateAlignedLoad(
788 IMPTy, Builder.CreateStructGEP(SlotStructTy, slot, 4),
793 Receiver = Builder.CreateLoad(ReceiverPtr,
true);
799 MessageSendInfo &MSI)
override {
803 llvm::CallInst *slot =
805 slot->setOnlyReadsMemory();
807 return Builder.CreateAlignedLoad(
808 IMPTy, Builder.CreateStructGEP(SlotStructTy, slot, 4),
813 CGObjCGNUstep(
CodeGenModule &Mod) : CGObjCGNUstep(Mod, 9, 3, 1) {}
814 CGObjCGNUstep(
CodeGenModule &Mod,
unsigned ABI,
unsigned ProtocolABI,
816 CGObjCGNU(Mod, ABI, ProtocolABI, ClassABI) {
819 SlotStructTy = llvm::StructType::get(PtrTy, PtrTy, PtrTy, IntTy, IMPTy);
820 SlotTy = llvm::PointerType::getUnqual(SlotStructTy);
822 SlotLookupFn.init(&CGM,
"objc_msg_lookup_sender", SlotTy, PtrToIdTy,
825 SlotLookupSuperFn.init(&CGM,
"objc_slot_lookup_super", SlotTy,
826 PtrToObjCSuperTy, SelectorTy);
828 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
829 if (usesCxxExceptions) {
831 EnterCatchFn.init(&CGM,
"__cxa_begin_catch", PtrTy, PtrTy);
833 ExitCatchFn.init(&CGM,
"__cxa_end_catch", VoidTy);
835 ExceptionReThrowFn.init(&CGM,
"__cxa_rethrow", PtrTy);
836 }
else if (usesSEHExceptions) {
838 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy);
841 EnterCatchFn.init(&CGM,
"__cxa_begin_catch", PtrTy, PtrTy);
843 ExitCatchFn.init(&CGM,
"__cxa_end_catch", VoidTy);
845 ExceptionReThrowFn.init(&CGM,
"_Unwind_Resume_or_Rethrow", VoidTy,
847 }
else if (R.
getVersion() >= VersionTuple(1, 7)) {
849 EnterCatchFn.init(&CGM,
"objc_begin_catch", IdTy, PtrTy);
851 ExitCatchFn.init(&CGM,
"objc_end_catch", VoidTy);
853 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy, PtrTy);
855 SetPropertyAtomic.init(&CGM,
"objc_setProperty_atomic", VoidTy, IdTy,
856 SelectorTy, IdTy, PtrDiffTy);
857 SetPropertyAtomicCopy.init(&CGM,
"objc_setProperty_atomic_copy", VoidTy,
858 IdTy, SelectorTy, IdTy, PtrDiffTy);
859 SetPropertyNonAtomic.init(&CGM,
"objc_setProperty_nonatomic", VoidTy,
860 IdTy, SelectorTy, IdTy, PtrDiffTy);
861 SetPropertyNonAtomicCopy.init(&CGM,
"objc_setProperty_nonatomic_copy",
862 VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy);
865 CxxAtomicObjectSetFn.init(&CGM,
"objc_setCppObjectAtomic", VoidTy, PtrTy,
869 CxxAtomicObjectGetFn.init(&CGM,
"objc_getCppObjectAtomic", VoidTy, PtrTy,
873 llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override {
878 return CxxAtomicObjectGetFn;
881 llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override {
886 return CxxAtomicObjectSetFn;
889 llvm::FunctionCallee GetOptimizedPropertySetFunction(
bool atomic,
890 bool copy)
override {
894 assert ((CGM.
getLangOpts().getGC() == LangOptions::NonGC));
901 if (copy)
return SetPropertyAtomicCopy;
902 return SetPropertyAtomic;
905 return copy ? SetPropertyNonAtomicCopy : SetPropertyNonAtomic;
912class CGObjCGNUstep2 :
public CGObjCGNUstep {
917 ClassReferenceSection,
920 ProtocolReferenceSection,
922 ConstantStringSection
927 ClassFlagMeta = (1 << 0),
930 ClassFlagInitialized = (1 << 8),
932 static const char *
const SectionsBaseNames[8];
933 static const char *
const PECOFFSectionsBaseNames[8];
934 template<SectionKind K>
935 std::string sectionName() {
936 if (CGM.
getTriple().isOSBinFormatCOFF()) {
937 std::string
name(PECOFFSectionsBaseNames[K]);
941 return SectionsBaseNames[K];
946 LazyRuntimeFunction MsgLookupSuperFn;
948 LazyRuntimeFunction SentInitializeFn;
952 bool EmittedProtocol =
false;
957 bool EmittedProtocolRef =
false;
961 bool EmittedClass =
false;
965 typedef std::pair<std::string, std::pair<llvm::GlobalVariable*, int>>
967 std::vector<EarlyInitPair> EarlyInitList;
969 std::string SymbolForClassRef(StringRef Name,
bool isWeak) {
971 return (ManglePublicSymbol(
"OBJC_WEAK_REF_CLASS_") + Name).str();
973 return (ManglePublicSymbol(
"OBJC_REF_CLASS_") + Name).str();
976 std::string SymbolForClass(StringRef Name) {
977 return (ManglePublicSymbol(
"OBJC_CLASS_") + Name).str();
979 void CallRuntimeFunction(
CGBuilderTy &B, StringRef FunctionName,
982 for (
auto *Arg : Args)
983 Types.push_back(Arg->getType());
984 llvm::FunctionType *FT = llvm::FunctionType::get(B.getVoidTy(), Types,
987 B.CreateCall(Fn, Args);
996 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
997 if (old != ObjCStrings.end())
1005 (LiteralLength < 9) && !isNonASCII) {
1011 for (
unsigned i=0 ; i<LiteralLength ; i++)
1012 str |= ((uint64_t)SL->
getCodeUnit(i)) << ((64 - 4 - 3) - (i*7));
1014 str |= LiteralLength << 3;
1017 auto *ObjCStr = llvm::ConstantExpr::getIntToPtr(
1018 llvm::ConstantInt::get(Int64Ty, str), IdTy);
1019 ObjCStrings[Str] = ObjCStr;
1025 if (StringClass.empty()) StringClass =
"NSConstantString";
1027 std::string Sym = SymbolForClass(StringClass);
1029 llvm::Constant *
isa = TheModule.getNamedGlobal(Sym);
1032 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
1033 llvm::GlobalValue::ExternalLinkage,
nullptr, Sym);
1034 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1035 cast<llvm::GlobalValue>(isa)->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
1050 auto Fields = Builder.beginStruct();
1051 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
1054 Fields.addNullPointer(PtrTy);
1061 unsigned NumU8CodeUnits = Str.size();
1066 const llvm::UTF8 *FromPtr = (
const llvm::UTF8 *)Str.data();
1067 llvm::UTF16 *ToPtr = &ToBuf[0];
1068 (void)llvm::ConvertUTF8toUTF16(&FromPtr, FromPtr + NumU8CodeUnits,
1069 &ToPtr, ToPtr + NumU8CodeUnits, llvm::strictConversion);
1070 uint32_t StringLength = ToPtr - &ToBuf[0];
1074 Fields.addInt(Int32Ty, 2);
1076 Fields.addInt(Int32Ty, StringLength);
1078 Fields.addInt(Int32Ty, StringLength * 2);
1080 Fields.addInt(Int32Ty, 0);
1083 auto *
C = llvm::ConstantDataArray::get(VMContext, Arr);
1084 auto *Buffer =
new llvm::GlobalVariable(TheModule,
C->getType(),
1085 true, llvm::GlobalValue::PrivateLinkage,
C,
".str");
1086 Buffer->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1090 Fields.addInt(Int32Ty, 0);
1092 Fields.addInt(Int32Ty, Str.size());
1094 Fields.addInt(Int32Ty, Str.size());
1096 Fields.addInt(Int32Ty, 0);
1098 Fields.add(MakeConstantString(Str));
1100 std::string StringName;
1103 StringName =
".objc_str_";
1104 for (
int i=0,e=Str.size() ; i<e ; ++i) {
1105 unsigned char c = Str[i];
1116 llvm::GlobalVariable *ObjCStrGV =
1118 isNamed ? StringRef(StringName) :
".objc_string",
1119 Align,
false,
isNamed ? llvm::GlobalValue::LinkOnceODRLinkage
1120 : llvm::GlobalValue::PrivateLinkage);
1121 ObjCStrGV->setSection(sectionName<ConstantStringSection>());
1123 ObjCStrGV->setComdat(TheModule.getOrInsertComdat(StringName));
1124 ObjCStrGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1126 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1127 std::pair<llvm::GlobalVariable*, int>
v{ObjCStrGV, 0};
1128 EarlyInitList.emplace_back(Sym,
v);
1130 ObjCStrings[Str] = ObjCStrGV;
1131 ConstantStrings.push_back(ObjCStrGV);
1138 bool isSynthesized=
true,
bool
1139 isDynamic=
true)
override {
1148 auto Fields = PropertiesArray.
beginStruct(PropertyMetadataTy);
1151 std::string TypeStr =
1153 Fields.add(MakeConstantString(TypeStr));
1154 std::string typeStr;
1156 Fields.add(MakeConstantString(typeStr));
1160 Fields.add(GetConstantSelector(accessor->getSelector(), TypeStr));
1162 Fields.add(NULLPtr);
1177 llvm::StructType *ObjCMethodDescTy =
1179 { PtrToInt8Ty, PtrToInt8Ty });
1188 auto MethodList = Builder.beginStruct();
1190 MethodList.addInt(IntTy, Methods.size());
1192 const llvm::DataLayout &DL = TheModule.getDataLayout();
1193 MethodList.addInt(IntTy, DL.getTypeSizeInBits(ObjCMethodDescTy) /
1196 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
1197 for (
auto *M : Methods) {
1198 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
1199 Method.add(CGObjCGNU::GetConstantSelector(M));
1201 Method.finishAndAddTo(MethodArray);
1203 MethodArray.finishAndAddTo(MethodList);
1204 return MethodList.finishAndCreateGlobal(
".objc_protocol_method_list",
1210 auto RuntimeProtocols = GetRuntimeProtocolList(ReferencedProtocols.begin(),
1211 ReferencedProtocols.end());
1213 for (
const auto *PI : RuntimeProtocols)
1214 Protocols.push_back(GenerateProtocolRef(PI));
1215 return GenerateProtocolList(Protocols);
1219 llvm::Value *cmd, MessageSendInfo &MSI)
override {
1222 llvm::Value *lookupArgs[] = {
1229 llvm::GlobalVariable *GetClassVar(StringRef Name,
bool isWeak=
false) {
1230 std::string SymbolName = SymbolForClassRef(Name, isWeak);
1231 auto *ClassSymbol = TheModule.getNamedGlobal(SymbolName);
1234 ClassSymbol =
new llvm::GlobalVariable(TheModule,
1235 IdTy,
false, llvm::GlobalValue::ExternalLinkage,
1236 nullptr, SymbolName);
1242 ClassSymbol->setInitializer(
new llvm::GlobalVariable(TheModule,
1243 Int8Ty,
false, llvm::GlobalValue::ExternalWeakLinkage,
1244 nullptr, SymbolForClass(Name)));
1246 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1252 for (
const auto *Result : DC->
lookup(&II))
1253 if ((OID = dyn_cast<ObjCInterfaceDecl>(Result)))
1259 assert(OID &&
"Failed to find ObjCInterfaceDecl");
1261 if (OIDDef !=
nullptr)
1264 auto Storage = llvm::GlobalValue::DefaultStorageClass;
1265 if (OID->
hasAttr<DLLImportAttr>())
1266 Storage = llvm::GlobalValue::DLLImportStorageClass;
1267 else if (OID->
hasAttr<DLLExportAttr>())
1268 Storage = llvm::GlobalValue::DLLExportStorageClass;
1270 cast<llvm::GlobalValue>(ClassSymbol)->setDLLStorageClass(Storage);
1273 assert(ClassSymbol->getName() == SymbolName);
1277 const std::string &Name,
1278 bool isWeak)
override {
1290 switch (Ownership) {
1312 llvm_unreachable(
"Method should not be called!");
1315 llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName)
override {
1316 std::string Name = SymbolForProtocol(ProtocolName);
1317 auto *GV = TheModule.getGlobalVariable(Name);
1320 GV =
new llvm::GlobalVariable(TheModule, ProtocolTy,
false,
1321 llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
1328 llvm::StringMap<llvm::Constant*> ExistingProtocolRefs;
1333 auto *&Ref = ExistingProtocolRefs[Name];
1335 auto *&
Protocol = ExistingProtocols[Name];
1337 Protocol = GenerateProtocolRef(PD);
1338 std::string RefName = SymbolForProtocolRef(Name);
1339 assert(!TheModule.getGlobalVariable(RefName));
1341 auto GV =
new llvm::GlobalVariable(TheModule, ProtocolPtrTy,
false,
1342 llvm::GlobalValue::LinkOnceODRLinkage,
1344 GV->setComdat(TheModule.getOrInsertComdat(RefName));
1345 GV->setSection(sectionName<ProtocolReferenceSection>());
1349 EmittedProtocolRef =
true;
1355 llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(ProtocolPtrTy,
1357 llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
1360 auto ProtocolBuilder = builder.beginStruct();
1361 ProtocolBuilder.addNullPointer(PtrTy);
1362 ProtocolBuilder.addInt(SizeTy, Protocols.size());
1363 ProtocolBuilder.add(ProtocolArray);
1364 return ProtocolBuilder.finishAndCreateGlobal(
".objc_protocol_list",
1373 auto *&
Protocol = ExistingProtocols[ProtocolName];
1377 EmittedProtocol =
true;
1379 auto SymName = SymbolForProtocol(ProtocolName);
1380 auto *OldGV = TheModule.getGlobalVariable(SymName);
1390 Protocol =
new llvm::GlobalVariable(TheModule, ProtocolTy,
1392 llvm::GlobalValue::ExternalLinkage,
nullptr, SymName);
1397 auto RuntimeProtocols =
1399 for (
const auto *PI : RuntimeProtocols)
1400 Protocols.push_back(GenerateProtocolRef(PI));
1401 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
1404 llvm::Constant *InstanceMethodList, *OptionalInstanceMethodList;
1405 llvm::Constant *ClassMethodList, *OptionalClassMethodList;
1407 OptionalInstanceMethodList);
1408 EmitProtocolMethodList(PD->
class_methods(), ClassMethodList,
1409 OptionalClassMethodList);
1414 auto ProtocolBuilder = builder.beginStruct();
1415 ProtocolBuilder.add(llvm::ConstantExpr::getIntToPtr(
1416 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
1417 ProtocolBuilder.add(MakeConstantString(ProtocolName));
1418 ProtocolBuilder.add(ProtocolList);
1419 ProtocolBuilder.add(InstanceMethodList);
1420 ProtocolBuilder.add(ClassMethodList);
1421 ProtocolBuilder.add(OptionalInstanceMethodList);
1422 ProtocolBuilder.add(OptionalClassMethodList);
1424 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
false,
false));
1426 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
false,
true));
1428 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
true,
false));
1430 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
true,
true));
1432 auto *GV = ProtocolBuilder.finishAndCreateGlobal(SymName,
1434 GV->setSection(sectionName<ProtocolSection>());
1435 GV->setComdat(TheModule.getOrInsertComdat(SymName));
1437 OldGV->replaceAllUsesWith(GV);
1438 OldGV->removeFromParent();
1439 GV->setName(SymName);
1445 const std::string &TypeEncoding)
override {
1446 return GetConstantSelector(Sel, TypeEncoding);
1448 std::string GetSymbolNameForTypeEncoding(
const std::string &TypeEncoding) {
1449 std::string MangledTypes = std::string(TypeEncoding);
1455 std::replace(MangledTypes.begin(), MangledTypes.end(),
'@',
'\1');
1458 std::replace(MangledTypes.begin(), MangledTypes.end(),
'=',
'\2');
1459 return MangledTypes;
1461 llvm::Constant *GetTypeString(llvm::StringRef TypeEncoding) {
1462 if (TypeEncoding.empty())
1464 std::string MangledTypes =
1465 GetSymbolNameForTypeEncoding(std::string(TypeEncoding));
1466 std::string TypesVarName =
".objc_sel_types_" + MangledTypes;
1467 auto *TypesGlobal = TheModule.getGlobalVariable(TypesVarName);
1469 llvm::Constant *
Init = llvm::ConstantDataArray::getString(VMContext,
1471 auto *GV =
new llvm::GlobalVariable(TheModule,
Init->getType(),
1472 true, llvm::GlobalValue::LinkOnceODRLinkage,
Init, TypesVarName);
1473 GV->setComdat(TheModule.getOrInsertComdat(TypesVarName));
1474 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1479 llvm::Constant *GetConstantSelector(
Selector Sel,
1480 const std::string &TypeEncoding)
override {
1481 std::string MangledTypes = GetSymbolNameForTypeEncoding(TypeEncoding);
1482 auto SelVarName = (StringRef(
".objc_selector_") + Sel.
getAsString() +
"_" +
1483 MangledTypes).str();
1484 if (
auto *GV = TheModule.getNamedGlobal(SelVarName))
1487 auto SelBuilder = builder.beginStruct();
1488 SelBuilder.add(ExportUniqueString(Sel.
getAsString(),
".objc_sel_name_",
1490 SelBuilder.add(GetTypeString(TypeEncoding));
1491 auto *GV = SelBuilder.finishAndCreateGlobal(SelVarName,
1493 GV->setComdat(TheModule.getOrInsertComdat(SelVarName));
1494 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1495 GV->setSection(sectionName<SelectorSection>());
1498 llvm::StructType *emptyStruct =
nullptr;
1507 std::pair<llvm::Constant*,llvm::Constant*>
1508 GetSectionBounds(StringRef Section) {
1509 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1510 if (emptyStruct ==
nullptr) {
1511 emptyStruct = llvm::StructType::create(
1512 VMContext, {},
".objc_section_sentinel",
true);
1514 auto ZeroInit = llvm::Constant::getNullValue(emptyStruct);
1515 auto Sym = [&](StringRef Prefix, StringRef SecSuffix) {
1516 auto *Sym =
new llvm::GlobalVariable(TheModule, emptyStruct,
1518 llvm::GlobalValue::LinkOnceODRLinkage, ZeroInit, Prefix +
1520 Sym->setVisibility(llvm::GlobalValue::HiddenVisibility);
1521 Sym->setSection((Section + SecSuffix).str());
1522 Sym->setComdat(TheModule.getOrInsertComdat((Prefix +
1527 return { Sym(
"__start_",
"$a"), Sym(
"__stop",
"$z") };
1529 auto *Start =
new llvm::GlobalVariable(TheModule, PtrTy,
1531 llvm::GlobalValue::ExternalLinkage,
nullptr, StringRef(
"__start_") +
1533 Start->setVisibility(llvm::GlobalValue::HiddenVisibility);
1534 auto *Stop =
new llvm::GlobalVariable(TheModule, PtrTy,
1536 llvm::GlobalValue::ExternalLinkage,
nullptr, StringRef(
"__stop_") +
1538 Stop->setVisibility(llvm::GlobalValue::HiddenVisibility);
1539 return { Start, Stop };
1544 llvm::Function *ModuleInitFunction()
override {
1545 llvm::Function *LoadFunction = llvm::Function::Create(
1546 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
1547 llvm::GlobalValue::LinkOnceODRLinkage,
".objcv2_load_function",
1549 LoadFunction->setVisibility(llvm::GlobalValue::HiddenVisibility);
1550 LoadFunction->setComdat(TheModule.getOrInsertComdat(
".objcv2_load_function"));
1552 llvm::BasicBlock *EntryBB =
1553 llvm::BasicBlock::Create(VMContext,
"entry", LoadFunction);
1555 B.SetInsertPoint(EntryBB);
1557 auto InitStructBuilder = builder.beginStruct();
1558 InitStructBuilder.addInt(Int64Ty, 0);
1559 auto §ionVec = CGM.
getTriple().isOSBinFormatCOFF() ? PECOFFSectionsBaseNames : SectionsBaseNames;
1560 for (
auto *
s : sectionVec) {
1561 auto bounds = GetSectionBounds(
s);
1562 InitStructBuilder.add(bounds.first);
1563 InitStructBuilder.add(bounds.second);
1565 auto *InitStruct = InitStructBuilder.finishAndCreateGlobal(
".objc_init",
1567 InitStruct->setVisibility(llvm::GlobalValue::HiddenVisibility);
1568 InitStruct->setComdat(TheModule.getOrInsertComdat(
".objc_init"));
1570 CallRuntimeFunction(B,
"__objc_load", {InitStruct});;
1577 auto *InitVar =
new llvm::GlobalVariable(TheModule, LoadFunction->getType(),
1578 false, llvm::GlobalValue::LinkOnceAnyLinkage,
1579 LoadFunction,
".objc_ctor");
1582 assert(InitVar->getName() ==
".objc_ctor");
1588 if (CGM.
getTriple().isOSBinFormatCOFF())
1589 InitVar->setSection(
".CRT$XCLz");
1593 InitVar->setSection(
".init_array");
1595 InitVar->setSection(
".ctors");
1597 InitVar->setVisibility(llvm::GlobalValue::HiddenVisibility);
1598 InitVar->setComdat(TheModule.getOrInsertComdat(
".objc_ctor"));
1600 for (
auto *
C : Categories) {
1601 auto *Cat = cast<llvm::GlobalVariable>(
C->stripPointerCasts());
1602 Cat->setSection(sectionName<CategorySection>());
1606 StringRef Section) {
1607 auto nullBuilder = builder.beginStruct();
1608 for (
auto *F :
Init)
1610 auto GV = nullBuilder.finishAndCreateGlobal(Name, CGM.
getPointerAlign(),
1611 false, llvm::GlobalValue::LinkOnceODRLinkage);
1612 GV->setSection(Section);
1613 GV->setComdat(TheModule.getOrInsertComdat(Name));
1614 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1618 for (
auto clsAlias : ClassAliases)
1619 createNullGlobal(std::string(
".objc_class_alias") +
1620 clsAlias.second, { MakeConstantString(clsAlias.second),
1621 GetClassVar(clsAlias.first) }, sectionName<ClassAliasSection>());
1626 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
1627 createNullGlobal(
".objc_null_selector", {NULLPtr, NULLPtr},
1628 sectionName<SelectorSection>());
1629 if (Categories.empty())
1630 createNullGlobal(
".objc_null_category", {NULLPtr, NULLPtr,
1631 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr},
1632 sectionName<CategorySection>());
1633 if (!EmittedClass) {
1634 createNullGlobal(
".objc_null_cls_init_ref", NULLPtr,
1635 sectionName<ClassSection>());
1636 createNullGlobal(
".objc_null_class_ref", { NULLPtr, NULLPtr },
1637 sectionName<ClassReferenceSection>());
1639 if (!EmittedProtocol)
1640 createNullGlobal(
".objc_null_protocol", {NULLPtr, NULLPtr, NULLPtr,
1641 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr,
1642 NULLPtr}, sectionName<ProtocolSection>());
1643 if (!EmittedProtocolRef)
1644 createNullGlobal(
".objc_null_protocol_ref", {NULLPtr},
1645 sectionName<ProtocolReferenceSection>());
1646 if (ClassAliases.empty())
1647 createNullGlobal(
".objc_null_class_alias", { NULLPtr, NULLPtr },
1648 sectionName<ClassAliasSection>());
1649 if (ConstantStrings.empty()) {
1650 auto i32Zero = llvm::ConstantInt::get(Int32Ty, 0);
1651 createNullGlobal(
".objc_null_constant_string", { NULLPtr, i32Zero,
1652 i32Zero, i32Zero, i32Zero, NULLPtr },
1653 sectionName<ConstantStringSection>());
1656 ConstantStrings.clear();
1660 if (EarlyInitList.size() > 0) {
1661 auto *
Init = llvm::Function::Create(llvm::FunctionType::get(CGM.
VoidTy,
1662 {}), llvm::GlobalValue::InternalLinkage,
".objc_early_init",
1664 llvm::IRBuilder<>
b(llvm::BasicBlock::Create(CGM.
getLLVMContext(),
"entry",
1666 for (
const auto &lateInit : EarlyInitList) {
1667 auto *global = TheModule.getGlobalVariable(lateInit.first);
1669 llvm::GlobalVariable *GV = lateInit.second.first;
1670 b.CreateAlignedStore(
1672 b.CreateStructGEP(GV->getValueType(), GV, lateInit.second.second),
1679 auto *InitVar =
new llvm::GlobalVariable(CGM.
getModule(),
Init->getType(),
1680 true, llvm::GlobalValue::InternalLinkage,
1681 Init,
".objc_early_init_ptr");
1682 InitVar->setSection(
".CRT$XCLb");
1691 std::string TypeEncoding;
1693 TypeEncoding = GetSymbolNameForTypeEncoding(TypeEncoding);
1694 const std::string Name =
"__objc_ivar_offset_" +
ID->getNameAsString()
1703 const std::string Name =
1704 GetIVarOffsetVariableName(ContainingInterface, Ivar);
1705 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
1706 if (!IvarOffsetPointer) {
1707 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule, IntTy,
false,
1708 llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
1714 llvm::Value *Offset =
1716 if (Offset->getType() != PtrDiffTy)
1717 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
1722 bool IsCOFF = CGM.
getTriple().isOSBinFormatCOFF();
1728 auto *classNameConstant = MakeConstantString(className);
1731 auto metaclassFields = builder.beginStruct();
1733 metaclassFields.addNullPointer(PtrTy);
1735 metaclassFields.addNullPointer(PtrTy);
1737 metaclassFields.add(classNameConstant);
1739 metaclassFields.addInt(LongTy, 0);
1742 metaclassFields.addInt(LongTy, ClassFlags::ClassFlagMeta);
1746 metaclassFields.addInt(LongTy, 0);
1748 metaclassFields.addNullPointer(PtrTy);
1753 metaclassFields.addNullPointer(PtrTy);
1758 metaclassFields.add(
1759 GenerateMethodList(className,
"", ClassMethods,
true));
1762 metaclassFields.addNullPointer(PtrTy);
1764 metaclassFields.addNullPointer(PtrTy);
1766 metaclassFields.addNullPointer(PtrTy);
1768 metaclassFields.addNullPointer(PtrTy);
1770 metaclassFields.addNullPointer(PtrTy);
1772 metaclassFields.addNullPointer(PtrTy);
1774 metaclassFields.addNullPointer(PtrTy);
1776 metaclassFields.addInt(LongTy, 0);
1778 metaclassFields.add(GeneratePropertyList(OID, classDecl,
true));
1780 auto *metaclass = metaclassFields.finishAndCreateGlobal(
1781 ManglePublicSymbol(
"OBJC_METACLASS_") + className,
1784 auto classFields = builder.beginStruct();
1786 classFields.add(metaclass);
1791 llvm::Constant *SuperClass =
nullptr;
1792 if (SuperClassDecl) {
1793 auto SuperClassName = SymbolForClass(SuperClassDecl->
getNameAsString());
1794 SuperClass = TheModule.getNamedGlobal(SuperClassName);
1797 SuperClass =
new llvm::GlobalVariable(TheModule, PtrTy,
false,
1798 llvm::GlobalValue::ExternalLinkage,
nullptr, SuperClassName);
1800 auto Storage = llvm::GlobalValue::DefaultStorageClass;
1801 if (SuperClassDecl->
hasAttr<DLLImportAttr>())
1802 Storage = llvm::GlobalValue::DLLImportStorageClass;
1803 else if (SuperClassDecl->
hasAttr<DLLExportAttr>())
1804 Storage = llvm::GlobalValue::DLLExportStorageClass;
1806 cast<llvm::GlobalValue>(SuperClass)->setDLLStorageClass(Storage);
1810 classFields.add(SuperClass);
1812 classFields.addNullPointer(PtrTy);
1814 classFields.addNullPointer(PtrTy);
1816 classFields.add(classNameConstant);
1818 classFields.addInt(LongTy, 0);
1821 classFields.addInt(LongTy, 0);
1823 int superInstanceSize = !SuperClassDecl ? 0 :
1827 classFields.addInt(LongTy,
1829 superInstanceSize));
1832 classFields.addNullPointer(PtrTy);
1837 const llvm::DataLayout &DL = TheModule.getDataLayout();
1840 auto ivarListBuilder =
b.beginStruct();
1842 ivarListBuilder.addInt(IntTy, ivar_count);
1844 llvm::StructType *ObjCIvarTy = llvm::StructType::get(
1850 ivarListBuilder.addInt(SizeTy, DL.getTypeSizeInBits(ObjCIvarTy) /
1853 auto ivarArrayBuilder = ivarListBuilder.beginArray();
1856 auto ivarTy = IVD->getType();
1857 auto ivarBuilder = ivarArrayBuilder.beginStruct();
1859 ivarBuilder.add(MakeConstantString(IVD->getNameAsString()));
1861 std::string TypeStr;
1864 ivarBuilder.add(MakeConstantString(TypeStr));
1866 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
1867 uint64_t Offset = BaseOffset - superInstanceSize;
1868 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
1869 std::string OffsetName = GetIVarOffsetVariableName(classDecl, IVD);
1870 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
1872 OffsetVar->setInitializer(OffsetValue);
1874 OffsetVar =
new llvm::GlobalVariable(TheModule, IntTy,
1875 false, llvm::GlobalValue::ExternalLinkage,
1876 OffsetValue, OffsetName);
1877 auto ivarVisibility =
1881 llvm::GlobalValue::HiddenVisibility :
1882 llvm::GlobalValue::DefaultVisibility;
1883 OffsetVar->setVisibility(ivarVisibility);
1884 if (ivarVisibility != llvm::GlobalValue::HiddenVisibility)
1886 ivarBuilder.add(OffsetVar);
1888 ivarBuilder.addInt(Int32Ty,
1899 ivarBuilder.addInt(Int32Ty,
1900 (align << 3) | (1<<2) |
1901 FlagsForOwnership(ivarTy.getQualifiers().getObjCLifetime()));
1902 ivarBuilder.finishAndAddTo(ivarArrayBuilder);
1904 ivarArrayBuilder.finishAndAddTo(ivarListBuilder);
1905 auto ivarList = ivarListBuilder.finishAndCreateGlobal(
".objc_ivar_list",
1907 llvm::GlobalValue::PrivateLinkage);
1908 classFields.add(ivarList);
1912 InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
1915 if (propImpl->getPropertyImplementation() ==
1918 if (OMD && OMD->hasBody())
1919 InstanceMethods.push_back(OMD);
1921 addIfExists(propImpl->getGetterMethodDecl());
1922 addIfExists(propImpl->getSetterMethodDecl());
1925 if (InstanceMethods.size() == 0)
1926 classFields.addNullPointer(PtrTy);
1929 GenerateMethodList(className,
"", InstanceMethods,
false));
1932 classFields.addNullPointer(PtrTy);
1934 classFields.addNullPointer(PtrTy);
1936 classFields.addNullPointer(PtrTy);
1938 classFields.addNullPointer(PtrTy);
1940 classFields.addNullPointer(PtrTy);
1942 auto RuntimeProtocols = GetRuntimeProtocolList(classDecl->
protocol_begin(),
1945 for (
const auto *I : RuntimeProtocols)
1946 Protocols.push_back(GenerateProtocolRef(I));
1948 if (Protocols.empty())
1949 classFields.addNullPointer(PtrTy);
1951 classFields.add(GenerateProtocolList(Protocols));
1953 classFields.addNullPointer(PtrTy);
1955 classFields.addInt(LongTy, 0);
1957 classFields.add(GeneratePropertyList(OID, classDecl));
1959 llvm::GlobalVariable *classStruct =
1960 classFields.finishAndCreateGlobal(SymbolForClass(className),
1963 auto *classRefSymbol = GetClassVar(className);
1964 classRefSymbol->setSection(sectionName<ClassReferenceSection>());
1965 classRefSymbol->setInitializer(classStruct);
1970 classStruct->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1971 cast<llvm::GlobalValue>(classRefSymbol)->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1975 std::pair<llvm::GlobalVariable*, int>
v{classStruct, 1};
1976 EarlyInitList.emplace_back(std::string(SuperClass->getName()),
1985 if (ClassPtrAlias) {
1986 ClassPtrAlias->replaceAllUsesWith(classStruct);
1987 ClassPtrAlias->eraseFromParent();
1988 ClassPtrAlias =
nullptr;
1990 if (
auto Placeholder =
1991 TheModule.getNamedGlobal(SymbolForClass(className)))
1992 if (Placeholder != classStruct) {
1993 Placeholder->replaceAllUsesWith(classStruct);
1994 Placeholder->eraseFromParent();
1995 classStruct->setName(SymbolForClass(className));
1997 if (MetaClassPtrAlias) {
1998 MetaClassPtrAlias->replaceAllUsesWith(metaclass);
1999 MetaClassPtrAlias->eraseFromParent();
2000 MetaClassPtrAlias =
nullptr;
2002 assert(classStruct->getName() == SymbolForClass(className));
2004 auto classInitRef =
new llvm::GlobalVariable(TheModule,
2005 classStruct->getType(),
false, llvm::GlobalValue::ExternalLinkage,
2006 classStruct, ManglePublicSymbol(
"OBJC_INIT_CLASS_") + className);
2007 classInitRef->setSection(sectionName<ClassSection>());
2010 EmittedClass =
true;
2013 CGObjCGNUstep2(
CodeGenModule &Mod) : CGObjCGNUstep(Mod, 10, 4, 2) {
2014 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
2015 PtrToObjCSuperTy, SelectorTy);
2016 SentInitializeFn.init(&CGM,
"objc_send_initialize",
2017 llvm::Type::getVoidTy(VMContext), IdTy);
2026 PropertyMetadataTy =
2028 { PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty });
2031 void GenerateDirectMethodPrologue(
CodeGenFunction &CGF, llvm::Function *Fn,
2035 bool ReceiverCanBeNull =
true;
2037 auto selfValue = Builder.CreateLoad(selfAddr);
2062 ReceiverCanBeNull = isWeakLinkedClass(OID);
2066 if (ReceiverCanBeNull) {
2067 llvm::BasicBlock *SelfIsNilBlock =
2069 llvm::BasicBlock *ContBlock =
2073 auto selfTy = cast<llvm::PointerType>(selfValue->getType());
2074 auto Zero = llvm::ConstantPointerNull::get(selfTy);
2076 Builder.CreateCondBr(Builder.CreateICmpEQ(selfValue, Zero),
2077 SelfIsNilBlock, ContBlock,
2078 MDHelper.createUnlikelyBranchWeights());
2084 Builder.SetInsertPoint(SelfIsNilBlock);
2085 if (!retTy->isVoidType()) {
2093 Builder.SetInsertPoint(ContBlock);
2099 llvm::StructType::get(PtrTy, PtrTy, PtrTy, LongTy, LongTy);
2106 llvm::Value *Val = Builder.CreateStructGEP(classStart, selfValue, 4);
2108 astContext.getTypeAlign(astContext.UnsignedLongTy));
2109 auto flags = Builder.CreateLoad(
Address{Val, LongTy, Align});
2110 auto isInitialized =
2111 Builder.CreateAnd(flags, ClassFlags::ClassFlagInitialized);
2112 llvm::BasicBlock *notInitializedBlock =
2114 llvm::BasicBlock *initializedBlock =
2116 Builder.CreateCondBr(Builder.CreateICmpEQ(isInitialized, Zeros[0]),
2117 notInitializedBlock, initializedBlock,
2118 MDHelper.createUnlikelyBranchWeights());
2120 Builder.SetInsertPoint(notInitializedBlock);
2122 Builder.CreateBr(initializedBlock);
2124 Builder.SetInsertPoint(initializedBlock);
2132 Builder.CreateStore(GetSelector(CGF, OMD),
2138const char *
const CGObjCGNUstep2::SectionsBaseNames[8] =
2145"__objc_protocol_refs",
2146"__objc_class_aliases",
2147"__objc_constant_string"
2150const char *
const CGObjCGNUstep2::PECOFFSectionsBaseNames[8] =
2163class CGObjCObjFW:
public CGObjCGNU {
2167 LazyRuntimeFunction MsgLookupFn;
2170 LazyRuntimeFunction MsgLookupFnSRet;
2174 LazyRuntimeFunction MsgLookupSuperFn, MsgLookupSuperFnSRet;
2177 llvm::Value *cmd, llvm::MDNode *node,
2178 MessageSendInfo &MSI)
override {
2180 llvm::Value *args[] = {
2181 EnforceType(Builder, Receiver, IdTy),
2182 EnforceType(Builder, cmd, SelectorTy) };
2184 llvm::CallBase *imp;
2190 imp->setMetadata(msgSendMDKind, node);
2195 llvm::Value *cmd, MessageSendInfo &MSI)
override {
2197 llvm::Value *lookupArgs[] = {
2198 EnforceType(Builder, ObjCSuper.
emitRawPointer(CGF), PtrToObjCSuperTy),
2208 llvm::Value *GetClassNamed(
CodeGenFunction &CGF,
const std::string &Name,
2209 bool isWeak)
override {
2211 return CGObjCGNU::GetClassNamed(CGF, Name, isWeak);
2214 std::string SymbolName =
"_OBJC_CLASS_" + Name;
2215 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(SymbolName);
2217 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
2218 llvm::GlobalValue::ExternalLinkage,
2219 nullptr, SymbolName);
2226 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
2227 MsgLookupFnSRet.init(&CGM,
"objc_msg_lookup_stret", IMPTy, IdTy,
2230 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
2231 PtrToObjCSuperTy, SelectorTy);
2232 MsgLookupSuperFnSRet.init(&CGM,
"objc_msg_lookup_super_stret", IMPTy,
2233 PtrToObjCSuperTy, SelectorTy);
2241void CGObjCGNU::EmitClassRef(
const std::string &className) {
2242 std::string symbolRef =
"__objc_class_ref_" + className;
2244 if (TheModule.getGlobalVariable(symbolRef))
2246 std::string symbolName =
"__objc_class_name_" + className;
2247 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
2249 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
2250 llvm::GlobalValue::ExternalLinkage,
2251 nullptr, symbolName);
2253 new llvm::GlobalVariable(TheModule, ClassSymbol->getType(),
true,
2254 llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef);
2257CGObjCGNU::CGObjCGNU(
CodeGenModule &cgm,
unsigned runtimeABIVersion,
2258 unsigned protocolClassVersion,
unsigned classABI)
2260 VMContext(cgm.getLLVMContext()), ClassPtrAlias(nullptr),
2261 MetaClassPtrAlias(nullptr), RuntimeVersion(runtimeABIVersion),
2262 ProtocolVersion(protocolClassVersion), ClassABIVersion(classABI) {
2264 msgSendMDKind = VMContext.getMDKindID(
"GNUObjCMessageSend");
2272 IntTy = cast<llvm::IntegerType>(
2274 LongTy = cast<llvm::IntegerType>(
2276 SizeTy = cast<llvm::IntegerType>(
2278 PtrDiffTy = cast<llvm::IntegerType>(
2282 Int8Ty = llvm::Type::getInt8Ty(VMContext);
2284 PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
2285 ProtocolPtrTy = llvm::PointerType::getUnqual(
2288 Zeros[0] = llvm::ConstantInt::get(LongTy, 0);
2289 Zeros[1] = Zeros[0];
2290 NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty);
2294 SelectorTy = PtrToInt8Ty;
2295 SelectorElemTy = Int8Ty;
2301 PtrToIntTy = llvm::PointerType::getUnqual(IntTy);
2302 PtrTy = PtrToInt8Ty;
2304 Int32Ty = llvm::Type::getInt32Ty(VMContext);
2305 Int64Ty = llvm::Type::getInt64Ty(VMContext);
2308 CGM.
getDataLayout().getPointerSizeInBits() == 32 ? Int32Ty : Int64Ty;
2322 PtrToIdTy = llvm::PointerType::getUnqual(IdTy);
2323 ProtocolTy = llvm::StructType::get(IdTy,
2345 PropertyMetadataTy = llvm::StructType::get(CGM.
getLLVMContext(), {
2346 PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty,
2347 PtrToInt8Ty, PtrToInt8Ty });
2349 ObjCSuperTy = llvm::StructType::get(IdTy, IdTy);
2350 PtrToObjCSuperTy = llvm::PointerType::getUnqual(ObjCSuperTy);
2352 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
2355 ExceptionThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy);
2356 ExceptionReThrowFn.init(&CGM,
2357 usesCxxExceptions ?
"objc_exception_rethrow"
2358 :
"objc_exception_throw",
2361 SyncEnterFn.init(&CGM,
"objc_sync_enter", IntTy, IdTy);
2363 SyncExitFn.init(&CGM,
"objc_sync_exit", IntTy, IdTy);
2366 EnumerationMutationFn.init(&CGM,
"objc_enumerationMutation", VoidTy, IdTy);
2369 GetPropertyFn.init(&CGM,
"objc_getProperty", IdTy, IdTy, SelectorTy,
2372 SetPropertyFn.init(&CGM,
"objc_setProperty", VoidTy, IdTy, SelectorTy,
2373 PtrDiffTy, IdTy, BoolTy, BoolTy);
2375 GetStructPropertyFn.init(&CGM,
"objc_getPropertyStruct", VoidTy, PtrTy, PtrTy,
2376 PtrDiffTy, BoolTy, BoolTy);
2378 SetStructPropertyFn.init(&CGM,
"objc_setPropertyStruct", VoidTy, PtrTy, PtrTy,
2379 PtrDiffTy, BoolTy, BoolTy);
2382 llvm::Type *IMPArgs[] = { IdTy, SelectorTy };
2383 IMPTy = llvm::PointerType::getUnqual(llvm::FunctionType::get(IdTy, IMPArgs,
2387 if ((Opts.getGC() != LangOptions::NonGC) || Opts.ObjCAutoRefCount)
2388 RuntimeVersion = 10;
2391 if (Opts.getGC() != LangOptions::NonGC) {
2403 IvarAssignFn.init(&CGM,
"objc_assign_ivar", IdTy, IdTy, IdTy, PtrDiffTy);
2405 StrongCastAssignFn.init(&CGM,
"objc_assign_strongCast", IdTy, IdTy,
2408 GlobalAssignFn.init(&CGM,
"objc_assign_global", IdTy, IdTy, PtrToIdTy);
2410 WeakAssignFn.init(&CGM,
"objc_assign_weak", IdTy, IdTy, PtrToIdTy);
2412 WeakReadFn.init(&CGM,
"objc_read_weak", IdTy, PtrToIdTy);
2414 MemMoveFn.init(&CGM,
"objc_memmove_collectable", PtrTy, PtrTy, PtrTy,
2420 const std::string &Name,
bool isWeak) {
2421 llvm::Constant *ClassName = MakeConstantString(Name);
2433 llvm::FunctionType::get(IdTy, PtrToInt8Ty,
true),
"objc_lookup_class");
2443 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value))
2448llvm::Value *CGObjCGNU::EmitNSAutoreleasePoolClassRef(
CodeGenFunction &CGF) {
2449 auto *
Value = GetClassNamed(CGF,
"NSAutoreleasePool",
false);
2450 if (CGM.
getTriple().isOSBinFormatCOFF()) {
2451 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value)) {
2457 for (
const auto *Result : DC->
lookup(&II))
2458 if ((VD = dyn_cast<VarDecl>(Result)))
2468 const std::string &TypeEncoding) {
2470 llvm::GlobalAlias *SelValue =
nullptr;
2473 e = Types.end() ; i!=e ; i++) {
2474 if (i->first == TypeEncoding) {
2475 SelValue = i->second;
2480 SelValue = llvm::GlobalAlias::create(SelectorElemTy, 0,
2481 llvm::GlobalValue::PrivateLinkage,
2484 Types.emplace_back(TypeEncoding, SelValue);
2491 llvm::Value *SelValue = GetSelector(CGF, Sel);
2502 return GetTypedSelector(CGF, Sel, std::string());
2508 return GetTypedSelector(CGF, Method->
getSelector(), SelTypes);
2511llvm::Constant *CGObjCGNU::GetEHType(
QualType T) {
2518 return MakeConstantString(
"@id");
2526 assert(OPT &&
"Invalid @catch type.");
2528 assert(IDecl &&
"Invalid @catch type.");
2532llvm::Constant *CGObjCGNUstep::GetEHType(
QualType T) {
2533 if (usesSEHExceptions)
2536 if (!CGM.
getLangOpts().CPlusPlus && !usesCxxExceptions)
2537 return CGObjCGNU::GetEHType(
T);
2545 llvm::Constant *IDEHType =
2546 CGM.
getModule().getGlobalVariable(
"__objc_id_type_info");
2549 new llvm::GlobalVariable(CGM.
getModule(), PtrToInt8Ty,
2551 llvm::GlobalValue::ExternalLinkage,
2552 nullptr,
"__objc_id_type_info");
2558 assert(PT &&
"Invalid @catch type.");
2560 assert(IT &&
"Invalid @catch type.");
2561 std::string className =
2564 std::string typeinfoName =
"__objc_eh_typeinfo_" + className;
2567 if (llvm::Constant *typeinfo = TheModule.getGlobalVariable(typeinfoName))
2575 const char *vtableName =
"_ZTVN7gnustep7libobjc22__objc_class_type_infoE";
2576 auto *Vtable = TheModule.getGlobalVariable(vtableName);
2578 Vtable =
new llvm::GlobalVariable(TheModule, PtrToInt8Ty,
true,
2579 llvm::GlobalValue::ExternalLinkage,
2580 nullptr, vtableName);
2582 llvm::Constant *Two = llvm::ConstantInt::get(IntTy, 2);
2584 llvm::ConstantExpr::getGetElementPtr(Vtable->getValueType(), Vtable, Two);
2586 llvm::Constant *typeName =
2587 ExportUniqueString(className,
"__objc_eh_typename_");
2590 auto fields = builder.beginStruct();
2591 fields.add(BVtable);
2592 fields.add(typeName);
2593 llvm::Constant *TI =
2594 fields.finishAndCreateGlobal(
"__objc_eh_typeinfo_" + className,
2597 llvm::GlobalValue::LinkOnceODRLinkage);
2604 std::string Str = SL->
getString().str();
2608 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
2609 if (old != ObjCStrings.end())
2614 if (StringClass.empty()) StringClass =
"NSConstantString";
2616 std::string Sym =
"_OBJC_CLASS_";
2619 llvm::Constant *
isa = TheModule.getNamedGlobal(Sym);
2622 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
2623 llvm::GlobalValue::ExternalWeakLinkage,
2627 auto Fields = Builder.beginStruct();
2629 Fields.add(MakeConstantString(Str));
2630 Fields.addInt(IntTy, Str.size());
2632 ObjCStrings[Str] = ObjCStr;
2633 ConstantStrings.push_back(ObjCStr);
2646 bool isCategoryImpl,
2647 llvm::Value *Receiver,
2648 bool IsClassMessage,
2652 if (CGM.
getLangOpts().getGC() == LangOptions::GCOnly) {
2653 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2657 if (Sel == ReleaseSel) {
2662 llvm::Value *cmd = GetSelector(CGF, Sel);
2665 ActualArgs.
add(
RValue::get(EnforceType(Builder, Receiver, IdTy)), ASTIdTy);
2669 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2671 llvm::Value *ReceiverClass =
nullptr;
2674 ReceiverClass = GetClassNamed(CGF,
2675 Class->getSuperClass()->getNameAsString(),
false);
2676 if (IsClassMessage) {
2678 ReceiverClass = Builder.CreateBitCast(ReceiverClass,
2679 llvm::PointerType::getUnqual(IdTy));
2681 Builder.CreateAlignedLoad(IdTy, ReceiverClass, CGF.
getPointerAlign());
2683 ReceiverClass = EnforceType(Builder, ReceiverClass, IdTy);
2685 if (isCategoryImpl) {
2686 llvm::FunctionCallee classLookupFunction =
nullptr;
2687 if (IsClassMessage) {
2689 IdTy, PtrTy,
true),
"objc_get_meta_class");
2692 IdTy, PtrTy,
true),
"objc_get_class");
2694 ReceiverClass = Builder.CreateCall(classLookupFunction,
2695 MakeConstantString(
Class->getNameAsString()));
2702 if (IsClassMessage) {
2703 if (!MetaClassPtrAlias) {
2704 MetaClassPtrAlias = llvm::GlobalAlias::create(
2705 IdElemTy, 0, llvm::GlobalValue::InternalLinkage,
2706 ".objc_metaclass_ref" +
Class->getNameAsString(), &TheModule);
2708 ReceiverClass = MetaClassPtrAlias;
2710 if (!ClassPtrAlias) {
2711 ClassPtrAlias = llvm::GlobalAlias::create(
2712 IdElemTy, 0, llvm::GlobalValue::InternalLinkage,
2713 ".objc_class_ref" +
Class->getNameAsString(), &TheModule);
2715 ReceiverClass = ClassPtrAlias;
2719 llvm::Type *CastTy = llvm::StructType::get(IdTy, IdTy);
2720 ReceiverClass = Builder.CreateBitCast(ReceiverClass,
2721 llvm::PointerType::getUnqual(CastTy));
2723 ReceiverClass = Builder.CreateStructGEP(CastTy, ReceiverClass, 1);
2726 Builder.CreateAlignedLoad(IdTy, ReceiverClass, CGF.
getPointerAlign());
2729 llvm::StructType *ObjCSuperTy =
2730 llvm::StructType::get(Receiver->getType(), IdTy);
2735 Builder.CreateStore(Receiver, Builder.CreateStructGEP(ObjCSuper, 0));
2736 Builder.CreateStore(ReceiverClass, Builder.CreateStructGEP(ObjCSuper, 1));
2739 llvm::Value *imp = LookupIMPSuper(CGF, ObjCSuper, cmd, MSI);
2740 imp = EnforceType(Builder, imp, MSI.MessengerType);
2742 llvm::Metadata *impMD[] = {
2743 llvm::MDString::get(VMContext, Sel.
getAsString()),
2744 llvm::MDString::get(VMContext,
Class->getSuperClass()->getNameAsString()),
2745 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2746 llvm::Type::getInt1Ty(VMContext), IsClassMessage))};
2747 llvm::MDNode *
node = llvm::MDNode::get(VMContext, impMD);
2751 llvm::CallBase *call;
2752 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2753 call->setMetadata(msgSendMDKind, node);
2763 llvm::Value *Receiver,
2770 if (CGM.
getLangOpts().getGC() == LangOptions::GCOnly) {
2771 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2775 if (Sel == ReleaseSel) {
2786 cmd = GetSelector(CGF, Method);
2788 cmd = GetSelector(CGF, Sel);
2789 cmd = EnforceType(Builder, cmd, SelectorTy);
2792 Receiver = EnforceType(Builder, Receiver, IdTy);
2794 llvm::Metadata *impMD[] = {
2795 llvm::MDString::get(VMContext, Sel.
getAsString()),
2796 llvm::MDString::get(VMContext, Class ?
Class->getNameAsString() :
""),
2797 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2798 llvm::Type::getInt1Ty(VMContext), Class !=
nullptr))};
2799 llvm::MDNode *
node = llvm::MDNode::get(VMContext, impMD);
2807 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2828 bool hasParamDestroyedInCallee =
false;
2829 bool requiresExplicitZeroResult =
false;
2830 bool requiresNilReceiverCheck = [&] {
2832 if (!canMessageReceiverBeNull(CGF, Method,
false,
2838 hasParamDestroyedInCallee =
true;
2859 requiresExplicitZeroResult = !isDirect;
2863 return hasParamDestroyedInCallee || requiresExplicitZeroResult;
2869 bool requiresExplicitAggZeroing =
2873 llvm::BasicBlock *continueBB =
nullptr;
2875 llvm::BasicBlock *nilPathBB =
nullptr;
2877 llvm::BasicBlock *nilCleanupBB =
nullptr;
2880 if (requiresNilReceiverCheck) {
2887 if (requiresExplicitAggZeroing || hasParamDestroyedInCallee) {
2890 nilPathBB = Builder.GetInsertBlock();
2893 llvm::Value *isNil = Builder.CreateICmpEQ(Receiver,
2894 llvm::Constant::getNullValue(Receiver->getType()));
2895 Builder.CreateCondBr(isNil, nilCleanupBB ? nilCleanupBB : continueBB,
2912 imp = LookupIMP(CGF, Receiver, cmd, node, MSI);
2916 StringRef
name =
"objc_msgSend";
2918 name =
"objc_msgSend_fpret";
2920 name =
"objc_msgSend_stret";
2924 bool shouldCheckForInReg =
2928 .isWindowsMSVCEnvironment() &&
2931 name =
"objc_msgSend_stret2";
2944 imp = EnforceType(Builder, imp, MSI.MessengerType);
2946 llvm::CallBase *call;
2948 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2950 call->setMetadata(msgSendMDKind, node);
2952 if (requiresNilReceiverCheck) {
2953 llvm::BasicBlock *nonNilPathBB = CGF.
Builder.GetInsertBlock();
2954 CGF.
Builder.CreateBr(continueBB);
2960 if (hasParamDestroyedInCallee) {
2961 destroyCalleeDestroyedArguments(CGF, Method, CallArgs);
2964 if (requiresExplicitAggZeroing) {
2970 nilPathBB = CGF.
Builder.GetInsertBlock();
2971 CGF.
Builder.CreateBr(continueBB);
2979 llvm::PHINode *phi = Builder.CreatePHI(
v->getType(), 2);
2980 phi->addIncoming(
v, nonNilPathBB);
2988 llvm::PHINode *phi = Builder.CreatePHI(
v.first->getType(), 2);
2989 phi->addIncoming(
v.first, nonNilPathBB);
2990 phi->addIncoming(llvm::Constant::getNullValue(
v.first->getType()),
2992 llvm::PHINode *phi2 = Builder.CreatePHI(
v.second->getType(), 2);
2993 phi2->addIncoming(
v.second, nonNilPathBB);
2994 phi2->addIncoming(llvm::Constant::getNullValue(
v.second->getType()),
3004llvm::Constant *CGObjCGNU::
3005GenerateMethodList(StringRef ClassName,
3006 StringRef CategoryName,
3008 bool isClassMethodList) {
3009 if (Methods.empty())
3014 auto MethodList = Builder.beginStruct();
3015 MethodList.addNullPointer(CGM.
Int8PtrTy);
3016 MethodList.addInt(Int32Ty, Methods.size());
3019 llvm::StructType *ObjCMethodTy =
3028 const llvm::DataLayout &DL = TheModule.getDataLayout();
3029 MethodList.addInt(SizeTy, DL.getTypeSizeInBits(ObjCMethodTy) /
3045 auto MethodArray = MethodList.beginArray();
3047 for (
const auto *OMD : Methods) {
3048 llvm::Constant *FnPtr =
3049 TheModule.getFunction(getSymbolNameForMethod(OMD));
3050 assert(FnPtr &&
"Can't generate metadata for method that doesn't exist");
3051 auto Method = MethodArray.beginStruct(ObjCMethodTy);
3062 Method.finishAndAddTo(MethodArray);
3064 MethodArray.finishAndAddTo(MethodList);
3067 return MethodList.finishAndCreateGlobal(
".objc_method_list",
3072llvm::Constant *CGObjCGNU::
3078 if (IvarNames.empty())
3084 auto IvarList = Builder.beginStruct();
3085 IvarList.addInt(IntTy, (
int)IvarNames.size());
3088 llvm::StructType *ObjCIvarTy =
3089 llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, IntTy);
3092 auto Ivars = IvarList.beginArray(ObjCIvarTy);
3093 for (
unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {
3094 auto Ivar = Ivars.beginStruct(ObjCIvarTy);
3095 Ivar.
add(IvarNames[i]);
3096 Ivar.
add(IvarTypes[i]);
3097 Ivar.
add(IvarOffsets[i]);
3098 Ivar.finishAndAddTo(Ivars);
3100 Ivars.finishAndAddTo(IvarList);
3103 return IvarList.finishAndCreateGlobal(
".objc_ivar_list",
3108llvm::Constant *CGObjCGNU::GenerateClassStructure(
3109 llvm::Constant *MetaClass,
3110 llvm::Constant *SuperClass,
3113 llvm::Constant *Version,
3114 llvm::Constant *InstanceSize,
3115 llvm::Constant *IVars,
3116 llvm::Constant *Methods,
3117 llvm::Constant *Protocols,
3118 llvm::Constant *IvarOffsets,
3119 llvm::Constant *Properties,
3120 llvm::Constant *StrongIvarBitmap,
3121 llvm::Constant *WeakIvarBitmap,
3130 llvm::StructType *ClassTy = llvm::StructType::get(
3147 IvarOffsets->getType(),
3148 Properties->getType(),
3154 auto Elements = Builder.beginStruct(ClassTy);
3159 Elements.add(MetaClass);
3161 Elements.add(SuperClass);
3163 Elements.add(MakeConstantString(Name,
".class_name"));
3165 Elements.addInt(LongTy, 0);
3167 Elements.addInt(LongTy, info);
3170 const llvm::DataLayout &DL = TheModule.getDataLayout();
3171 Elements.addInt(LongTy, DL.getTypeSizeInBits(ClassTy) /
3174 Elements.add(InstanceSize);
3176 Elements.add(IVars);
3178 Elements.add(Methods);
3181 Elements.add(NULLPtr);
3183 Elements.add(NULLPtr);
3185 Elements.add(NULLPtr);
3187 Elements.add(Protocols);
3189 Elements.add(NULLPtr);
3191 Elements.addInt(LongTy, ClassABIVersion);
3193 Elements.add(IvarOffsets);
3195 Elements.add(Properties);
3197 Elements.add(StrongIvarBitmap);
3199 Elements.add(WeakIvarBitmap);
3204 std::string ClassSym((isMeta ?
"_OBJC_METACLASS_":
"_OBJC_CLASS_") +
3206 llvm::GlobalVariable *ClassRef = TheModule.getNamedGlobal(ClassSym);
3207 llvm::Constant *
Class =
3208 Elements.finishAndCreateGlobal(ClassSym, CGM.
getPointerAlign(),
false,
3209 llvm::GlobalValue::ExternalLinkage);
3211 ClassRef->replaceAllUsesWith(Class);
3212 ClassRef->removeFromParent();
3213 Class->setName(ClassSym);
3218llvm::Constant *CGObjCGNU::
3221 llvm::StructType *ObjCMethodDescTy =
3222 llvm::StructType::get(CGM.
getLLVMContext(), { PtrToInt8Ty, PtrToInt8Ty });
3225 auto MethodList = Builder.beginStruct();
3226 MethodList.addInt(IntTy, Methods.size());
3227 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
3228 for (
auto *M : Methods) {
3229 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
3230 Method.
add(MakeConstantString(M->getSelector().getAsString()));
3232 Method.finishAndAddTo(MethodArray);
3234 MethodArray.finishAndAddTo(MethodList);
3235 return MethodList.finishAndCreateGlobal(
".objc_method_list",
3244 auto ProtocolList = Builder.beginStruct();
3245 ProtocolList.add(NULLPtr);
3246 ProtocolList.addInt(LongTy, Protocols.size());
3248 auto Elements = ProtocolList.beginArray(PtrToInt8Ty);
3249 for (
const std::string *iter = Protocols.begin(), *endIter = Protocols.end();
3250 iter != endIter ; iter++) {
3251 llvm::Constant *protocol =
nullptr;
3252 llvm::StringMap<llvm::Constant*>::iterator value =
3253 ExistingProtocols.find(*iter);
3254 if (value == ExistingProtocols.end()) {
3255 protocol = GenerateEmptyProtocol(*iter);
3257 protocol = value->getValue();
3259 Elements.add(protocol);
3261 Elements.finishAndAddTo(ProtocolList);
3262 return ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
3268 auto protocol = GenerateProtocolRef(PD);
3271 return CGF.
Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(
T));
3274llvm::Constant *CGObjCGNU::GenerateProtocolRef(
const ObjCProtocolDecl *PD) {
3277 GenerateProtocol(PD);
3278 assert(protocol &&
"Unknown protocol");
3283CGObjCGNU::GenerateEmptyProtocol(StringRef ProtocolName) {
3284 llvm::Constant *ProtocolList = GenerateProtocolList({});
3285 llvm::Constant *MethodList = GenerateProtocolMethodList({});
3289 auto Elements = Builder.beginStruct();
3293 Elements.add(llvm::ConstantExpr::getIntToPtr(
3294 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3296 Elements.add(MakeConstantString(ProtocolName,
".objc_protocol_name"));
3297 Elements.add(ProtocolList);
3298 Elements.add(MethodList);
3299 Elements.add(MethodList);
3300 Elements.add(MethodList);
3301 Elements.add(MethodList);
3302 Elements.add(NULLPtr);
3303 Elements.add(NULLPtr);
3304 return Elements.finishAndCreateGlobal(SymbolForProtocol(ProtocolName),
3320 Protocols.push_back(PI->getNameAsString());
3324 if (I->isOptional())
3325 OptionalInstanceMethods.push_back(I);
3327 InstanceMethods.push_back(I);
3332 if (I->isOptional())
3333 OptionalClassMethods.push_back(I);
3335 ClassMethods.push_back(I);
3337 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
3338 llvm::Constant *InstanceMethodList =
3339 GenerateProtocolMethodList(InstanceMethods);
3340 llvm::Constant *ClassMethodList =
3341 GenerateProtocolMethodList(ClassMethods);
3342 llvm::Constant *OptionalInstanceMethodList =
3343 GenerateProtocolMethodList(OptionalInstanceMethods);
3344 llvm::Constant *OptionalClassMethodList =
3345 GenerateProtocolMethodList(OptionalClassMethods);
3353 llvm::Constant *PropertyList =
3354 GeneratePropertyList(
nullptr, PD,
false,
false);
3355 llvm::Constant *OptionalPropertyList =
3356 GeneratePropertyList(
nullptr, PD,
false,
true);
3363 auto Elements = Builder.beginStruct();
3365 llvm::ConstantExpr::getIntToPtr(
3366 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3367 Elements.add(MakeConstantString(ProtocolName));
3368 Elements.add(ProtocolList);
3369 Elements.add(InstanceMethodList);
3370 Elements.add(ClassMethodList);
3371 Elements.add(OptionalInstanceMethodList);
3372 Elements.add(OptionalClassMethodList);
3373 Elements.add(PropertyList);
3374 Elements.add(OptionalPropertyList);
3375 ExistingProtocols[ProtocolName] =
3376 Elements.finishAndCreateGlobal(
".objc_protocol", CGM.
getPointerAlign());
3378void CGObjCGNU::GenerateProtocolHolderCategory() {
3382 auto Elements = Builder.beginStruct();
3384 const std::string ClassName =
"__ObjC_Protocol_Holder_Ugly_Hack";
3385 const std::string CategoryName =
"AnotherHack";
3386 Elements.add(MakeConstantString(CategoryName));
3387 Elements.add(MakeConstantString(ClassName));
3389 Elements.add(GenerateMethodList(ClassName, CategoryName, {},
false));
3391 Elements.add(GenerateMethodList(ClassName, CategoryName, {},
true));
3395 auto ProtocolList = ProtocolListBuilder.beginStruct();
3396 ProtocolList.add(NULLPtr);
3397 ProtocolList.addInt(LongTy, ExistingProtocols.size());
3398 auto ProtocolElements = ProtocolList.beginArray(PtrTy);
3399 for (
auto iter = ExistingProtocols.begin(), endIter = ExistingProtocols.end();
3400 iter != endIter ; iter++) {
3401 ProtocolElements.add(iter->getValue());
3403 ProtocolElements.finishAndAddTo(ProtocolList);
3404 Elements.add(ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
3406 Categories.push_back(
3422 int bitCount = bits.size();
3424 if (bitCount < ptrBits) {
3426 for (
int i=0 ; i<bitCount ; ++i) {
3427 if (bits[i]) val |= 1ULL<<(i+1);
3429 return llvm::ConstantInt::get(IntPtrTy, val);
3433 while (
v < bitCount) {
3435 for (
int i=0 ; (i<32) && (
v<bitCount) ; ++i) {
3436 if (bits[
v]) word |= 1<<i;
3439 values.push_back(llvm::ConstantInt::get(Int32Ty, word));
3443 auto fields = builder.beginStruct();
3444 fields.addInt(Int32Ty, values.size());
3445 auto array = fields.beginArray();
3446 for (
auto *
v : values) array.add(
v);
3447 array.finishAndAddTo(fields);
3449 llvm::Constant *GS =
3451 llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy);
3455llvm::Constant *CGObjCGNU::GenerateCategoryProtocolList(
const
3458 const auto RuntimeProtos =
3459 GetRuntimeProtocolList(RefPro.begin(), RefPro.end());
3461 for (
const auto *PD : RuntimeProtos)
3463 return GenerateProtocolList(Protocols);
3468 std::string ClassName =
Class->getNameAsString();
3475 auto Elements = Builder.beginStruct();
3476 Elements.add(MakeConstantString(CategoryName));
3477 Elements.add(MakeConstantString(ClassName));
3480 InstanceMethods.insert(InstanceMethods.begin(), OCD->
instmeth_begin(),
3483 GenerateMethodList(ClassName, CategoryName, InstanceMethods,
false));
3490 Elements.add(GenerateMethodList(ClassName, CategoryName, ClassMethods,
true));
3493 Elements.add(GenerateCategoryProtocolList(CatDecl));
3499 Elements.add(GeneratePropertyList(OCD,
Category,
false));
3501 Elements.add(GeneratePropertyList(OCD,
Category,
true));
3503 Elements.addNullPointer(PtrTy);
3504 Elements.addNullPointer(PtrTy);
3508 Categories.push_back(Elements.finishAndCreateGlobal(
3509 std::string(
".objc_category_") + ClassName + CategoryName,
3513llvm::Constant *CGObjCGNU::GeneratePropertyList(
const Decl *Container,
3515 bool isClassProperty,
3516 bool protocolOptionalProperties) {
3520 bool isProtocol = isa<ObjCProtocolDecl>(OCD);
3523 std::function<void(
const ObjCProtocolDecl *Proto)> collectProtocolProperties
3525 for (
const auto *
P : Proto->protocols())
3526 collectProtocolProperties(
P);
3527 for (
const auto *PD : Proto->properties()) {
3528 if (isClassProperty != PD->isClassProperty())
3536 Properties.push_back(PD);
3542 for (
auto *PD : ClassExt->properties()) {
3543 if (isClassProperty != PD->isClassProperty())
3546 Properties.push_back(PD);
3550 if (isClassProperty != PD->isClassProperty())
3554 if (isProtocol && (protocolOptionalProperties != PD->isOptional()))
3561 Properties.push_back(PD);
3566 collectProtocolProperties(
P);
3568 for (
const auto *
P : CD->protocols())
3569 collectProtocolProperties(
P);
3571 auto numProperties = Properties.size();
3573 if (numProperties == 0)
3577 auto propertyList = builder.beginStruct();
3578 auto properties = PushPropertyListHeader(propertyList, numProperties);
3582 for (
auto *property : Properties) {
3583 bool isSynthesized =
false;
3584 bool isDynamic =
false;
3588 isSynthesized = (propertyImpl->getPropertyImplementation() ==
3590 isDynamic = (propertyImpl->getPropertyImplementation() ==
3594 PushProperty(properties, property, Container, isSynthesized, isDynamic);
3596 properties.finishAndAddTo(propertyList);
3598 return propertyList.finishAndCreateGlobal(
".objc_property_list",
3616 std::string SuperClassName;
3617 if (SuperClassDecl) {
3619 EmitClassRef(SuperClassName);
3629 std::string classSymbolName =
"__objc_class_name_" + ClassName;
3630 if (
auto *symbol = TheModule.getGlobalVariable(classSymbolName)) {
3631 symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0));
3633 new llvm::GlobalVariable(TheModule, LongTy,
false,
3634 llvm::GlobalValue::ExternalLinkage,
3635 llvm::ConstantInt::get(LongTy, 0),
3651 auto IvarOffsetValues = IvarOffsetBuilder.beginArray(PtrToIntTy);
3655 int superInstanceSize = !SuperClassDecl ? 0 :
3660 instanceSize = 0 - (instanceSize - superInstanceSize);
3666 IvarNames.push_back(MakeConstantString(IVD->getNameAsString()));
3668 std::string TypeStr;
3670 IvarTypes.push_back(MakeConstantString(TypeStr));
3671 IvarAligns.push_back(llvm::ConstantInt::get(IntTy,
3674 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
3677 Offset = BaseOffset - superInstanceSize;
3679 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
3681 std::string OffsetName =
"__objc_ivar_offset_value_" + ClassName +
"." +
3682 IVD->getNameAsString();
3684 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
3686 OffsetVar->setInitializer(OffsetValue);
3690 OffsetVar->setLinkage(llvm::GlobalValue::ExternalLinkage);
3692 OffsetVar =
new llvm::GlobalVariable(TheModule, Int32Ty,
3693 false, llvm::GlobalValue::ExternalLinkage,
3694 OffsetValue, OffsetName);
3695 IvarOffsets.push_back(OffsetValue);
3696 IvarOffsetValues.add(OffsetVar);
3698 IvarOwnership.push_back(lt);
3701 StrongIvars.push_back(
true);
3702 WeakIvars.push_back(
false);
3705 StrongIvars.push_back(
false);
3706 WeakIvars.push_back(
true);
3709 StrongIvars.push_back(
false);
3710 WeakIvars.push_back(
false);
3713 llvm::Constant *StrongIvarBitmap = MakeBitField(StrongIvars);
3714 llvm::Constant *WeakIvarBitmap = MakeBitField(WeakIvars);
3715 llvm::GlobalVariable *IvarOffsetArray =
3716 IvarOffsetValues.finishAndCreateGlobal(
".ivar.offsets",
3721 InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
3728 llvm::Constant *Properties = GeneratePropertyList(OID, ClassDecl);
3731 auto RefProtocols = ClassDecl->
protocols();
3732 auto RuntimeProtocols =
3733 GetRuntimeProtocolList(RefProtocols.begin(), RefProtocols.end());
3735 for (
const auto *I : RuntimeProtocols)
3736 Protocols.push_back(I->getNameAsString());
3739 llvm::Constant *SuperClass;
3740 if (!SuperClassName.empty()) {
3741 SuperClass = MakeConstantString(SuperClassName,
".super_class_name");
3743 SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty);
3748 llvm::Constant *MethodList = GenerateMethodList(ClassName,
"",
3749 InstanceMethods,
false);
3750 llvm::Constant *ClassMethodList = GenerateMethodList(ClassName,
"",
3751 ClassMethods,
true);
3752 llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
3753 IvarOffsets, IvarAligns, IvarOwnership);
3764 llvm::Type *IndexTy = Int32Ty;
3765 llvm::Constant *offsetPointerIndexes[] = {Zeros[0],
3766 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 2 : 1),
nullptr,
3767 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 3 : 2) };
3769 unsigned ivarIndex = 0;
3772 const std::string Name = GetIVarOffsetVariableName(ClassDecl, IVD);
3773 offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, ivarIndex);
3775 llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr(
3776 cast<llvm::GlobalVariable>(IvarList)->getValueType(), IvarList,
3777 offsetPointerIndexes);
3779 llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name);
3781 offset->setInitializer(offsetValue);
3785 offset->setLinkage(llvm::GlobalValue::ExternalLinkage);
3788 new llvm::GlobalVariable(TheModule, offsetValue->getType(),
3789 false, llvm::GlobalValue::ExternalLinkage, offsetValue, Name);
3792 llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0);
3795 llvm::Constant *MetaClassStruct = GenerateClassStructure(
3796 NULLPtr, NULLPtr, 0x12L, ClassName.c_str(),
nullptr, Zeros[0],
3797 NULLPtr, ClassMethodList, NULLPtr, NULLPtr,
3798 GeneratePropertyList(OID, ClassDecl,
true), ZeroPtr, ZeroPtr,
true);
3803 llvm::Constant *ClassStruct = GenerateClassStructure(
3804 MetaClassStruct, SuperClass, 0x11L, ClassName.c_str(),
nullptr,
3805 llvm::ConstantInt::get(LongTy, instanceSize), IvarList, MethodList,
3806 GenerateProtocolList(Protocols), IvarOffsetArray, Properties,
3807 StrongIvarBitmap, WeakIvarBitmap);
3812 if (ClassPtrAlias) {
3813 ClassPtrAlias->replaceAllUsesWith(ClassStruct);
3814 ClassPtrAlias->eraseFromParent();
3815 ClassPtrAlias =
nullptr;
3817 if (MetaClassPtrAlias) {
3818 MetaClassPtrAlias->replaceAllUsesWith(MetaClassStruct);
3819 MetaClassPtrAlias->eraseFromParent();
3820 MetaClassPtrAlias =
nullptr;
3824 Classes.push_back(ClassStruct);
3827llvm::Function *CGObjCGNU::ModuleInitFunction() {
3829 if (Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
3834 GenerateProtocolHolderCategory();
3836 llvm::StructType *selStructTy = dyn_cast<llvm::StructType>(SelectorElemTy);
3839 { PtrToInt8Ty, PtrToInt8Ty });
3843 llvm::Constant *statics = NULLPtr;
3844 if (!ConstantStrings.empty()) {
3845 llvm::GlobalVariable *fileStatics = [&] {
3847 auto staticsStruct = builder.beginStruct();
3850 if (stringClass.empty()) stringClass =
"NXConstantString";
3851 staticsStruct.add(MakeConstantString(stringClass,
3852 ".objc_static_class_name"));
3854 auto array = staticsStruct.beginArray();
3855 array.addAll(ConstantStrings);
3857 array.finishAndAddTo(staticsStruct);
3859 return staticsStruct.finishAndCreateGlobal(
".objc_statics",
3864 auto allStaticsArray = builder.beginArray(fileStatics->getType());
3865 allStaticsArray.add(fileStatics);
3866 allStaticsArray.addNullPointer(fileStatics->getType());
3868 statics = allStaticsArray.finishAndCreateGlobal(
".objc_statics_ptr",
3875 unsigned selectorCount;
3878 llvm::GlobalVariable *selectorList = [&] {
3880 auto selectors = builder.beginArray(selStructTy);
3882 std::vector<Selector> allSelectors;
3883 for (
auto &entry : table)
3884 allSelectors.push_back(entry.first);
3885 llvm::sort(allSelectors);
3887 for (
auto &untypedSel : allSelectors) {
3888 std::string selNameStr = untypedSel.getAsString();
3889 llvm::Constant *selName = ExportUniqueString(selNameStr,
".objc_sel_name");
3891 for (TypedSelector &sel : table[untypedSel]) {
3892 llvm::Constant *selectorTypeEncoding = NULLPtr;
3893 if (!sel.first.empty())
3894 selectorTypeEncoding =
3895 MakeConstantString(sel.first,
".objc_sel_types");
3897 auto selStruct = selectors.beginStruct(selStructTy);
3898 selStruct.add(selName);
3899 selStruct.add(selectorTypeEncoding);
3900 selStruct.finishAndAddTo(selectors);
3903 selectorAliases.push_back(sel.second);
3908 selectorCount = selectors.size();
3914 auto selStruct = selectors.beginStruct(selStructTy);
3915 selStruct.add(NULLPtr);
3916 selStruct.add(NULLPtr);
3917 selStruct.finishAndAddTo(selectors);
3919 return selectors.finishAndCreateGlobal(
".objc_selector_list",
3924 for (
unsigned i = 0; i < selectorCount; ++i) {
3925 llvm::Constant *idxs[] = {
3927 llvm::ConstantInt::get(Int32Ty, i)
3930 llvm::Constant *selPtr = llvm::ConstantExpr::getGetElementPtr(
3931 selectorList->getValueType(), selectorList, idxs);
3932 selectorAliases[i]->replaceAllUsesWith(selPtr);
3933 selectorAliases[i]->eraseFromParent();
3936 llvm::GlobalVariable *symtab = [&] {
3938 auto symtab = builder.beginStruct();
3941 symtab.addInt(LongTy, selectorCount);
3943 symtab.add(selectorList);
3946 symtab.addInt(CGM.
Int16Ty, Classes.size());
3948 symtab.addInt(CGM.
Int16Ty, Categories.size());
3951 auto classList = symtab.beginArray(PtrToInt8Ty);
3952 classList.addAll(Classes);
3953 classList.addAll(Categories);
3955 classList.add(statics);
3956 classList.add(NULLPtr);
3957 classList.finishAndAddTo(symtab);
3965 llvm::Constant *module = [&] {
3966 llvm::Type *moduleEltTys[] = {
3967 LongTy, LongTy, PtrToInt8Ty, symtab->getType(), IntTy
3969 llvm::StructType *moduleTy = llvm::StructType::get(
3971 ArrayRef(moduleEltTys).drop_back(
unsigned(RuntimeVersion < 10)));
3974 auto module = builder.beginStruct(moduleTy);
3976 module.addInt(LongTy, RuntimeVersion);
3978 module.addInt(LongTy, CGM.
getDataLayout().getTypeStoreSize(moduleTy));
3985 module.add(MakeConstantString(path,
".objc_source_file_name"));
3988 if (RuntimeVersion >= 10) {
3990 case LangOptions::GCOnly:
3991 module.addInt(IntTy, 2);
3993 case LangOptions::NonGC:
3995 module.addInt(IntTy, 1);
3997 module.addInt(IntTy, 0);
3999 case LangOptions::HybridGC:
4000 module.addInt(IntTy, 1);
4010 llvm::Function * LoadFunction = llvm::Function::Create(
4011 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
4012 llvm::GlobalValue::InternalLinkage,
".objc_load_function",
4014 llvm::BasicBlock *EntryBB =
4015 llvm::BasicBlock::Create(VMContext,
"entry", LoadFunction);
4017 Builder.SetInsertPoint(EntryBB);
4019 llvm::FunctionType *FT =
4020 llvm::FunctionType::get(Builder.getVoidTy(), module->getType(),
true);
4021 llvm::FunctionCallee Register =
4023 Builder.CreateCall(Register, module);
4025 if (!ClassAliases.empty()) {
4026 llvm::Type *ArgTypes[2] = {PtrTy, PtrToInt8Ty};
4027 llvm::FunctionType *RegisterAliasTy =
4028 llvm::FunctionType::get(Builder.getVoidTy(),
4030 llvm::Function *RegisterAlias = llvm::Function::Create(
4032 llvm::GlobalValue::ExternalWeakLinkage,
"class_registerAlias_np",
4034 llvm::BasicBlock *AliasBB =
4035 llvm::BasicBlock::Create(VMContext,
"alias", LoadFunction);
4036 llvm::BasicBlock *NoAliasBB =
4037 llvm::BasicBlock::Create(VMContext,
"no_alias", LoadFunction);
4040 llvm::Value *HasRegisterAlias = Builder.CreateICmpNE(RegisterAlias,
4041 llvm::Constant::getNullValue(RegisterAlias->getType()));
4042 Builder.CreateCondBr(HasRegisterAlias, AliasBB, NoAliasBB);
4045 Builder.SetInsertPoint(AliasBB);
4047 for (std::vector<ClassAliasPair>::iterator iter = ClassAliases.begin();
4048 iter != ClassAliases.end(); ++iter) {
4049 llvm::Constant *TheClass =
4050 TheModule.getGlobalVariable(
"_OBJC_CLASS_" + iter->first,
true);
4052 Builder.CreateCall(RegisterAlias,
4053 {TheClass, MakeConstantString(iter->second)});
4057 Builder.CreateBr(NoAliasBB);
4060 Builder.SetInsertPoint(NoAliasBB);
4062 Builder.CreateRetVoid();
4064 return LoadFunction;
4067llvm::Function *CGObjCGNU::GenerateMethod(
const ObjCMethodDecl *OMD,
4070 llvm::FunctionType *MethodTy =
4071 Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
4074 std::string FunctionName =
4075 getSymbolNameForMethod(OMD, !isDirect);
4078 return llvm::Function::Create(MethodTy,
4079 llvm::GlobalVariable::InternalLinkage,
4080 FunctionName, &TheModule);
4083 auto I = DirectMethodDefinitions.find(COMD);
4084 llvm::Function *OldFn =
nullptr, *
Fn =
nullptr;
4086 if (I == DirectMethodDefinitions.end()) {
4088 llvm::Function::Create(MethodTy, llvm::GlobalVariable::ExternalLinkage,
4089 FunctionName, &TheModule);
4090 DirectMethodDefinitions.insert(std::make_pair(COMD, F));
4107 Fn = llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,
"",
4109 Fn->takeName(OldFn);
4110 OldFn->replaceAllUsesWith(Fn);
4111 OldFn->eraseFromParent();
4125llvm::FunctionCallee CGObjCGNU::GetPropertyGetFunction() {
4126 return GetPropertyFn;
4129llvm::FunctionCallee CGObjCGNU::GetPropertySetFunction() {
4130 return SetPropertyFn;
4133llvm::FunctionCallee CGObjCGNU::GetOptimizedPropertySetFunction(
bool atomic,
4138llvm::FunctionCallee CGObjCGNU::GetGetStructFunction() {
4139 return GetStructPropertyFn;
4142llvm::FunctionCallee CGObjCGNU::GetSetStructFunction() {
4143 return SetStructPropertyFn;
4146llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectGetFunction() {
4150llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectSetFunction() {
4154llvm::FunctionCallee CGObjCGNU::EnumerationMutationFunction() {
4155 return EnumerationMutationFn;
4160 EmitAtSynchronizedStmt(CGF, S, SyncEnterFn, SyncExitFn);
4177 EmitTryCatchStmt(CGF, S, EnterCatchFn, ExitCatchFn, ExceptionReThrowFn);
4182 bool ClearInsertionPoint) {
4183 llvm::Value *ExceptionAsObject;
4184 bool isRethrow =
false;
4186 if (
const Expr *ThrowExpr = S.getThrowExpr()) {
4188 ExceptionAsObject = Exception;
4191 "Unexpected rethrow outside @catch block.");
4195 if (isRethrow && (usesSEHExceptions || usesCxxExceptions)) {
4204 Throw->setDoesNotReturn();
4206 ExceptionAsObject = CGF.
Builder.CreateBitCast(ExceptionAsObject, IdTy);
4207 llvm::CallBase *Throw =
4209 Throw->setDoesNotReturn();
4211 CGF.
Builder.CreateUnreachable();
4212 if (ClearInsertionPoint)
4213 CGF.
Builder.ClearInsertionPoint();
4219 return B.CreateCall(
4220 WeakReadFn, EnforceType(B, AddrWeakObj.
emitRawPointer(CGF), PtrToIdTy));
4224 llvm::Value *src,
Address dst) {
4226 src = EnforceType(B, src, IdTy);
4227 llvm::Value *dstVal = EnforceType(B, dst.
emitRawPointer(CGF), PtrToIdTy);
4228 B.CreateCall(WeakAssignFn, {src, dstVal});
4232 llvm::Value *src,
Address dst,
4235 src = EnforceType(B, src, IdTy);
4236 llvm::Value *dstVal = EnforceType(B, dst.
emitRawPointer(CGF), PtrToIdTy);
4238 assert(!threadlocal &&
"EmitObjCGlobalAssign - Threal Local API NYI");
4239 B.CreateCall(GlobalAssignFn, {src, dstVal});
4243 llvm::Value *src,
Address dst,
4244 llvm::Value *ivarOffset) {
4246 src = EnforceType(B, src, IdTy);
4247 llvm::Value *dstVal = EnforceType(B, dst.
emitRawPointer(CGF), IdTy);
4248 B.CreateCall(IvarAssignFn, {src, dstVal, ivarOffset});
4252 llvm::Value *src,
Address dst) {
4254 src = EnforceType(B, src, IdTy);
4255 llvm::Value *dstVal = EnforceType(B, dst.
emitRawPointer(CGF), PtrToIdTy);
4256 B.CreateCall(StrongCastAssignFn, {src, dstVal});
4262 llvm::Value *Size) {
4264 llvm::Value *DestPtrVal = EnforceType(B, DestPtr.
emitRawPointer(CGF), PtrTy);
4265 llvm::Value *SrcPtrVal = EnforceType(B, SrcPtr.
emitRawPointer(CGF), PtrTy);
4267 B.CreateCall(MemMoveFn, {DestPtrVal, SrcPtrVal,
Size});
4270llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
4273 const std::string Name = GetIVarOffsetVariableName(ID, Ivar);
4277 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
4278 if (!IvarOffsetPointer)
4279 IvarOffsetPointer =
new llvm::GlobalVariable(
4280 TheModule, llvm::PointerType::getUnqual(VMContext),
false,
4281 llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
4282 return IvarOffsetPointer;
4287 llvm::Value *BaseValue,
4289 unsigned CVRQualifiers) {
4292 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
4293 EmitIvarOffset(CGF, ID, Ivar));
4321 if (RuntimeVersion < 10 ||
4323 return CGF.
Builder.CreateZExtOrBitCast(
4327 llvm::PointerType::getUnqual(VMContext),
4328 ObjCIvarOffsetVariable(
Interface, Ivar),
4332 std::string
name =
"__objc_ivar_offset_value_" +
4335 llvm::Value *Offset = TheModule.getGlobalVariable(name);
4337 auto GV =
new llvm::GlobalVariable(TheModule, IntTy,
4338 false, llvm::GlobalValue::LinkOnceAnyLinkage,
4339 llvm::Constant::getNullValue(IntTy), name);
4344 if (Offset->getType() != PtrDiffTy)
4345 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
4349 return llvm::ConstantInt::get(PtrDiffTy, Offset,
true);
4355 switch (Runtime.getKind()) {
4357 if (Runtime.getVersion() >= VersionTuple(2, 0))
4358 return new CGObjCGNUstep2(CGM);
4359 return new CGObjCGNUstep(CGM);
4362 return new CGObjCGCC(CGM);
4365 return new CGObjCObjFW(CGM);
4371 llvm_unreachable(
"these runtimes are not GNU runtimes");
4373 llvm_unreachable(
"bad runtime");
Defines the clang::ASTContext interface.
static const ObjCInterfaceDecl * FindIvarInterface(ASTContext &Context, const ObjCInterfaceDecl *OID, const ObjCIvarDecl *OIVD)
static bool isNamed(const NamedDecl *ND, const char(&Str)[Len])
Defines the SourceManager interface.
Defines the Objective-C statement AST node classes.
__device__ __2f16 float __ockl_bool s
__device__ __2f16 float c
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
TranslationUnitDecl * getTranslationUnitDecl() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
void getObjCEncodingForType(QualType T, std::string &S, const FieldDecl *Field=nullptr, QualType *NotEncodedT=nullptr) const
Emit the Objective-CC type encoding for the given type T into S.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
std::string getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, bool Extended=false) const
Emit the encoded type for the method declaration Decl into S.
std::string getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD, const Decl *Container) const
getObjCEncodingForPropertyDecl - Return the encoded type for this method declaration.
const ASTRecordLayout & getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const
Get or compute information about the layout of the specified Objective-C implementation.
const ASTRecordLayout & getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const
Get or compute information about the layout of the specified Objective-C interface.
QualType getObjCProtoType() const
Retrieve the type of the Objective-C Protocol class.
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
ObjCPropertyImplDecl * getObjCPropertyImplDeclForPropertyDecl(const ObjCPropertyDecl *PD, const Decl *Container) const
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
QualType getObjCIdType() const
Represents the Objective-CC id type.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
void getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT, QualType T, std::string &S, bool Extended) const
getObjCEncodingForMethodParameter - Return the encoded type for a single method parameter or return t...
const TargetInfo & getTargetInfo() const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
CharUnits getSize() const
getSize - Get the record size in characters.
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
CharUnits - This is an opaque type for sizes expressed in character units.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
CGBlockInfo - Information to generate a block literal.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
virtual llvm::Constant * getAddrOfRTTIDescriptor(QualType Ty)=0
virtual CatchTypeInfo getCatchAllTypeInfo()
Abstract information about a function or function prototype.
All available information about a concrete callee.
Implements runtime-specific code generation functions.
virtual llvm::Constant * GetEHType(QualType T)=0
Get the type constant to catch for the given ObjC pointer type.
virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest, llvm::Value *ivarOffset)=0
virtual llvm::FunctionCallee GetCppAtomicObjectGetFunction()=0
API for atomic copying of qualified aggregates with non-trivial copy assignment (c++) in getter.
virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest)=0
virtual llvm::Constant * BuildByrefLayout(CodeGen::CodeGenModule &CGM, QualType T)=0
Returns an i8* which points to the byref layout information.
virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, Address DestPtr, Address SrcPtr, llvm::Value *Size)=0
virtual llvm::FunctionCallee GetPropertySetFunction()=0
Return the runtime function for setting properties.
virtual llvm::FunctionCallee GetCppAtomicObjectSetFunction()=0
API for atomic copying of qualified aggregates with non-trivial copy assignment (c++) in setter.
virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtTryStmt &S)=0
virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, ReturnValueSlot ReturnSlot, QualType ResultType, Selector Sel, llvm::Value *Receiver, const CallArgList &CallArgs, const ObjCInterfaceDecl *Class=nullptr, const ObjCMethodDecl *Method=nullptr)=0
Generate an Objective-C message send operation.
virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy, llvm::Value *BaseValue, const ObjCIvarDecl *Ivar, unsigned CVRQualifiers)=0
virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD)=0
Register an class alias.
virtual void GenerateCategory(const ObjCCategoryImplDecl *OCD)=0
Generate a category.
virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S, bool ClearInsertionPoint=true)=0
virtual llvm::Value * EmitIvarOffset(CodeGen::CodeGenFunction &CGF, const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar)=0
virtual llvm::Function * GenerateMethod(const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD)=0
Generate a function preamble for a method with the specified types.
virtual llvm::Value * GenerateProtocolRef(CodeGenFunction &CGF, const ObjCProtocolDecl *OPD)=0
Emit the code to return the named protocol as an object, as in a @protocol expression.
virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, Address AddrWeakObj)=0
virtual llvm::Function * ModuleInitFunction()=0
Generate the function required to register all Objective-C components in this compilation unit with t...
virtual CodeGen::RValue GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, ReturnValueSlot ReturnSlot, QualType ResultType, Selector Sel, const ObjCInterfaceDecl *Class, bool isCategoryImpl, llvm::Value *Self, bool IsClassMessage, const CallArgList &CallArgs, const ObjCMethodDecl *Method=nullptr)=0
Generate an Objective-C message send operation to the super class initiated in a method for Class and...
virtual void GenerateClass(const ObjCImplementationDecl *OID)=0
Generate a class structure for this class.
virtual llvm::FunctionCallee EnumerationMutationFunction()=0
EnumerationMutationFunction - Return the function that's called by the compiler when a mutation is de...
virtual llvm::Constant * BuildGCBlockLayout(CodeGen::CodeGenModule &CGM, const CodeGen::CGBlockInfo &blockInfo)=0
virtual llvm::FunctionCallee GetGetStructFunction()=0
virtual llvm::Constant * GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0
GetOrEmitProtocol - Get the protocol object for the given declaration, emitting it if necessary.
virtual ConstantAddress GenerateConstantString(const StringLiteral *)=0
Generate a constant string object.
virtual llvm::Value * GetClass(CodeGenFunction &CGF, const ObjCInterfaceDecl *OID)=0
GetClass - Return a reference to the class for the given interface decl.
virtual void GenerateProtocol(const ObjCProtocolDecl *OPD)=0
Generate the named protocol.
virtual llvm::Constant * BuildRCBlockLayout(CodeGen::CodeGenModule &CGM, const CodeGen::CGBlockInfo &blockInfo)=0
virtual llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic, bool copy)=0
Return the runtime function for optimized setting properties.
virtual llvm::Value * GetSelector(CodeGenFunction &CGF, Selector Sel)=0
Get a selector for the specified name and type values.
virtual void GenerateDirectMethodPrologue(CodeGenFunction &CGF, llvm::Function *Fn, const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD)=0
Generates prologue for direct Objective-C Methods.
virtual Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel)=0
Get the address of a selector for the specified name and type values.
virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest)=0
virtual llvm::Value * EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF)
virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest, bool threadlocal=false)=0
virtual llvm::FunctionCallee GetPropertyGetFunction()=0
Return the runtime function for getting properties.
virtual llvm::FunctionCallee GetSetStructFunction()=0
virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S)=0
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
void addFrom(const CallArgList &other)
Add all the arguments from another CallArgList to this one.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
SmallVector< llvm::Value *, 8 > ObjCEHValueStack
ObjCEHValueStack - Stack of Objective-C exception values, used for rethrows.
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
JumpDest ReturnBlock
ReturnBlock - Unified return block.
llvm::Value * EmitObjCThrowOperand(const Expr *expr)
llvm::Value * LoadObjCSelf()
LoadObjCSelf - Load the value of self.
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
void EmitVarDecl(const VarDecl &D)
EmitVarDecl - Emit a local variable declaration.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
static bool hasAggregateEvaluationKind(QualType T)
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
This class organizes the cross-function state that is used while generating LLVM code.
void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const
Set visibility, dllimport/dllexport and dso_local.
llvm::Module & getModule() const
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
void addCompilerUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.compiler.used metadata.
bool ReturnTypeUsesFPRet(QualType ResultType)
Return true iff the given type uses 'fpret' when used as a return type.
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
void addUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.used metadata.
const llvm::DataLayout & getDataLayout() const
CGCXXABI & getCXXABI() const
const llvm::Triple & getTriple() const
bool ReturnTypeHasInReg(const CGFunctionInfo &FI)
Return true iff the given type has inreg set.
ASTContext & getContext() const
bool ReturnTypeUsesSRet(const CGFunctionInfo &FI)
Return true iff the given type uses 'sret' when used as a return type.
const CodeGenOptions & getCodeGenOpts() const
llvm::LLVMContext & getLLVMContext()
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
ConstantAddress GetAddrOfConstantCString(const std::string &Str, const char *GlobalName=nullptr)
Returns a pointer to a character array containing the literal and a terminating '\0' character.
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
bool isZeroInitializable(QualType T)
IsZeroInitializable - Return whether a type can be zero-initialized (in the C++ sense) with an LLVM z...
A specialization of Address that requires the address to be an LLVM Constant.
ArrayBuilder beginArray(llvm::Type *eltTy=nullptr)
llvm::GlobalVariable * finishAndCreateGlobal(As &&...args)
Given that this builder was created by beginning an array or struct directly on a ConstantInitBuilder...
StructBuilder beginStruct(llvm::StructType *ty=nullptr)
void finishAndAddTo(AggregateBuilderBase &parent)
Given that this builder was created by beginning an array or struct component on the given parent bui...
A helper class of ConstantInitBuilder, used for building constant array initializers.
The standard implementation of ConstantInitBuilder used in Clang.
A helper class of ConstantInitBuilder, used for building constant struct initializers.
LValue - This represents an lvalue references.
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
An abstract representation of an aligned address.
llvm::Value * getPointer() const
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
Decl - This represents one declaration (or definition), e.g.
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
StringRef getName() const
This represents one expression.
StringRef getName() const
The name of this FileEntry.
DirectoryEntryRef getDir() const
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
std::string ObjCConstantStringClass
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Visibility getVisibility() const
Determines the visibility of this entity.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
Represents Objective-C's @synchronized statement.
Represents Objective-C's @throw statement.
Represents Objective-C's @try ... @catch ... @finally statement.
ObjCCategoryDecl - Represents a category declaration.
const ObjCProtocolList & getReferencedProtocols() const
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
ObjCCategoryDecl * getCategoryDecl() const
ObjCCompatibleAliasDecl - Represents alias of a class.
const ObjCInterfaceDecl * getClassInterface() const
ObjCContainerDecl - Represents a container for method declarations.
classmeth_iterator classmeth_end() const
classmeth_iterator classmeth_begin() const
instmeth_range instance_methods() const
instmeth_iterator instmeth_end() const
instmeth_iterator instmeth_begin() const
prop_range properties() const
classmeth_range class_methods() const
propimpl_range property_impls() const
const ObjCInterfaceDecl * getClassInterface() const
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Represents an ObjC class declaration.
all_protocol_range all_referenced_protocols() const
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
protocol_range protocols() const
protocol_iterator protocol_end() const
protocol_iterator protocol_begin() const
ObjCInterfaceDecl * getSuperClass() const
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
known_extensions_range known_extensions() const
Interfaces are the core concept in Objective-C for object oriented design.
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
ObjCIvarDecl - Represents an ObjC instance variable.
AccessControl getAccessControl() const
ObjCInterfaceDecl * getContainingInterface()
Return the class interface that this ivar is logically contained in; this is either the interface whe...
ObjCIvarDecl * getNextIvar()
ObjCMethodDecl - Represents an instance or class method declaration.
ImplicitParamDecl * getSelfDecl() const
bool hasParamDestroyedInCallee() const
True if the method has a parameter that's destroyed in the callee.
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
ObjCMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Selector getSelector() const
ImplicitParamDecl * getCmdDecl() const
QualType getReturnType() const
bool isClassMethod() const
ObjCInterfaceDecl * getClassInterface()
Represents a pointer to an Objective C object.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
const ObjCInterfaceType * getInterfaceType() const
If this pointer points to an Objective C @interface type, gets the type for that interface.
Represents a class type in Objective C.
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface.
Represents one property declaration in an Objective-C interface.
ObjCMethodDecl * getGetterMethodDecl() const
ObjCMethodDecl * getSetterMethodDecl() const
Represents an Objective-C protocol declaration.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
bool isNonRuntimeProtocol() const
This is true iff the protocol is tagged with the objc_non_runtime_protocol attribute.
protocol_iterator protocol_begin() const
protocol_range protocols() const
protocol_iterator protocol_end() const
The basic abstraction for the target Objective-C runtime.
const VersionTuple & getVersion() const
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
Kind
The basic Objective-C runtimes that we know about.
@ MacOSX
'macosx' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the non-fragile AB...
@ FragileMacOSX
'macosx-fragile' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the fragil...
@ GNUstep
'gnustep' is the modern non-fragile GNUstep runtime.
@ ObjFW
'objfw' is the Objective-C runtime included in ObjFW
@ iOS
'ios' is the Apple-provided NeXT-derived runtime on iOS or the iOS simulator; it is always non-fragil...
@ GCC
'gcc' is the Objective-C runtime shipped with GCC, implementing a fragile Objective-C ABI
@ WatchOS
'watchos' is a variant of iOS for Apple's watchOS.
A (possibly-)qualified type.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
This table allows us to fully hide how we implement multi-keyword caching.
Smart pointer class that efficiently represents Objective-C method names.
std::string getAsString() const
Derive the full selector name (e.g.
This class handles loading and caching of source files into memory.
StringLiteral - This represents a string literal expression, e.g.
bool containsNonAscii() const
unsigned getLength() const
uint32_t getCodeUnit(size_t i) const
StringRef getString() const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
The top declaration context.
static DeclContext * castToDeclContext(const TranslationUnitDecl *D)
const T * castAs() const
Member-template castAs<specific type>.
bool isObjCQualifiedIdType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isObjCIdType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
Represents a variable declaration or definition.
CGObjCRuntime * CreateGNUObjCRuntime(CodeGenModule &CGM)
Creates an instance of an Objective-C runtime class.
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
bool Zero(InterpState &S, CodePtr OpPC)
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