32#include "llvm/ADT/SmallVector.h"
33#include "llvm/ADT/StringMap.h"
34#include "llvm/IR/DataLayout.h"
35#include "llvm/IR/Intrinsics.h"
36#include "llvm/IR/LLVMContext.h"
37#include "llvm/IR/Module.h"
38#include "llvm/Support/Compiler.h"
39#include "llvm/Support/ConvertUTF.h"
43using namespace CodeGen;
50class LazyRuntimeFunction {
52 llvm::FunctionType *FTy =
nullptr;
53 const char *FunctionName =
nullptr;
54 llvm::FunctionCallee
Function =
nullptr;
57 LazyRuntimeFunction() =
default;
61 template <
typename... Tys>
62 void init(
CodeGenModule *Mod,
const char *name, llvm::Type *RetTy,
69 FTy = llvm::FunctionType::get(RetTy, ArgTys,
false);
72 FTy = llvm::FunctionType::get(RetTy, std::nullopt,
false);
76 llvm::FunctionType *getType() {
return FTy; }
80 operator llvm::FunctionCallee() {
97 llvm::Module &TheModule;
100 llvm::StructType *ObjCSuperTy;
103 llvm::PointerType *PtrToObjCSuperTy;
107 llvm::PointerType *SelectorTy;
109 llvm::Type *SelectorElemTy;
112 llvm::IntegerType *Int8Ty;
115 llvm::PointerType *PtrToInt8Ty;
117 llvm::StructType *ProtocolTy;
119 llvm::PointerType *ProtocolPtrTy;
125 llvm::PointerType *IMPTy;
130 llvm::PointerType *IdTy;
132 llvm::Type *IdElemTy;
135 llvm::PointerType *PtrToIdTy;
140 llvm::IntegerType *IntTy;
144 llvm::PointerType *PtrTy;
148 llvm::IntegerType *LongTy;
150 llvm::IntegerType *SizeTy;
152 llvm::IntegerType *IntPtrTy;
154 llvm::IntegerType *PtrDiffTy;
157 llvm::PointerType *PtrToIntTy;
161 llvm::IntegerType *Int32Ty;
163 llvm::IntegerType *Int64Ty;
165 llvm::StructType *PropertyMetadataTy;
169 unsigned msgSendMDKind;
172 bool usesSEHExceptions;
174 bool usesCxxExceptions;
179 return (R.
getKind() == kind) &&
180 (R.
getVersion() >= VersionTuple(major, minor));
183 std::string ManglePublicSymbol(StringRef Name) {
184 return (StringRef(CGM.
getTriple().isOSBinFormatCOFF() ?
"$_" :
"._") + Name).str();
187 std::string SymbolForProtocol(Twine Name) {
188 return (ManglePublicSymbol(
"OBJC_PROTOCOL_") + Name).str();
191 std::string SymbolForProtocolRef(StringRef Name) {
192 return (ManglePublicSymbol(
"OBJC_REF_PROTOCOL_") + Name).str();
199 llvm::Constant *MakeConstantString(StringRef Str,
const char *Name =
"") {
202 return llvm::ConstantExpr::getGetElementPtr(Array.getElementType(),
203 Array.getPointer(), Zeros);
210 llvm::Constant *ExportUniqueString(
const std::string &Str,
211 const std::string &prefix,
212 bool Private=
false) {
213 std::string
name = prefix + Str;
214 auto *ConstStr = TheModule.getGlobalVariable(name);
216 llvm::Constant *value = llvm::ConstantDataArray::getString(VMContext,Str);
217 auto *GV =
new llvm::GlobalVariable(TheModule, value->getType(),
true,
218 llvm::GlobalValue::LinkOnceODRLinkage, value, name);
219 GV->setComdat(TheModule.getOrInsertComdat(name));
221 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
224 return llvm::ConstantExpr::getGetElementPtr(ConstStr->getValueType(),
230 const Decl *Container) {
233 std::string NameAndAttributes;
234 std::string TypeStr =
236 NameAndAttributes +=
'\0';
237 NameAndAttributes += TypeStr.length() + 3;
238 NameAndAttributes += TypeStr;
239 NameAndAttributes +=
'\0';
241 return MakeConstantString(NameAndAttributes);
250 int attrs =
property->getPropertyAttributes();
253 attrs &= ~ObjCPropertyAttribute::kind_copy;
254 attrs &= ~ObjCPropertyAttribute::kind_retain;
255 attrs &= ~ObjCPropertyAttribute::kind_weak;
256 attrs &= ~ObjCPropertyAttribute::kind_strong;
259 Fields.addInt(Int8Ty, attrs & 0xff);
265 attrs |= isSynthesized ? (1<<0) : 0;
266 attrs |= isDynamic ? (1<<1) : 0;
269 Fields.addInt(Int8Ty, attrs & 0xff);
271 Fields.addInt(Int8Ty, 0);
272 Fields.addInt(Int8Ty, 0);
275 virtual llvm::Constant *GenerateCategoryProtocolList(
const
280 Fields.addInt(IntTy, count);
283 llvm::DataLayout td(&TheModule);
284 Fields.addInt(IntTy, td.getTypeSizeInBits(PropertyMetadataTy) /
295 bool isSynthesized=
true,
bool
297 auto Fields = PropertiesArray.
beginStruct(PropertyMetadataTy);
299 Fields.add(MakePropertyEncodingString(property, OCD));
300 PushPropertyAttributes(Fields, property, isSynthesized, isDynamic);
304 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
305 Fields.add(MakeConstantString(accessor->getSelector().getAsString()));
306 Fields.add(TypeEncoding);
320 llvm::Value *EnforceType(
CGBuilderTy &B, llvm::Value *
V, llvm::Type *Ty) {
321 if (
V->getType() == Ty)
323 return B.CreateBitCast(
V, Ty);
327 llvm::Constant *Zeros[2];
329 llvm::Constant *NULLPtr;
331 llvm::LLVMContext &VMContext;
339 llvm::GlobalAlias *ClassPtrAlias;
344 llvm::GlobalAlias *MetaClassPtrAlias;
346 std::vector<llvm::Constant*> Classes;
348 std::vector<llvm::Constant*> Categories;
351 std::vector<llvm::Constant*> ConstantStrings;
355 llvm::StringMap<llvm::Constant*> ObjCStrings;
357 llvm::StringMap<llvm::Constant*> ExistingProtocols;
363 typedef std::pair<std::string, llvm::GlobalAlias*> TypedSelector;
367 typedef llvm::DenseMap<Selector, SmallVector<TypedSelector, 2> >
375 Selector RetainSel, ReleaseSel, AutoreleaseSel;
379 LazyRuntimeFunction IvarAssignFn, StrongCastAssignFn, MemMoveFn, WeakReadFn,
380 WeakAssignFn, GlobalAssignFn;
382 typedef std::pair<std::string, std::string> ClassAliasPair;
384 std::vector<ClassAliasPair> ClassAliases;
388 LazyRuntimeFunction ExceptionThrowFn;
391 LazyRuntimeFunction ExceptionReThrowFn;
394 LazyRuntimeFunction EnterCatchFn;
397 LazyRuntimeFunction ExitCatchFn;
399 LazyRuntimeFunction SyncEnterFn;
401 LazyRuntimeFunction SyncExitFn;
406 LazyRuntimeFunction EnumerationMutationFn;
409 LazyRuntimeFunction GetPropertyFn;
412 LazyRuntimeFunction SetPropertyFn;
414 LazyRuntimeFunction GetStructPropertyFn;
416 LazyRuntimeFunction SetStructPropertyFn;
428 const int ProtocolVersion;
431 const int ClassABIVersion;
447 llvm::Constant *GenerateMethodList(StringRef ClassName,
448 StringRef CategoryName,
450 bool isClassMethodList);
455 virtual llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName);
459 llvm::Constant *GeneratePropertyList(
const Decl *Container,
461 bool isClassProperty=
false,
462 bool protocolOptionalProperties=
false);
472 void GenerateProtocolHolderCategory();
475 llvm::Constant *GenerateClassStructure(
476 llvm::Constant *MetaClass,
477 llvm::Constant *SuperClass,
480 llvm::Constant *Version,
481 llvm::Constant *InstanceSize,
482 llvm::Constant *IVars,
483 llvm::Constant *Methods,
484 llvm::Constant *Protocols,
485 llvm::Constant *IvarOffsets,
486 llvm::Constant *Properties,
487 llvm::Constant *StrongIvarBitmap,
488 llvm::Constant *WeakIvarBitmap,
493 virtual llvm::Constant *GenerateProtocolMethodList(
497 void EmitProtocolMethodList(
T &&Methods, llvm::Constant *&
Required,
501 for (
const auto *I : Methods)
503 OptionalMethods.push_back(I);
505 RequiredMethods.push_back(I);
506 Required = GenerateProtocolMethodList(RequiredMethods);
507 Optional = GenerateProtocolMethodList(OptionalMethods);
513 const std::string &TypeEncoding);
520 const std::string Name =
"__objc_ivar_offset_" +
ID->getNameAsString()
529 void EmitClassRef(
const std::string &className);
533 const std::string &Name,
bool isWeak);
539 llvm::Value *&Receiver,
542 MessageSendInfo &MSI) = 0;
550 MessageSendInfo &MSI) = 0;
567 unsigned protocolClassVersion,
unsigned classABI=1);
574 llvm::Value *Receiver,
const CallArgList &CallArgs,
581 bool isCategoryImpl, llvm::Value *Receiver,
590 virtual llvm::Constant *GetConstantSelector(
Selector Sel,
591 const std::string &TypeEncoding) {
592 llvm_unreachable(
"Runtime unable to generate constant selector");
604 llvm::DenseMap<const ObjCMethodDecl *, llvm::Function *>
605 DirectMethodDefinitions;
639 bool ClearInsertionPoint=
true)
override;
643 llvm::Value *src,
Address dst)
override;
645 llvm::Value *src,
Address dest,
646 bool threadlocal=
false)
override;
648 Address dest, llvm::Value *ivarOffset)
override;
650 llvm::Value *src,
Address dest)
override;
653 llvm::Value *Size)
override;
656 unsigned CVRQualifiers)
override;
683class CGObjCGCC :
public CGObjCGNU {
686 LazyRuntimeFunction MsgLookupFn;
690 LazyRuntimeFunction MsgLookupSuperFn;
694 llvm::Value *cmd, llvm::MDNode *node,
695 MessageSendInfo &MSI)
override {
697 llvm::Value *args[] = {
698 EnforceType(Builder, Receiver, IdTy),
699 EnforceType(Builder, cmd, SelectorTy) };
701 imp->setMetadata(msgSendMDKind, node);
706 llvm::Value *cmd, MessageSendInfo &MSI)
override {
708 llvm::Value *lookupArgs[] = {
709 EnforceType(Builder, ObjCSuper.
emitRawPointer(CGF), PtrToObjCSuperTy),
717 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
719 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
720 PtrToObjCSuperTy, SelectorTy);
725class CGObjCGNUstep :
public CGObjCGNU {
728 LazyRuntimeFunction SlotLookupFn;
733 LazyRuntimeFunction SlotLookupSuperFn;
735 LazyRuntimeFunction SetPropertyAtomic;
737 LazyRuntimeFunction SetPropertyAtomicCopy;
739 LazyRuntimeFunction SetPropertyNonAtomic;
741 LazyRuntimeFunction SetPropertyNonAtomicCopy;
744 LazyRuntimeFunction CxxAtomicObjectGetFn;
747 LazyRuntimeFunction CxxAtomicObjectSetFn;
752 llvm::Type *SlotStructTy;
755 llvm::Constant *GetEHType(
QualType T)
override;
759 llvm::Value *cmd, llvm::MDNode *node,
760 MessageSendInfo &MSI)
override {
762 llvm::FunctionCallee LookupFn = SlotLookupFn;
767 Builder.CreateStore(Receiver, ReceiverPtr);
774 self = llvm::ConstantPointerNull::get(IdTy);
778 if (
auto *LookupFn2 = dyn_cast<llvm::Function>(LookupFn.getCallee()))
779 LookupFn2->addParamAttr(0, llvm::Attribute::NoCapture);
781 llvm::Value *args[] = {
782 EnforceType(Builder, ReceiverPtr.
getPointer(), PtrToIdTy),
783 EnforceType(Builder, cmd, SelectorTy),
784 EnforceType(Builder, self, IdTy)};
786 slot->setOnlyReadsMemory();
787 slot->setMetadata(msgSendMDKind, node);
790 llvm::Value *imp = Builder.CreateAlignedLoad(
791 IMPTy, Builder.CreateStructGEP(SlotStructTy, slot, 4),
796 Receiver = Builder.CreateLoad(ReceiverPtr,
true);
802 MessageSendInfo &MSI)
override {
806 llvm::CallInst *slot =
808 slot->setOnlyReadsMemory();
810 return Builder.CreateAlignedLoad(
811 IMPTy, Builder.CreateStructGEP(SlotStructTy, slot, 4),
816 CGObjCGNUstep(
CodeGenModule &Mod) : CGObjCGNUstep(Mod, 9, 3, 1) {}
817 CGObjCGNUstep(
CodeGenModule &Mod,
unsigned ABI,
unsigned ProtocolABI,
819 CGObjCGNU(Mod, ABI, ProtocolABI, ClassABI) {
822 SlotStructTy = llvm::StructType::get(PtrTy, PtrTy, PtrTy, IntTy, IMPTy);
823 SlotTy = llvm::PointerType::getUnqual(SlotStructTy);
825 SlotLookupFn.init(&CGM,
"objc_msg_lookup_sender", SlotTy, PtrToIdTy,
828 SlotLookupSuperFn.init(&CGM,
"objc_slot_lookup_super", SlotTy,
829 PtrToObjCSuperTy, SelectorTy);
831 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
832 if (usesCxxExceptions) {
834 EnterCatchFn.init(&CGM,
"__cxa_begin_catch", PtrTy, PtrTy);
836 ExitCatchFn.init(&CGM,
"__cxa_end_catch", VoidTy);
838 ExceptionReThrowFn.init(&CGM,
"__cxa_rethrow", PtrTy);
839 }
else if (usesSEHExceptions) {
841 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy);
844 EnterCatchFn.init(&CGM,
"__cxa_begin_catch", PtrTy, PtrTy);
846 ExitCatchFn.init(&CGM,
"__cxa_end_catch", VoidTy);
848 ExceptionReThrowFn.init(&CGM,
"_Unwind_Resume_or_Rethrow", VoidTy,
850 }
else if (R.
getVersion() >= VersionTuple(1, 7)) {
852 EnterCatchFn.init(&CGM,
"objc_begin_catch", IdTy, PtrTy);
854 ExitCatchFn.init(&CGM,
"objc_end_catch", VoidTy);
856 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy, PtrTy);
858 SetPropertyAtomic.init(&CGM,
"objc_setProperty_atomic", VoidTy, IdTy,
859 SelectorTy, IdTy, PtrDiffTy);
860 SetPropertyAtomicCopy.init(&CGM,
"objc_setProperty_atomic_copy", VoidTy,
861 IdTy, SelectorTy, IdTy, PtrDiffTy);
862 SetPropertyNonAtomic.init(&CGM,
"objc_setProperty_nonatomic", VoidTy,
863 IdTy, SelectorTy, IdTy, PtrDiffTy);
864 SetPropertyNonAtomicCopy.init(&CGM,
"objc_setProperty_nonatomic_copy",
865 VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy);
868 CxxAtomicObjectSetFn.init(&CGM,
"objc_setCppObjectAtomic", VoidTy, PtrTy,
872 CxxAtomicObjectGetFn.init(&CGM,
"objc_getCppObjectAtomic", VoidTy, PtrTy,
876 llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override {
881 return CxxAtomicObjectGetFn;
884 llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override {
889 return CxxAtomicObjectSetFn;
892 llvm::FunctionCallee GetOptimizedPropertySetFunction(
bool atomic,
893 bool copy)
override {
897 assert ((CGM.
getLangOpts().getGC() == LangOptions::NonGC));
904 if (copy)
return SetPropertyAtomicCopy;
905 return SetPropertyAtomic;
908 return copy ? SetPropertyNonAtomicCopy : SetPropertyNonAtomic;
915class CGObjCGNUstep2 :
public CGObjCGNUstep {
920 ClassReferenceSection,
923 ProtocolReferenceSection,
925 ConstantStringSection
930 ClassFlagMeta = (1 << 0),
933 ClassFlagInitialized = (1 << 8),
935 static const char *
const SectionsBaseNames[8];
936 static const char *
const PECOFFSectionsBaseNames[8];
937 template<SectionKind K>
938 std::string sectionName() {
939 if (CGM.
getTriple().isOSBinFormatCOFF()) {
940 std::string
name(PECOFFSectionsBaseNames[K]);
944 return SectionsBaseNames[K];
949 LazyRuntimeFunction MsgLookupSuperFn;
951 LazyRuntimeFunction SentInitializeFn;
955 bool EmittedProtocol =
false;
960 bool EmittedProtocolRef =
false;
964 bool EmittedClass =
false;
968 typedef std::pair<std::string, std::pair<llvm::GlobalVariable*, int>>
970 std::vector<EarlyInitPair> EarlyInitList;
972 std::string SymbolForClassRef(StringRef Name,
bool isWeak) {
974 return (ManglePublicSymbol(
"OBJC_WEAK_REF_CLASS_") + Name).str();
976 return (ManglePublicSymbol(
"OBJC_REF_CLASS_") + Name).str();
979 std::string SymbolForClass(StringRef Name) {
980 return (ManglePublicSymbol(
"OBJC_CLASS_") + Name).str();
982 void CallRuntimeFunction(
CGBuilderTy &B, StringRef FunctionName,
985 for (
auto *Arg : Args)
986 Types.push_back(Arg->getType());
987 llvm::FunctionType *FT = llvm::FunctionType::get(B.getVoidTy(), Types,
990 B.CreateCall(Fn, Args);
999 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
1000 if (old != ObjCStrings.end())
1008 (LiteralLength < 9) && !isNonASCII) {
1014 for (
unsigned i=0 ; i<LiteralLength ; i++)
1015 str |= ((uint64_t)SL->
getCodeUnit(i)) << ((64 - 4 - 3) - (i*7));
1017 str |= LiteralLength << 3;
1020 auto *ObjCStr = llvm::ConstantExpr::getIntToPtr(
1021 llvm::ConstantInt::get(Int64Ty, str), IdTy);
1022 ObjCStrings[Str] = ObjCStr;
1028 if (StringClass.empty()) StringClass =
"NSConstantString";
1030 std::string Sym = SymbolForClass(StringClass);
1032 llvm::Constant *
isa = TheModule.getNamedGlobal(Sym);
1035 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
1036 llvm::GlobalValue::ExternalLinkage,
nullptr, Sym);
1037 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1038 cast<llvm::GlobalValue>(isa)->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
1053 auto Fields = Builder.beginStruct();
1054 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
1057 Fields.addNullPointer(PtrTy);
1064 unsigned NumU8CodeUnits = Str.size();
1069 const llvm::UTF8 *FromPtr = (
const llvm::UTF8 *)Str.data();
1070 llvm::UTF16 *ToPtr = &ToBuf[0];
1071 (void)llvm::ConvertUTF8toUTF16(&FromPtr, FromPtr + NumU8CodeUnits,
1072 &ToPtr, ToPtr + NumU8CodeUnits, llvm::strictConversion);
1073 uint32_t StringLength = ToPtr - &ToBuf[0];
1077 Fields.addInt(Int32Ty, 2);
1079 Fields.addInt(Int32Ty, StringLength);
1081 Fields.addInt(Int32Ty, StringLength * 2);
1083 Fields.addInt(Int32Ty, 0);
1086 auto *
C = llvm::ConstantDataArray::get(VMContext, Arr);
1087 auto *Buffer =
new llvm::GlobalVariable(TheModule,
C->getType(),
1088 true, llvm::GlobalValue::PrivateLinkage,
C,
".str");
1089 Buffer->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1093 Fields.addInt(Int32Ty, 0);
1095 Fields.addInt(Int32Ty, Str.size());
1097 Fields.addInt(Int32Ty, Str.size());
1099 Fields.addInt(Int32Ty, 0);
1101 Fields.add(MakeConstantString(Str));
1103 std::string StringName;
1106 StringName =
".objc_str_";
1107 for (
int i=0,e=Str.size() ; i<e ; ++i) {
1108 unsigned char c = Str[i];
1119 llvm::GlobalVariable *ObjCStrGV =
1121 isNamed ? StringRef(StringName) :
".objc_string",
1122 Align,
false,
isNamed ? llvm::GlobalValue::LinkOnceODRLinkage
1123 : llvm::GlobalValue::PrivateLinkage);
1124 ObjCStrGV->setSection(sectionName<ConstantStringSection>());
1126 ObjCStrGV->setComdat(TheModule.getOrInsertComdat(StringName));
1127 ObjCStrGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1129 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1130 std::pair<llvm::GlobalVariable*, int>
v{ObjCStrGV, 0};
1131 EarlyInitList.emplace_back(Sym,
v);
1133 ObjCStrings[Str] = ObjCStrGV;
1134 ConstantStrings.push_back(ObjCStrGV);
1141 bool isSynthesized=
true,
bool
1142 isDynamic=
true)
override {
1151 auto Fields = PropertiesArray.
beginStruct(PropertyMetadataTy);
1154 std::string TypeStr =
1156 Fields.add(MakeConstantString(TypeStr));
1157 std::string typeStr;
1159 Fields.add(MakeConstantString(typeStr));
1163 Fields.add(GetConstantSelector(accessor->getSelector(), TypeStr));
1165 Fields.add(NULLPtr);
1180 llvm::StructType *ObjCMethodDescTy =
1182 { PtrToInt8Ty, PtrToInt8Ty });
1191 auto MethodList = Builder.beginStruct();
1193 MethodList.addInt(IntTy, Methods.size());
1195 llvm::DataLayout td(&TheModule);
1196 MethodList.addInt(IntTy, td.getTypeSizeInBits(ObjCMethodDescTy) /
1199 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
1200 for (
auto *M : Methods) {
1201 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
1202 Method.add(CGObjCGNU::GetConstantSelector(M));
1204 Method.finishAndAddTo(MethodArray);
1206 MethodArray.finishAndAddTo(MethodList);
1207 return MethodList.finishAndCreateGlobal(
".objc_protocol_method_list",
1213 auto RuntimeProtocols = GetRuntimeProtocolList(ReferencedProtocols.begin(),
1214 ReferencedProtocols.end());
1216 for (
const auto *PI : RuntimeProtocols)
1217 Protocols.push_back(GenerateProtocolRef(PI));
1218 return GenerateProtocolList(Protocols);
1222 llvm::Value *cmd, MessageSendInfo &MSI)
override {
1225 llvm::Value *lookupArgs[] = {
1232 llvm::GlobalVariable *GetClassVar(StringRef Name,
bool isWeak=
false) {
1233 std::string SymbolName = SymbolForClassRef(Name, isWeak);
1234 auto *ClassSymbol = TheModule.getNamedGlobal(SymbolName);
1237 ClassSymbol =
new llvm::GlobalVariable(TheModule,
1238 IdTy,
false, llvm::GlobalValue::ExternalLinkage,
1239 nullptr, SymbolName);
1245 ClassSymbol->setInitializer(
new llvm::GlobalVariable(TheModule,
1246 Int8Ty,
false, llvm::GlobalValue::ExternalWeakLinkage,
1247 nullptr, SymbolForClass(Name)));
1249 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1255 for (
const auto *Result : DC->
lookup(&II))
1256 if ((OID = dyn_cast<ObjCInterfaceDecl>(Result)))
1262 assert(OID &&
"Failed to find ObjCInterfaceDecl");
1264 if (OIDDef !=
nullptr)
1267 auto Storage = llvm::GlobalValue::DefaultStorageClass;
1268 if (OID->
hasAttr<DLLImportAttr>())
1269 Storage = llvm::GlobalValue::DLLImportStorageClass;
1270 else if (OID->
hasAttr<DLLExportAttr>())
1271 Storage = llvm::GlobalValue::DLLExportStorageClass;
1273 cast<llvm::GlobalValue>(ClassSymbol)->setDLLStorageClass(Storage);
1276 assert(ClassSymbol->getName() == SymbolName);
1280 const std::string &Name,
1281 bool isWeak)
override {
1293 switch (Ownership) {
1315 llvm_unreachable(
"Method should not be called!");
1318 llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName)
override {
1319 std::string Name = SymbolForProtocol(ProtocolName);
1320 auto *GV = TheModule.getGlobalVariable(Name);
1323 GV =
new llvm::GlobalVariable(TheModule, ProtocolTy,
false,
1324 llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
1331 llvm::StringMap<llvm::Constant*> ExistingProtocolRefs;
1336 auto *&Ref = ExistingProtocolRefs[Name];
1338 auto *&
Protocol = ExistingProtocols[Name];
1340 Protocol = GenerateProtocolRef(PD);
1341 std::string RefName = SymbolForProtocolRef(Name);
1342 assert(!TheModule.getGlobalVariable(RefName));
1344 auto GV =
new llvm::GlobalVariable(TheModule, ProtocolPtrTy,
false,
1345 llvm::GlobalValue::LinkOnceODRLinkage,
1347 GV->setComdat(TheModule.getOrInsertComdat(RefName));
1348 GV->setSection(sectionName<ProtocolReferenceSection>());
1352 EmittedProtocolRef =
true;
1358 llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(ProtocolPtrTy,
1360 llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
1363 auto ProtocolBuilder = builder.beginStruct();
1364 ProtocolBuilder.addNullPointer(PtrTy);
1365 ProtocolBuilder.addInt(SizeTy, Protocols.size());
1366 ProtocolBuilder.add(ProtocolArray);
1367 return ProtocolBuilder.finishAndCreateGlobal(
".objc_protocol_list",
1376 auto *&
Protocol = ExistingProtocols[ProtocolName];
1380 EmittedProtocol =
true;
1382 auto SymName = SymbolForProtocol(ProtocolName);
1383 auto *OldGV = TheModule.getGlobalVariable(SymName);
1393 Protocol =
new llvm::GlobalVariable(TheModule, ProtocolTy,
1395 llvm::GlobalValue::ExternalLinkage,
nullptr, SymName);
1400 auto RuntimeProtocols =
1402 for (
const auto *PI : RuntimeProtocols)
1403 Protocols.push_back(GenerateProtocolRef(PI));
1404 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
1407 llvm::Constant *InstanceMethodList, *OptionalInstanceMethodList;
1408 llvm::Constant *ClassMethodList, *OptionalClassMethodList;
1410 OptionalInstanceMethodList);
1411 EmitProtocolMethodList(PD->
class_methods(), ClassMethodList,
1412 OptionalClassMethodList);
1417 auto ProtocolBuilder = builder.beginStruct();
1418 ProtocolBuilder.add(llvm::ConstantExpr::getIntToPtr(
1419 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
1420 ProtocolBuilder.add(MakeConstantString(ProtocolName));
1421 ProtocolBuilder.add(ProtocolList);
1422 ProtocolBuilder.add(InstanceMethodList);
1423 ProtocolBuilder.add(ClassMethodList);
1424 ProtocolBuilder.add(OptionalInstanceMethodList);
1425 ProtocolBuilder.add(OptionalClassMethodList);
1427 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
false,
false));
1429 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
false,
true));
1431 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
true,
false));
1433 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
true,
true));
1435 auto *GV = ProtocolBuilder.finishAndCreateGlobal(SymName,
1437 GV->setSection(sectionName<ProtocolSection>());
1438 GV->setComdat(TheModule.getOrInsertComdat(SymName));
1440 OldGV->replaceAllUsesWith(GV);
1441 OldGV->removeFromParent();
1442 GV->setName(SymName);
1448 const std::string &TypeEncoding)
override {
1449 return GetConstantSelector(Sel, TypeEncoding);
1451 std::string GetSymbolNameForTypeEncoding(
const std::string &TypeEncoding) {
1452 std::string MangledTypes = std::string(TypeEncoding);
1458 std::replace(MangledTypes.begin(), MangledTypes.end(),
'@',
'\1');
1461 std::replace(MangledTypes.begin(), MangledTypes.end(),
'=',
'\2');
1462 return MangledTypes;
1464 llvm::Constant *GetTypeString(llvm::StringRef TypeEncoding) {
1465 if (TypeEncoding.empty())
1467 std::string MangledTypes =
1468 GetSymbolNameForTypeEncoding(std::string(TypeEncoding));
1469 std::string TypesVarName =
".objc_sel_types_" + MangledTypes;
1470 auto *TypesGlobal = TheModule.getGlobalVariable(TypesVarName);
1472 llvm::Constant *
Init = llvm::ConstantDataArray::getString(VMContext,
1474 auto *GV =
new llvm::GlobalVariable(TheModule,
Init->getType(),
1475 true, llvm::GlobalValue::LinkOnceODRLinkage,
Init, TypesVarName);
1476 GV->setComdat(TheModule.getOrInsertComdat(TypesVarName));
1477 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1480 return llvm::ConstantExpr::getGetElementPtr(TypesGlobal->getValueType(),
1481 TypesGlobal, Zeros);
1483 llvm::Constant *GetConstantSelector(
Selector Sel,
1484 const std::string &TypeEncoding)
override {
1485 std::string MangledTypes = GetSymbolNameForTypeEncoding(TypeEncoding);
1486 auto SelVarName = (StringRef(
".objc_selector_") + Sel.
getAsString() +
"_" +
1487 MangledTypes).str();
1488 if (
auto *GV = TheModule.getNamedGlobal(SelVarName))
1491 auto SelBuilder = builder.beginStruct();
1492 SelBuilder.add(ExportUniqueString(Sel.
getAsString(),
".objc_sel_name_",
1494 SelBuilder.add(GetTypeString(TypeEncoding));
1495 auto *GV = SelBuilder.finishAndCreateGlobal(SelVarName,
1497 GV->setComdat(TheModule.getOrInsertComdat(SelVarName));
1498 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1499 GV->setSection(sectionName<SelectorSection>());
1502 llvm::StructType *emptyStruct =
nullptr;
1511 std::pair<llvm::Constant*,llvm::Constant*>
1512 GetSectionBounds(StringRef Section) {
1513 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1514 if (emptyStruct ==
nullptr) {
1515 emptyStruct = llvm::StructType::create(VMContext,
".objc_section_sentinel");
1516 emptyStruct->setBody({},
true);
1518 auto ZeroInit = llvm::Constant::getNullValue(emptyStruct);
1519 auto Sym = [&](StringRef Prefix, StringRef SecSuffix) {
1520 auto *Sym =
new llvm::GlobalVariable(TheModule, emptyStruct,
1522 llvm::GlobalValue::LinkOnceODRLinkage, ZeroInit, Prefix +
1524 Sym->setVisibility(llvm::GlobalValue::HiddenVisibility);
1525 Sym->setSection((Section + SecSuffix).str());
1526 Sym->setComdat(TheModule.getOrInsertComdat((Prefix +
1531 return { Sym(
"__start_",
"$a"), Sym(
"__stop",
"$z") };
1533 auto *Start =
new llvm::GlobalVariable(TheModule, PtrTy,
1535 llvm::GlobalValue::ExternalLinkage,
nullptr, StringRef(
"__start_") +
1537 Start->setVisibility(llvm::GlobalValue::HiddenVisibility);
1538 auto *Stop =
new llvm::GlobalVariable(TheModule, PtrTy,
1540 llvm::GlobalValue::ExternalLinkage,
nullptr, StringRef(
"__stop_") +
1542 Stop->setVisibility(llvm::GlobalValue::HiddenVisibility);
1543 return { Start, Stop };
1548 llvm::Function *ModuleInitFunction()
override {
1549 llvm::Function *LoadFunction = llvm::Function::Create(
1550 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
1551 llvm::GlobalValue::LinkOnceODRLinkage,
".objcv2_load_function",
1553 LoadFunction->setVisibility(llvm::GlobalValue::HiddenVisibility);
1554 LoadFunction->setComdat(TheModule.getOrInsertComdat(
".objcv2_load_function"));
1556 llvm::BasicBlock *EntryBB =
1557 llvm::BasicBlock::Create(VMContext,
"entry", LoadFunction);
1559 B.SetInsertPoint(EntryBB);
1561 auto InitStructBuilder = builder.beginStruct();
1562 InitStructBuilder.addInt(Int64Ty, 0);
1563 auto §ionVec = CGM.
getTriple().isOSBinFormatCOFF() ? PECOFFSectionsBaseNames : SectionsBaseNames;
1564 for (
auto *
s : sectionVec) {
1565 auto bounds = GetSectionBounds(
s);
1566 InitStructBuilder.add(bounds.first);
1567 InitStructBuilder.add(bounds.second);
1569 auto *InitStruct = InitStructBuilder.finishAndCreateGlobal(
".objc_init",
1571 InitStruct->setVisibility(llvm::GlobalValue::HiddenVisibility);
1572 InitStruct->setComdat(TheModule.getOrInsertComdat(
".objc_init"));
1574 CallRuntimeFunction(B,
"__objc_load", {InitStruct});;
1581 auto *InitVar =
new llvm::GlobalVariable(TheModule, LoadFunction->getType(),
1582 false, llvm::GlobalValue::LinkOnceAnyLinkage,
1583 LoadFunction,
".objc_ctor");
1586 assert(InitVar->getName() ==
".objc_ctor");
1592 if (CGM.
getTriple().isOSBinFormatCOFF())
1593 InitVar->setSection(
".CRT$XCLz");
1597 InitVar->setSection(
".init_array");
1599 InitVar->setSection(
".ctors");
1601 InitVar->setVisibility(llvm::GlobalValue::HiddenVisibility);
1602 InitVar->setComdat(TheModule.getOrInsertComdat(
".objc_ctor"));
1604 for (
auto *
C : Categories) {
1605 auto *Cat = cast<llvm::GlobalVariable>(
C->stripPointerCasts());
1606 Cat->setSection(sectionName<CategorySection>());
1610 StringRef Section) {
1611 auto nullBuilder = builder.beginStruct();
1612 for (
auto *F :
Init)
1614 auto GV = nullBuilder.finishAndCreateGlobal(Name, CGM.
getPointerAlign(),
1615 false, llvm::GlobalValue::LinkOnceODRLinkage);
1616 GV->setSection(Section);
1617 GV->setComdat(TheModule.getOrInsertComdat(Name));
1618 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1622 for (
auto clsAlias : ClassAliases)
1623 createNullGlobal(std::string(
".objc_class_alias") +
1624 clsAlias.second, { MakeConstantString(clsAlias.second),
1625 GetClassVar(clsAlias.first) }, sectionName<ClassAliasSection>());
1630 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
1631 createNullGlobal(
".objc_null_selector", {NULLPtr, NULLPtr},
1632 sectionName<SelectorSection>());
1633 if (Categories.empty())
1634 createNullGlobal(
".objc_null_category", {NULLPtr, NULLPtr,
1635 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr},
1636 sectionName<CategorySection>());
1637 if (!EmittedClass) {
1638 createNullGlobal(
".objc_null_cls_init_ref", NULLPtr,
1639 sectionName<ClassSection>());
1640 createNullGlobal(
".objc_null_class_ref", { NULLPtr, NULLPtr },
1641 sectionName<ClassReferenceSection>());
1643 if (!EmittedProtocol)
1644 createNullGlobal(
".objc_null_protocol", {NULLPtr, NULLPtr, NULLPtr,
1645 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr,
1646 NULLPtr}, sectionName<ProtocolSection>());
1647 if (!EmittedProtocolRef)
1648 createNullGlobal(
".objc_null_protocol_ref", {NULLPtr},
1649 sectionName<ProtocolReferenceSection>());
1650 if (ClassAliases.empty())
1651 createNullGlobal(
".objc_null_class_alias", { NULLPtr, NULLPtr },
1652 sectionName<ClassAliasSection>());
1653 if (ConstantStrings.empty()) {
1654 auto i32Zero = llvm::ConstantInt::get(Int32Ty, 0);
1655 createNullGlobal(
".objc_null_constant_string", { NULLPtr, i32Zero,
1656 i32Zero, i32Zero, i32Zero, NULLPtr },
1657 sectionName<ConstantStringSection>());
1660 ConstantStrings.clear();
1664 if (EarlyInitList.size() > 0) {
1665 auto *
Init = llvm::Function::Create(llvm::FunctionType::get(CGM.
VoidTy,
1666 {}), llvm::GlobalValue::InternalLinkage,
".objc_early_init",
1668 llvm::IRBuilder<>
b(llvm::BasicBlock::Create(CGM.
getLLVMContext(),
"entry",
1670 for (
const auto &lateInit : EarlyInitList) {
1671 auto *global = TheModule.getGlobalVariable(lateInit.first);
1673 llvm::GlobalVariable *GV = lateInit.second.first;
1674 b.CreateAlignedStore(
1676 b.CreateStructGEP(GV->getValueType(), GV, lateInit.second.second),
1683 auto *InitVar =
new llvm::GlobalVariable(CGM.
getModule(),
Init->getType(),
1684 true, llvm::GlobalValue::InternalLinkage,
1685 Init,
".objc_early_init_ptr");
1686 InitVar->setSection(
".CRT$XCLb");
1695 std::string TypeEncoding;
1697 TypeEncoding = GetSymbolNameForTypeEncoding(TypeEncoding);
1698 const std::string Name =
"__objc_ivar_offset_" +
ID->getNameAsString()
1706 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
1707 if (!IvarOffsetPointer)
1708 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule, IntTy,
false,
1709 llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
1711 llvm::Value *Offset =
1713 if (Offset->getType() != PtrDiffTy)
1714 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
1719 bool IsCOFF = CGM.
getTriple().isOSBinFormatCOFF();
1725 auto *classNameConstant = MakeConstantString(className);
1728 auto metaclassFields = builder.beginStruct();
1730 metaclassFields.addNullPointer(PtrTy);
1732 metaclassFields.addNullPointer(PtrTy);
1734 metaclassFields.add(classNameConstant);
1736 metaclassFields.addInt(LongTy, 0);
1739 metaclassFields.addInt(LongTy, ClassFlags::ClassFlagMeta);
1743 metaclassFields.addInt(LongTy, 0);
1745 metaclassFields.addNullPointer(PtrTy);
1750 metaclassFields.addNullPointer(PtrTy);
1755 metaclassFields.add(
1756 GenerateMethodList(className,
"", ClassMethods,
true));
1759 metaclassFields.addNullPointer(PtrTy);
1761 metaclassFields.addNullPointer(PtrTy);
1763 metaclassFields.addNullPointer(PtrTy);
1765 metaclassFields.addNullPointer(PtrTy);
1767 metaclassFields.addNullPointer(PtrTy);
1769 metaclassFields.addNullPointer(PtrTy);
1771 metaclassFields.addNullPointer(PtrTy);
1773 metaclassFields.addInt(LongTy, 0);
1775 metaclassFields.add(GeneratePropertyList(OID, classDecl,
true));
1777 auto *metaclass = metaclassFields.finishAndCreateGlobal(
1778 ManglePublicSymbol(
"OBJC_METACLASS_") + className,
1781 auto classFields = builder.beginStruct();
1783 classFields.add(metaclass);
1788 llvm::Constant *SuperClass =
nullptr;
1789 if (SuperClassDecl) {
1790 auto SuperClassName = SymbolForClass(SuperClassDecl->
getNameAsString());
1791 SuperClass = TheModule.getNamedGlobal(SuperClassName);
1794 SuperClass =
new llvm::GlobalVariable(TheModule, PtrTy,
false,
1795 llvm::GlobalValue::ExternalLinkage,
nullptr, SuperClassName);
1797 auto Storage = llvm::GlobalValue::DefaultStorageClass;
1798 if (SuperClassDecl->
hasAttr<DLLImportAttr>())
1799 Storage = llvm::GlobalValue::DLLImportStorageClass;
1800 else if (SuperClassDecl->
hasAttr<DLLExportAttr>())
1801 Storage = llvm::GlobalValue::DLLExportStorageClass;
1803 cast<llvm::GlobalValue>(SuperClass)->setDLLStorageClass(Storage);
1807 classFields.add(SuperClass);
1809 classFields.addNullPointer(PtrTy);
1811 classFields.addNullPointer(PtrTy);
1813 classFields.add(classNameConstant);
1815 classFields.addInt(LongTy, 0);
1818 classFields.addInt(LongTy, 0);
1820 int superInstanceSize = !SuperClassDecl ? 0 :
1824 classFields.addInt(LongTy,
1826 superInstanceSize));
1829 classFields.addNullPointer(PtrTy);
1834 llvm::DataLayout td(&TheModule);
1837 auto ivarListBuilder =
b.beginStruct();
1839 ivarListBuilder.addInt(IntTy, ivar_count);
1841 llvm::StructType *ObjCIvarTy = llvm::StructType::get(
1847 ivarListBuilder.addInt(SizeTy, td.getTypeSizeInBits(ObjCIvarTy) /
1850 auto ivarArrayBuilder = ivarListBuilder.beginArray();
1853 auto ivarTy = IVD->getType();
1854 auto ivarBuilder = ivarArrayBuilder.beginStruct();
1856 ivarBuilder.add(MakeConstantString(IVD->getNameAsString()));
1858 std::string TypeStr;
1861 ivarBuilder.add(MakeConstantString(TypeStr));
1863 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
1864 uint64_t Offset = BaseOffset - superInstanceSize;
1865 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
1866 std::string OffsetName = GetIVarOffsetVariableName(classDecl, IVD);
1867 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
1869 OffsetVar->setInitializer(OffsetValue);
1871 OffsetVar =
new llvm::GlobalVariable(TheModule, IntTy,
1872 false, llvm::GlobalValue::ExternalLinkage,
1873 OffsetValue, OffsetName);
1874 auto ivarVisibility =
1878 llvm::GlobalValue::HiddenVisibility :
1879 llvm::GlobalValue::DefaultVisibility;
1880 OffsetVar->setVisibility(ivarVisibility);
1881 if (ivarVisibility != llvm::GlobalValue::HiddenVisibility)
1883 ivarBuilder.add(OffsetVar);
1885 ivarBuilder.addInt(Int32Ty,
1896 ivarBuilder.addInt(Int32Ty,
1897 (align << 3) | (1<<2) |
1898 FlagsForOwnership(ivarTy.getQualifiers().getObjCLifetime()));
1899 ivarBuilder.finishAndAddTo(ivarArrayBuilder);
1901 ivarArrayBuilder.finishAndAddTo(ivarListBuilder);
1902 auto ivarList = ivarListBuilder.finishAndCreateGlobal(
".objc_ivar_list",
1904 llvm::GlobalValue::PrivateLinkage);
1905 classFields.add(ivarList);
1909 InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
1912 if (propImpl->getPropertyImplementation() ==
1915 if (OMD && OMD->hasBody())
1916 InstanceMethods.push_back(OMD);
1918 addIfExists(propImpl->getGetterMethodDecl());
1919 addIfExists(propImpl->getSetterMethodDecl());
1922 if (InstanceMethods.size() == 0)
1923 classFields.addNullPointer(PtrTy);
1926 GenerateMethodList(className,
"", InstanceMethods,
false));
1929 classFields.addNullPointer(PtrTy);
1931 classFields.addNullPointer(PtrTy);
1933 classFields.addNullPointer(PtrTy);
1935 classFields.addNullPointer(PtrTy);
1937 classFields.addNullPointer(PtrTy);
1939 auto RuntimeProtocols = GetRuntimeProtocolList(classDecl->
protocol_begin(),
1942 for (
const auto *I : RuntimeProtocols)
1943 Protocols.push_back(GenerateProtocolRef(I));
1945 if (Protocols.empty())
1946 classFields.addNullPointer(PtrTy);
1948 classFields.add(GenerateProtocolList(Protocols));
1950 classFields.addNullPointer(PtrTy);
1952 classFields.addInt(LongTy, 0);
1954 classFields.add(GeneratePropertyList(OID, classDecl));
1956 llvm::GlobalVariable *classStruct =
1957 classFields.finishAndCreateGlobal(SymbolForClass(className),
1960 auto *classRefSymbol = GetClassVar(className);
1961 classRefSymbol->setSection(sectionName<ClassReferenceSection>());
1962 classRefSymbol->setInitializer(classStruct);
1967 classStruct->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1968 cast<llvm::GlobalValue>(classRefSymbol)->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1972 std::pair<llvm::GlobalVariable*, int>
v{classStruct, 1};
1973 EarlyInitList.emplace_back(std::string(SuperClass->getName()),
1982 if (ClassPtrAlias) {
1983 ClassPtrAlias->replaceAllUsesWith(classStruct);
1984 ClassPtrAlias->eraseFromParent();
1985 ClassPtrAlias =
nullptr;
1987 if (
auto Placeholder =
1988 TheModule.getNamedGlobal(SymbolForClass(className)))
1989 if (Placeholder != classStruct) {
1990 Placeholder->replaceAllUsesWith(classStruct);
1991 Placeholder->eraseFromParent();
1992 classStruct->setName(SymbolForClass(className));
1994 if (MetaClassPtrAlias) {
1995 MetaClassPtrAlias->replaceAllUsesWith(metaclass);
1996 MetaClassPtrAlias->eraseFromParent();
1997 MetaClassPtrAlias =
nullptr;
1999 assert(classStruct->getName() == SymbolForClass(className));
2001 auto classInitRef =
new llvm::GlobalVariable(TheModule,
2002 classStruct->getType(),
false, llvm::GlobalValue::ExternalLinkage,
2003 classStruct, ManglePublicSymbol(
"OBJC_INIT_CLASS_") + className);
2004 classInitRef->setSection(sectionName<ClassSection>());
2007 EmittedClass =
true;
2010 CGObjCGNUstep2(
CodeGenModule &Mod) : CGObjCGNUstep(Mod, 10, 4, 2) {
2011 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
2012 PtrToObjCSuperTy, SelectorTy);
2013 SentInitializeFn.init(&CGM,
"objc_send_initialize",
2014 llvm::Type::getVoidTy(VMContext), IdTy);
2023 PropertyMetadataTy =
2025 { PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty });
2028 void GenerateDirectMethodPrologue(
CodeGenFunction &CGF, llvm::Function *Fn,
2032 bool ReceiverCanBeNull =
true;
2034 auto selfValue = Builder.CreateLoad(selfAddr);
2059 ReceiverCanBeNull = isWeakLinkedClass(OID);
2063 if (ReceiverCanBeNull) {
2064 llvm::BasicBlock *SelfIsNilBlock =
2066 llvm::BasicBlock *ContBlock =
2070 auto selfTy = cast<llvm::PointerType>(selfValue->getType());
2071 auto Zero = llvm::ConstantPointerNull::get(selfTy);
2073 Builder.CreateCondBr(Builder.CreateICmpEQ(selfValue, Zero),
2074 SelfIsNilBlock, ContBlock,
2075 MDHelper.createBranchWeights(1, 1 << 20));
2081 Builder.SetInsertPoint(SelfIsNilBlock);
2082 if (!retTy->isVoidType()) {
2090 Builder.SetInsertPoint(ContBlock);
2096 llvm::StructType::get(PtrTy, PtrTy, PtrTy, LongTy, LongTy);
2098 auto flags = Builder.CreateLoad(
2099 Address{Builder.CreateStructGEP(classStart, selfValue, 4), LongTy,
2101 astContext.getTypeAlign(astContext.UnsignedLongTy))});
2102 auto isInitialized =
2103 Builder.CreateAnd(flags, ClassFlags::ClassFlagInitialized);
2104 llvm::BasicBlock *notInitializedBlock =
2106 llvm::BasicBlock *initializedBlock =
2108 Builder.CreateCondBr(Builder.CreateICmpEQ(isInitialized, Zeros[0]),
2109 notInitializedBlock, initializedBlock,
2110 MDHelper.createBranchWeights(1, 1 << 20));
2112 Builder.SetInsertPoint(notInitializedBlock);
2114 Builder.CreateBr(initializedBlock);
2116 Builder.SetInsertPoint(initializedBlock);
2124 Builder.CreateStore(GetSelector(CGF, OMD),
2130const char *
const CGObjCGNUstep2::SectionsBaseNames[8] =
2137"__objc_protocol_refs",
2138"__objc_class_aliases",
2139"__objc_constant_string"
2142const char *
const CGObjCGNUstep2::PECOFFSectionsBaseNames[8] =
2155class CGObjCObjFW:
public CGObjCGNU {
2159 LazyRuntimeFunction MsgLookupFn;
2162 LazyRuntimeFunction MsgLookupFnSRet;
2166 LazyRuntimeFunction MsgLookupSuperFn, MsgLookupSuperFnSRet;
2169 llvm::Value *cmd, llvm::MDNode *node,
2170 MessageSendInfo &MSI)
override {
2172 llvm::Value *args[] = {
2173 EnforceType(Builder, Receiver, IdTy),
2174 EnforceType(Builder, cmd, SelectorTy) };
2176 llvm::CallBase *imp;
2182 imp->setMetadata(msgSendMDKind, node);
2187 llvm::Value *cmd, MessageSendInfo &MSI)
override {
2189 llvm::Value *lookupArgs[] = {
2190 EnforceType(Builder, ObjCSuper.
emitRawPointer(CGF), PtrToObjCSuperTy),
2200 llvm::Value *GetClassNamed(
CodeGenFunction &CGF,
const std::string &Name,
2201 bool isWeak)
override {
2203 return CGObjCGNU::GetClassNamed(CGF, Name, isWeak);
2206 std::string SymbolName =
"_OBJC_CLASS_" + Name;
2207 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(SymbolName);
2209 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
2210 llvm::GlobalValue::ExternalLinkage,
2211 nullptr, SymbolName);
2218 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
2219 MsgLookupFnSRet.init(&CGM,
"objc_msg_lookup_stret", IMPTy, IdTy,
2222 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
2223 PtrToObjCSuperTy, SelectorTy);
2224 MsgLookupSuperFnSRet.init(&CGM,
"objc_msg_lookup_super_stret", IMPTy,
2225 PtrToObjCSuperTy, SelectorTy);
2233void CGObjCGNU::EmitClassRef(
const std::string &className) {
2234 std::string symbolRef =
"__objc_class_ref_" + className;
2236 if (TheModule.getGlobalVariable(symbolRef))
2238 std::string symbolName =
"__objc_class_name_" + className;
2239 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
2241 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
2242 llvm::GlobalValue::ExternalLinkage,
2243 nullptr, symbolName);
2245 new llvm::GlobalVariable(TheModule, ClassSymbol->getType(),
true,
2246 llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef);
2249CGObjCGNU::CGObjCGNU(
CodeGenModule &cgm,
unsigned runtimeABIVersion,
2250 unsigned protocolClassVersion,
unsigned classABI)
2252 VMContext(cgm.getLLVMContext()), ClassPtrAlias(nullptr),
2253 MetaClassPtrAlias(nullptr), RuntimeVersion(runtimeABIVersion),
2254 ProtocolVersion(protocolClassVersion), ClassABIVersion(classABI) {
2256 msgSendMDKind = VMContext.getMDKindID(
"GNUObjCMessageSend");
2264 IntTy = cast<llvm::IntegerType>(
2266 LongTy = cast<llvm::IntegerType>(
2268 SizeTy = cast<llvm::IntegerType>(
2270 PtrDiffTy = cast<llvm::IntegerType>(
2274 Int8Ty = llvm::Type::getInt8Ty(VMContext);
2276 PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
2277 ProtocolPtrTy = llvm::PointerType::getUnqual(
2280 Zeros[0] = llvm::ConstantInt::get(LongTy, 0);
2281 Zeros[1] = Zeros[0];
2282 NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty);
2286 SelectorTy = PtrToInt8Ty;
2287 SelectorElemTy = Int8Ty;
2293 PtrToIntTy = llvm::PointerType::getUnqual(IntTy);
2294 PtrTy = PtrToInt8Ty;
2296 Int32Ty = llvm::Type::getInt32Ty(VMContext);
2297 Int64Ty = llvm::Type::getInt64Ty(VMContext);
2300 CGM.
getDataLayout().getPointerSizeInBits() == 32 ? Int32Ty : Int64Ty;
2314 PtrToIdTy = llvm::PointerType::getUnqual(IdTy);
2315 ProtocolTy = llvm::StructType::get(IdTy,
2337 PropertyMetadataTy = llvm::StructType::get(CGM.
getLLVMContext(), {
2338 PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty,
2339 PtrToInt8Ty, PtrToInt8Ty });
2341 ObjCSuperTy = llvm::StructType::get(IdTy, IdTy);
2342 PtrToObjCSuperTy = llvm::PointerType::getUnqual(ObjCSuperTy);
2344 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
2347 ExceptionThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy);
2348 ExceptionReThrowFn.init(&CGM,
2349 usesCxxExceptions ?
"objc_exception_rethrow"
2350 :
"objc_exception_throw",
2353 SyncEnterFn.init(&CGM,
"objc_sync_enter", IntTy, IdTy);
2355 SyncExitFn.init(&CGM,
"objc_sync_exit", IntTy, IdTy);
2358 EnumerationMutationFn.init(&CGM,
"objc_enumerationMutation", VoidTy, IdTy);
2361 GetPropertyFn.init(&CGM,
"objc_getProperty", IdTy, IdTy, SelectorTy,
2364 SetPropertyFn.init(&CGM,
"objc_setProperty", VoidTy, IdTy, SelectorTy,
2365 PtrDiffTy, IdTy, BoolTy, BoolTy);
2367 GetStructPropertyFn.init(&CGM,
"objc_getPropertyStruct", VoidTy, PtrTy, PtrTy,
2368 PtrDiffTy, BoolTy, BoolTy);
2370 SetStructPropertyFn.init(&CGM,
"objc_setPropertyStruct", VoidTy, PtrTy, PtrTy,
2371 PtrDiffTy, BoolTy, BoolTy);
2374 llvm::Type *IMPArgs[] = { IdTy, SelectorTy };
2375 IMPTy = llvm::PointerType::getUnqual(llvm::FunctionType::get(IdTy, IMPArgs,
2379 if ((Opts.getGC() != LangOptions::NonGC) || Opts.ObjCAutoRefCount)
2380 RuntimeVersion = 10;
2383 if (Opts.getGC() != LangOptions::NonGC) {
2395 IvarAssignFn.init(&CGM,
"objc_assign_ivar", IdTy, IdTy, IdTy, PtrDiffTy);
2397 StrongCastAssignFn.init(&CGM,
"objc_assign_strongCast", IdTy, IdTy,
2400 GlobalAssignFn.init(&CGM,
"objc_assign_global", IdTy, IdTy, PtrToIdTy);
2402 WeakAssignFn.init(&CGM,
"objc_assign_weak", IdTy, IdTy, PtrToIdTy);
2404 WeakReadFn.init(&CGM,
"objc_read_weak", IdTy, PtrToIdTy);
2406 MemMoveFn.init(&CGM,
"objc_memmove_collectable", PtrTy, PtrTy, PtrTy,
2412 const std::string &Name,
bool isWeak) {
2413 llvm::Constant *ClassName = MakeConstantString(Name);
2425 llvm::FunctionType::get(IdTy, PtrToInt8Ty,
true),
"objc_lookup_class");
2435 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value))
2440llvm::Value *CGObjCGNU::EmitNSAutoreleasePoolClassRef(
CodeGenFunction &CGF) {
2441 auto *
Value = GetClassNamed(CGF,
"NSAutoreleasePool",
false);
2442 if (CGM.
getTriple().isOSBinFormatCOFF()) {
2443 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value)) {
2449 for (
const auto *Result : DC->
lookup(&II))
2450 if ((VD = dyn_cast<VarDecl>(Result)))
2460 const std::string &TypeEncoding) {
2462 llvm::GlobalAlias *SelValue =
nullptr;
2465 e = Types.end() ; i!=e ; i++) {
2466 if (i->first == TypeEncoding) {
2467 SelValue = i->second;
2472 SelValue = llvm::GlobalAlias::create(SelectorElemTy, 0,
2473 llvm::GlobalValue::PrivateLinkage,
2476 Types.emplace_back(TypeEncoding, SelValue);
2483 llvm::Value *SelValue = GetSelector(CGF, Sel);
2494 return GetTypedSelector(CGF, Sel, std::string());
2500 return GetTypedSelector(CGF, Method->
getSelector(), SelTypes);
2503llvm::Constant *CGObjCGNU::GetEHType(
QualType T) {
2510 return MakeConstantString(
"@id");
2518 assert(OPT &&
"Invalid @catch type.");
2520 assert(IDecl &&
"Invalid @catch type.");
2524llvm::Constant *CGObjCGNUstep::GetEHType(
QualType T) {
2525 if (usesSEHExceptions)
2528 if (!CGM.
getLangOpts().CPlusPlus && !usesCxxExceptions)
2529 return CGObjCGNU::GetEHType(
T);
2537 llvm::Constant *IDEHType =
2538 CGM.
getModule().getGlobalVariable(
"__objc_id_type_info");
2541 new llvm::GlobalVariable(CGM.
getModule(), PtrToInt8Ty,
2543 llvm::GlobalValue::ExternalLinkage,
2544 nullptr,
"__objc_id_type_info");
2550 assert(PT &&
"Invalid @catch type.");
2552 assert(IT &&
"Invalid @catch type.");
2553 std::string className =
2556 std::string typeinfoName =
"__objc_eh_typeinfo_" + className;
2559 if (llvm::Constant *typeinfo = TheModule.getGlobalVariable(typeinfoName))
2567 const char *vtableName =
"_ZTVN7gnustep7libobjc22__objc_class_type_infoE";
2568 auto *Vtable = TheModule.getGlobalVariable(vtableName);
2570 Vtable =
new llvm::GlobalVariable(TheModule, PtrToInt8Ty,
true,
2571 llvm::GlobalValue::ExternalLinkage,
2572 nullptr, vtableName);
2574 llvm::Constant *Two = llvm::ConstantInt::get(IntTy, 2);
2576 llvm::ConstantExpr::getGetElementPtr(Vtable->getValueType(), Vtable, Two);
2578 llvm::Constant *typeName =
2579 ExportUniqueString(className,
"__objc_eh_typename_");
2582 auto fields = builder.beginStruct();
2583 fields.add(BVtable);
2584 fields.add(typeName);
2585 llvm::Constant *TI =
2586 fields.finishAndCreateGlobal(
"__objc_eh_typeinfo_" + className,
2589 llvm::GlobalValue::LinkOnceODRLinkage);
2596 std::string Str = SL->
getString().str();
2600 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
2601 if (old != ObjCStrings.end())
2606 if (StringClass.empty()) StringClass =
"NSConstantString";
2608 std::string Sym =
"_OBJC_CLASS_";
2611 llvm::Constant *
isa = TheModule.getNamedGlobal(Sym);
2614 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
2615 llvm::GlobalValue::ExternalWeakLinkage,
2619 auto Fields = Builder.beginStruct();
2621 Fields.add(MakeConstantString(Str));
2622 Fields.addInt(IntTy, Str.size());
2624 ObjCStrings[Str] = ObjCStr;
2625 ConstantStrings.push_back(ObjCStr);
2638 bool isCategoryImpl,
2639 llvm::Value *Receiver,
2640 bool IsClassMessage,
2644 if (CGM.
getLangOpts().getGC() == LangOptions::GCOnly) {
2645 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2649 if (Sel == ReleaseSel) {
2654 llvm::Value *cmd = GetSelector(CGF, Sel);
2657 ActualArgs.
add(
RValue::get(EnforceType(Builder, Receiver, IdTy)), ASTIdTy);
2661 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2663 llvm::Value *ReceiverClass =
nullptr;
2666 ReceiverClass = GetClassNamed(CGF,
2667 Class->getSuperClass()->getNameAsString(),
false);
2668 if (IsClassMessage) {
2670 ReceiverClass = Builder.CreateBitCast(ReceiverClass,
2671 llvm::PointerType::getUnqual(IdTy));
2673 Builder.CreateAlignedLoad(IdTy, ReceiverClass, CGF.
getPointerAlign());
2675 ReceiverClass = EnforceType(Builder, ReceiverClass, IdTy);
2677 if (isCategoryImpl) {
2678 llvm::FunctionCallee classLookupFunction =
nullptr;
2679 if (IsClassMessage) {
2681 IdTy, PtrTy,
true),
"objc_get_meta_class");
2684 IdTy, PtrTy,
true),
"objc_get_class");
2686 ReceiverClass = Builder.CreateCall(classLookupFunction,
2687 MakeConstantString(
Class->getNameAsString()));
2694 if (IsClassMessage) {
2695 if (!MetaClassPtrAlias) {
2696 MetaClassPtrAlias = llvm::GlobalAlias::create(
2697 IdElemTy, 0, llvm::GlobalValue::InternalLinkage,
2698 ".objc_metaclass_ref" +
Class->getNameAsString(), &TheModule);
2700 ReceiverClass = MetaClassPtrAlias;
2702 if (!ClassPtrAlias) {
2703 ClassPtrAlias = llvm::GlobalAlias::create(
2704 IdElemTy, 0, llvm::GlobalValue::InternalLinkage,
2705 ".objc_class_ref" +
Class->getNameAsString(), &TheModule);
2707 ReceiverClass = ClassPtrAlias;
2711 llvm::Type *CastTy = llvm::StructType::get(IdTy, IdTy);
2712 ReceiverClass = Builder.CreateBitCast(ReceiverClass,
2713 llvm::PointerType::getUnqual(CastTy));
2715 ReceiverClass = Builder.CreateStructGEP(CastTy, ReceiverClass, 1);
2718 Builder.CreateAlignedLoad(IdTy, ReceiverClass, CGF.
getPointerAlign());
2721 llvm::StructType *ObjCSuperTy =
2722 llvm::StructType::get(Receiver->getType(), IdTy);
2727 Builder.CreateStore(Receiver, Builder.CreateStructGEP(ObjCSuper, 0));
2728 Builder.CreateStore(ReceiverClass, Builder.CreateStructGEP(ObjCSuper, 1));
2731 llvm::Value *imp = LookupIMPSuper(CGF, ObjCSuper, cmd, MSI);
2732 imp = EnforceType(Builder, imp, MSI.MessengerType);
2734 llvm::Metadata *impMD[] = {
2735 llvm::MDString::get(VMContext, Sel.
getAsString()),
2736 llvm::MDString::get(VMContext,
Class->getSuperClass()->getNameAsString()),
2737 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2738 llvm::Type::getInt1Ty(VMContext), IsClassMessage))};
2739 llvm::MDNode *
node = llvm::MDNode::get(VMContext, impMD);
2743 llvm::CallBase *call;
2744 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2745 call->setMetadata(msgSendMDKind, node);
2755 llvm::Value *Receiver,
2762 if (CGM.
getLangOpts().getGC() == LangOptions::GCOnly) {
2763 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2767 if (Sel == ReleaseSel) {
2778 cmd = GetSelector(CGF, Method);
2780 cmd = GetSelector(CGF, Sel);
2781 cmd = EnforceType(Builder, cmd, SelectorTy);
2784 Receiver = EnforceType(Builder, Receiver, IdTy);
2786 llvm::Metadata *impMD[] = {
2787 llvm::MDString::get(VMContext, Sel.
getAsString()),
2788 llvm::MDString::get(VMContext, Class ?
Class->getNameAsString() :
""),
2789 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2790 llvm::Type::getInt1Ty(VMContext), Class !=
nullptr))};
2791 llvm::MDNode *
node = llvm::MDNode::get(VMContext, impMD);
2799 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2820 bool hasParamDestroyedInCallee =
false;
2821 bool requiresExplicitZeroResult =
false;
2822 bool requiresNilReceiverCheck = [&] {
2824 if (!canMessageReceiverBeNull(CGF, Method,
false,
2830 hasParamDestroyedInCallee =
true;
2851 requiresExplicitZeroResult = !isDirect;
2855 return hasParamDestroyedInCallee || requiresExplicitZeroResult;
2861 bool requiresExplicitAggZeroing =
2865 llvm::BasicBlock *continueBB =
nullptr;
2867 llvm::BasicBlock *nilPathBB =
nullptr;
2869 llvm::BasicBlock *nilCleanupBB =
nullptr;
2872 if (requiresNilReceiverCheck) {
2879 if (requiresExplicitAggZeroing || hasParamDestroyedInCallee) {
2882 nilPathBB = Builder.GetInsertBlock();
2885 llvm::Value *isNil = Builder.CreateICmpEQ(Receiver,
2886 llvm::Constant::getNullValue(Receiver->getType()));
2887 Builder.CreateCondBr(isNil, nilCleanupBB ? nilCleanupBB : continueBB,
2904 imp = LookupIMP(CGF, Receiver, cmd, node, MSI);
2908 StringRef
name =
"objc_msgSend";
2910 name =
"objc_msgSend_fpret";
2912 name =
"objc_msgSend_stret";
2916 bool shouldCheckForInReg =
2920 .isWindowsMSVCEnvironment() &&
2923 name =
"objc_msgSend_stret2";
2936 imp = EnforceType(Builder, imp, MSI.MessengerType);
2938 llvm::CallBase *call;
2940 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2942 call->setMetadata(msgSendMDKind, node);
2944 if (requiresNilReceiverCheck) {
2945 llvm::BasicBlock *nonNilPathBB = CGF.
Builder.GetInsertBlock();
2946 CGF.
Builder.CreateBr(continueBB);
2952 if (hasParamDestroyedInCallee) {
2953 destroyCalleeDestroyedArguments(CGF, Method, CallArgs);
2956 if (requiresExplicitAggZeroing) {
2962 nilPathBB = CGF.
Builder.GetInsertBlock();
2963 CGF.
Builder.CreateBr(continueBB);
2971 llvm::PHINode *phi = Builder.CreatePHI(
v->getType(), 2);
2972 phi->addIncoming(
v, nonNilPathBB);
2980 llvm::PHINode *phi = Builder.CreatePHI(
v.first->getType(), 2);
2981 phi->addIncoming(
v.first, nonNilPathBB);
2982 phi->addIncoming(llvm::Constant::getNullValue(
v.first->getType()),
2984 llvm::PHINode *phi2 = Builder.CreatePHI(
v.second->getType(), 2);
2985 phi2->addIncoming(
v.second, nonNilPathBB);
2986 phi2->addIncoming(llvm::Constant::getNullValue(
v.second->getType()),
2996llvm::Constant *CGObjCGNU::
2997GenerateMethodList(StringRef ClassName,
2998 StringRef CategoryName,
3000 bool isClassMethodList) {
3001 if (Methods.empty())
3006 auto MethodList = Builder.beginStruct();
3007 MethodList.addNullPointer(CGM.
Int8PtrTy);
3008 MethodList.addInt(Int32Ty, Methods.size());
3011 llvm::StructType *ObjCMethodTy =
3020 llvm::DataLayout td(&TheModule);
3021 MethodList.addInt(SizeTy, td.getTypeSizeInBits(ObjCMethodTy) /
3037 auto MethodArray = MethodList.beginArray();
3039 for (
const auto *OMD : Methods) {
3040 llvm::Constant *FnPtr =
3041 TheModule.getFunction(getSymbolNameForMethod(OMD));
3042 assert(FnPtr &&
"Can't generate metadata for method that doesn't exist");
3043 auto Method = MethodArray.beginStruct(ObjCMethodTy);
3054 Method.finishAndAddTo(MethodArray);
3056 MethodArray.finishAndAddTo(MethodList);
3059 return MethodList.finishAndCreateGlobal(
".objc_method_list",
3064llvm::Constant *CGObjCGNU::
3070 if (IvarNames.empty())
3076 auto IvarList = Builder.beginStruct();
3077 IvarList.addInt(IntTy, (
int)IvarNames.size());
3080 llvm::StructType *ObjCIvarTy =
3081 llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, IntTy);
3084 auto Ivars = IvarList.beginArray(ObjCIvarTy);
3085 for (
unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {
3086 auto Ivar = Ivars.beginStruct(ObjCIvarTy);
3087 Ivar.
add(IvarNames[i]);
3088 Ivar.
add(IvarTypes[i]);
3089 Ivar.
add(IvarOffsets[i]);
3090 Ivar.finishAndAddTo(Ivars);
3092 Ivars.finishAndAddTo(IvarList);
3095 return IvarList.finishAndCreateGlobal(
".objc_ivar_list",
3100llvm::Constant *CGObjCGNU::GenerateClassStructure(
3101 llvm::Constant *MetaClass,
3102 llvm::Constant *SuperClass,
3105 llvm::Constant *Version,
3106 llvm::Constant *InstanceSize,
3107 llvm::Constant *IVars,
3108 llvm::Constant *Methods,
3109 llvm::Constant *Protocols,
3110 llvm::Constant *IvarOffsets,
3111 llvm::Constant *Properties,
3112 llvm::Constant *StrongIvarBitmap,
3113 llvm::Constant *WeakIvarBitmap,
3122 llvm::StructType *ClassTy = llvm::StructType::get(
3139 IvarOffsets->getType(),
3140 Properties->getType(),
3146 auto Elements = Builder.beginStruct(ClassTy);
3151 Elements.add(MetaClass);
3153 Elements.add(SuperClass);
3155 Elements.add(MakeConstantString(Name,
".class_name"));
3157 Elements.addInt(LongTy, 0);
3159 Elements.addInt(LongTy, info);
3162 llvm::DataLayout td(&TheModule);
3163 Elements.addInt(LongTy,
3164 td.getTypeSizeInBits(ClassTy) /
3167 Elements.add(InstanceSize);
3169 Elements.add(IVars);
3171 Elements.add(Methods);
3174 Elements.add(NULLPtr);
3176 Elements.add(NULLPtr);
3178 Elements.add(NULLPtr);
3180 Elements.add(Protocols);
3182 Elements.add(NULLPtr);
3184 Elements.addInt(LongTy, ClassABIVersion);
3186 Elements.add(IvarOffsets);
3188 Elements.add(Properties);
3190 Elements.add(StrongIvarBitmap);
3192 Elements.add(WeakIvarBitmap);
3197 std::string ClassSym((isMeta ?
"_OBJC_METACLASS_":
"_OBJC_CLASS_") +
3199 llvm::GlobalVariable *ClassRef = TheModule.getNamedGlobal(ClassSym);
3200 llvm::Constant *
Class =
3201 Elements.finishAndCreateGlobal(ClassSym, CGM.
getPointerAlign(),
false,
3202 llvm::GlobalValue::ExternalLinkage);
3204 ClassRef->replaceAllUsesWith(Class);
3205 ClassRef->removeFromParent();
3206 Class->setName(ClassSym);
3211llvm::Constant *CGObjCGNU::
3214 llvm::StructType *ObjCMethodDescTy =
3215 llvm::StructType::get(CGM.
getLLVMContext(), { PtrToInt8Ty, PtrToInt8Ty });
3218 auto MethodList = Builder.beginStruct();
3219 MethodList.addInt(IntTy, Methods.size());
3220 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
3221 for (
auto *M : Methods) {
3222 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
3223 Method.
add(MakeConstantString(M->getSelector().getAsString()));
3225 Method.finishAndAddTo(MethodArray);
3227 MethodArray.finishAndAddTo(MethodList);
3228 return MethodList.finishAndCreateGlobal(
".objc_method_list",
3237 auto ProtocolList = Builder.beginStruct();
3238 ProtocolList.add(NULLPtr);
3239 ProtocolList.addInt(LongTy, Protocols.size());
3241 auto Elements = ProtocolList.beginArray(PtrToInt8Ty);
3242 for (
const std::string *iter = Protocols.begin(), *endIter = Protocols.end();
3243 iter != endIter ; iter++) {
3244 llvm::Constant *protocol =
nullptr;
3245 llvm::StringMap<llvm::Constant*>::iterator value =
3246 ExistingProtocols.find(*iter);
3247 if (value == ExistingProtocols.end()) {
3248 protocol = GenerateEmptyProtocol(*iter);
3250 protocol = value->getValue();
3252 Elements.add(protocol);
3254 Elements.finishAndAddTo(ProtocolList);
3255 return ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
3261 auto protocol = GenerateProtocolRef(PD);
3264 return CGF.
Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(
T));
3267llvm::Constant *CGObjCGNU::GenerateProtocolRef(
const ObjCProtocolDecl *PD) {
3270 GenerateProtocol(PD);
3271 assert(protocol &&
"Unknown protocol");
3276CGObjCGNU::GenerateEmptyProtocol(StringRef ProtocolName) {
3277 llvm::Constant *ProtocolList = GenerateProtocolList({});
3278 llvm::Constant *MethodList = GenerateProtocolMethodList({});
3282 auto Elements = Builder.beginStruct();
3286 Elements.add(llvm::ConstantExpr::getIntToPtr(
3287 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3289 Elements.add(MakeConstantString(ProtocolName,
".objc_protocol_name"));
3290 Elements.add(ProtocolList);
3291 Elements.add(MethodList);
3292 Elements.add(MethodList);
3293 Elements.add(MethodList);
3294 Elements.add(MethodList);
3295 Elements.add(NULLPtr);
3296 Elements.add(NULLPtr);
3297 return Elements.finishAndCreateGlobal(SymbolForProtocol(ProtocolName),
3313 Protocols.push_back(PI->getNameAsString());
3317 if (I->isOptional())
3318 OptionalInstanceMethods.push_back(I);
3320 InstanceMethods.push_back(I);
3325 if (I->isOptional())
3326 OptionalClassMethods.push_back(I);
3328 ClassMethods.push_back(I);
3330 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
3331 llvm::Constant *InstanceMethodList =
3332 GenerateProtocolMethodList(InstanceMethods);
3333 llvm::Constant *ClassMethodList =
3334 GenerateProtocolMethodList(ClassMethods);
3335 llvm::Constant *OptionalInstanceMethodList =
3336 GenerateProtocolMethodList(OptionalInstanceMethods);
3337 llvm::Constant *OptionalClassMethodList =
3338 GenerateProtocolMethodList(OptionalClassMethods);
3346 llvm::Constant *PropertyList =
3347 GeneratePropertyList(
nullptr, PD,
false,
false);
3348 llvm::Constant *OptionalPropertyList =
3349 GeneratePropertyList(
nullptr, PD,
false,
true);
3356 auto Elements = Builder.beginStruct();
3358 llvm::ConstantExpr::getIntToPtr(
3359 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3360 Elements.add(MakeConstantString(ProtocolName));
3361 Elements.add(ProtocolList);
3362 Elements.add(InstanceMethodList);
3363 Elements.add(ClassMethodList);
3364 Elements.add(OptionalInstanceMethodList);
3365 Elements.add(OptionalClassMethodList);
3366 Elements.add(PropertyList);
3367 Elements.add(OptionalPropertyList);
3368 ExistingProtocols[ProtocolName] =
3369 Elements.finishAndCreateGlobal(
".objc_protocol", CGM.
getPointerAlign());
3371void CGObjCGNU::GenerateProtocolHolderCategory() {
3375 auto Elements = Builder.beginStruct();
3377 const std::string ClassName =
"__ObjC_Protocol_Holder_Ugly_Hack";
3378 const std::string CategoryName =
"AnotherHack";
3379 Elements.add(MakeConstantString(CategoryName));
3380 Elements.add(MakeConstantString(ClassName));
3382 Elements.add(GenerateMethodList(ClassName, CategoryName, {},
false));
3384 Elements.add(GenerateMethodList(ClassName, CategoryName, {},
true));
3388 auto ProtocolList = ProtocolListBuilder.beginStruct();
3389 ProtocolList.add(NULLPtr);
3390 ProtocolList.addInt(LongTy, ExistingProtocols.size());
3391 auto ProtocolElements = ProtocolList.beginArray(PtrTy);
3392 for (
auto iter = ExistingProtocols.begin(), endIter = ExistingProtocols.end();
3393 iter != endIter ; iter++) {
3394 ProtocolElements.add(iter->getValue());
3396 ProtocolElements.finishAndAddTo(ProtocolList);
3397 Elements.add(ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
3399 Categories.push_back(
3415 int bitCount = bits.size();
3417 if (bitCount < ptrBits) {
3419 for (
int i=0 ; i<bitCount ; ++i) {
3420 if (bits[i]) val |= 1ULL<<(i+1);
3422 return llvm::ConstantInt::get(IntPtrTy, val);
3426 while (
v < bitCount) {
3428 for (
int i=0 ; (i<32) && (
v<bitCount) ; ++i) {
3429 if (bits[
v]) word |= 1<<i;
3432 values.push_back(llvm::ConstantInt::get(Int32Ty, word));
3436 auto fields = builder.beginStruct();
3437 fields.addInt(Int32Ty, values.size());
3438 auto array = fields.beginArray();
3439 for (
auto *
v : values) array.add(
v);
3440 array.finishAndAddTo(fields);
3442 llvm::Constant *GS =
3444 llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy);
3448llvm::Constant *CGObjCGNU::GenerateCategoryProtocolList(
const
3451 const auto RuntimeProtos =
3452 GetRuntimeProtocolList(RefPro.begin(), RefPro.end());
3454 for (
const auto *PD : RuntimeProtos)
3456 return GenerateProtocolList(Protocols);
3461 std::string ClassName =
Class->getNameAsString();
3468 auto Elements = Builder.beginStruct();
3469 Elements.add(MakeConstantString(CategoryName));
3470 Elements.add(MakeConstantString(ClassName));
3473 InstanceMethods.insert(InstanceMethods.begin(), OCD->
instmeth_begin(),
3476 GenerateMethodList(ClassName, CategoryName, InstanceMethods,
false));
3483 Elements.add(GenerateMethodList(ClassName, CategoryName, ClassMethods,
true));
3486 Elements.add(GenerateCategoryProtocolList(CatDecl));
3492 Elements.add(GeneratePropertyList(OCD,
Category,
false));
3494 Elements.add(GeneratePropertyList(OCD,
Category,
true));
3496 Elements.addNullPointer(PtrTy);
3497 Elements.addNullPointer(PtrTy);
3501 Categories.push_back(Elements.finishAndCreateGlobal(
3502 std::string(
".objc_category_") + ClassName + CategoryName,
3506llvm::Constant *CGObjCGNU::GeneratePropertyList(
const Decl *Container,
3508 bool isClassProperty,
3509 bool protocolOptionalProperties) {
3513 bool isProtocol = isa<ObjCProtocolDecl>(OCD);
3516 std::function<void(
const ObjCProtocolDecl *Proto)> collectProtocolProperties
3518 for (
const auto *
P : Proto->protocols())
3519 collectProtocolProperties(
P);
3520 for (
const auto *PD : Proto->properties()) {
3521 if (isClassProperty != PD->isClassProperty())
3529 Properties.push_back(PD);
3535 for (
auto *PD : ClassExt->properties()) {
3536 if (isClassProperty != PD->isClassProperty())
3539 Properties.push_back(PD);
3543 if (isClassProperty != PD->isClassProperty())
3547 if (isProtocol && (protocolOptionalProperties != PD->isOptional()))
3554 Properties.push_back(PD);
3559 collectProtocolProperties(
P);
3561 for (
const auto *
P : CD->protocols())
3562 collectProtocolProperties(
P);
3564 auto numProperties = Properties.size();
3566 if (numProperties == 0)
3570 auto propertyList = builder.beginStruct();
3571 auto properties = PushPropertyListHeader(propertyList, numProperties);
3575 for (
auto *property : Properties) {
3576 bool isSynthesized =
false;
3577 bool isDynamic =
false;
3581 isSynthesized = (propertyImpl->getPropertyImplementation() ==
3583 isDynamic = (propertyImpl->getPropertyImplementation() ==
3587 PushProperty(properties, property, Container, isSynthesized, isDynamic);
3589 properties.finishAndAddTo(propertyList);
3591 return propertyList.finishAndCreateGlobal(
".objc_property_list",
3609 std::string SuperClassName;
3610 if (SuperClassDecl) {
3612 EmitClassRef(SuperClassName);
3622 std::string classSymbolName =
"__objc_class_name_" + ClassName;
3623 if (
auto *symbol = TheModule.getGlobalVariable(classSymbolName)) {
3624 symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0));
3626 new llvm::GlobalVariable(TheModule, LongTy,
false,
3627 llvm::GlobalValue::ExternalLinkage,
3628 llvm::ConstantInt::get(LongTy, 0),
3644 auto IvarOffsetValues = IvarOffsetBuilder.beginArray(PtrToIntTy);
3648 int superInstanceSize = !SuperClassDecl ? 0 :
3653 instanceSize = 0 - (instanceSize - superInstanceSize);
3659 IvarNames.push_back(MakeConstantString(IVD->getNameAsString()));
3661 std::string TypeStr;
3663 IvarTypes.push_back(MakeConstantString(TypeStr));
3664 IvarAligns.push_back(llvm::ConstantInt::get(IntTy,
3667 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
3670 Offset = BaseOffset - superInstanceSize;
3672 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
3674 std::string OffsetName =
"__objc_ivar_offset_value_" + ClassName +
"." +
3675 IVD->getNameAsString();
3677 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
3679 OffsetVar->setInitializer(OffsetValue);
3683 OffsetVar->setLinkage(llvm::GlobalValue::ExternalLinkage);
3685 OffsetVar =
new llvm::GlobalVariable(TheModule, Int32Ty,
3686 false, llvm::GlobalValue::ExternalLinkage,
3687 OffsetValue, OffsetName);
3688 IvarOffsets.push_back(OffsetValue);
3689 IvarOffsetValues.add(OffsetVar);
3691 IvarOwnership.push_back(lt);
3694 StrongIvars.push_back(
true);
3695 WeakIvars.push_back(
false);
3698 StrongIvars.push_back(
false);
3699 WeakIvars.push_back(
true);
3702 StrongIvars.push_back(
false);
3703 WeakIvars.push_back(
false);
3706 llvm::Constant *StrongIvarBitmap = MakeBitField(StrongIvars);
3707 llvm::Constant *WeakIvarBitmap = MakeBitField(WeakIvars);
3708 llvm::GlobalVariable *IvarOffsetArray =
3709 IvarOffsetValues.finishAndCreateGlobal(
".ivar.offsets",
3714 InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
3721 llvm::Constant *Properties = GeneratePropertyList(OID, ClassDecl);
3724 auto RefProtocols = ClassDecl->
protocols();
3725 auto RuntimeProtocols =
3726 GetRuntimeProtocolList(RefProtocols.begin(), RefProtocols.end());
3728 for (
const auto *I : RuntimeProtocols)
3729 Protocols.push_back(I->getNameAsString());
3732 llvm::Constant *SuperClass;
3733 if (!SuperClassName.empty()) {
3734 SuperClass = MakeConstantString(SuperClassName,
".super_class_name");
3736 SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty);
3741 llvm::Constant *MethodList = GenerateMethodList(ClassName,
"",
3742 InstanceMethods,
false);
3743 llvm::Constant *ClassMethodList = GenerateMethodList(ClassName,
"",
3744 ClassMethods,
true);
3745 llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
3746 IvarOffsets, IvarAligns, IvarOwnership);
3757 llvm::Type *IndexTy = Int32Ty;
3758 llvm::Constant *offsetPointerIndexes[] = {Zeros[0],
3759 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 2 : 1),
nullptr,
3760 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 3 : 2) };
3762 unsigned ivarIndex = 0;
3765 const std::string Name = GetIVarOffsetVariableName(ClassDecl, IVD);
3766 offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, ivarIndex);
3768 llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr(
3769 cast<llvm::GlobalVariable>(IvarList)->getValueType(), IvarList,
3770 offsetPointerIndexes);
3772 llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name);
3774 offset->setInitializer(offsetValue);
3778 offset->setLinkage(llvm::GlobalValue::ExternalLinkage);
3781 new llvm::GlobalVariable(TheModule, offsetValue->getType(),
3782 false, llvm::GlobalValue::ExternalLinkage, offsetValue, Name);
3785 llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0);
3788 llvm::Constant *MetaClassStruct = GenerateClassStructure(
3789 NULLPtr, NULLPtr, 0x12L, ClassName.c_str(),
nullptr, Zeros[0],
3790 NULLPtr, ClassMethodList, NULLPtr, NULLPtr,
3791 GeneratePropertyList(OID, ClassDecl,
true), ZeroPtr, ZeroPtr,
true);
3796 llvm::Constant *ClassStruct = GenerateClassStructure(
3797 MetaClassStruct, SuperClass, 0x11L, ClassName.c_str(),
nullptr,
3798 llvm::ConstantInt::get(LongTy, instanceSize), IvarList, MethodList,
3799 GenerateProtocolList(Protocols), IvarOffsetArray, Properties,
3800 StrongIvarBitmap, WeakIvarBitmap);
3805 if (ClassPtrAlias) {
3806 ClassPtrAlias->replaceAllUsesWith(ClassStruct);
3807 ClassPtrAlias->eraseFromParent();
3808 ClassPtrAlias =
nullptr;
3810 if (MetaClassPtrAlias) {
3811 MetaClassPtrAlias->replaceAllUsesWith(MetaClassStruct);
3812 MetaClassPtrAlias->eraseFromParent();
3813 MetaClassPtrAlias =
nullptr;
3817 Classes.push_back(ClassStruct);
3820llvm::Function *CGObjCGNU::ModuleInitFunction() {
3822 if (Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
3827 GenerateProtocolHolderCategory();
3829 llvm::StructType *selStructTy = dyn_cast<llvm::StructType>(SelectorElemTy);
3832 { PtrToInt8Ty, PtrToInt8Ty });
3836 llvm::Constant *statics = NULLPtr;
3837 if (!ConstantStrings.empty()) {
3838 llvm::GlobalVariable *fileStatics = [&] {
3840 auto staticsStruct = builder.beginStruct();
3843 if (stringClass.empty()) stringClass =
"NXConstantString";
3844 staticsStruct.add(MakeConstantString(stringClass,
3845 ".objc_static_class_name"));
3847 auto array = staticsStruct.beginArray();
3848 array.addAll(ConstantStrings);
3850 array.finishAndAddTo(staticsStruct);
3852 return staticsStruct.finishAndCreateGlobal(
".objc_statics",
3857 auto allStaticsArray = builder.beginArray(fileStatics->getType());
3858 allStaticsArray.add(fileStatics);
3859 allStaticsArray.addNullPointer(fileStatics->getType());
3861 statics = allStaticsArray.finishAndCreateGlobal(
".objc_statics_ptr",
3868 unsigned selectorCount;
3871 llvm::GlobalVariable *selectorList = [&] {
3873 auto selectors = builder.beginArray(selStructTy);
3875 std::vector<Selector> allSelectors;
3876 for (
auto &entry : table)
3877 allSelectors.push_back(entry.first);
3878 llvm::sort(allSelectors);
3880 for (
auto &untypedSel : allSelectors) {
3881 std::string selNameStr = untypedSel.getAsString();
3882 llvm::Constant *selName = ExportUniqueString(selNameStr,
".objc_sel_name");
3884 for (TypedSelector &sel : table[untypedSel]) {
3885 llvm::Constant *selectorTypeEncoding = NULLPtr;
3886 if (!sel.first.empty())
3887 selectorTypeEncoding =
3888 MakeConstantString(sel.first,
".objc_sel_types");
3890 auto selStruct = selectors.beginStruct(selStructTy);
3891 selStruct.add(selName);
3892 selStruct.add(selectorTypeEncoding);
3893 selStruct.finishAndAddTo(selectors);
3896 selectorAliases.push_back(sel.second);
3901 selectorCount = selectors.size();
3907 auto selStruct = selectors.beginStruct(selStructTy);
3908 selStruct.add(NULLPtr);
3909 selStruct.add(NULLPtr);
3910 selStruct.finishAndAddTo(selectors);
3912 return selectors.finishAndCreateGlobal(
".objc_selector_list",
3917 for (
unsigned i = 0; i < selectorCount; ++i) {
3918 llvm::Constant *idxs[] = {
3920 llvm::ConstantInt::get(Int32Ty, i)
3923 llvm::Constant *selPtr = llvm::ConstantExpr::getGetElementPtr(
3924 selectorList->getValueType(), selectorList, idxs);
3925 selectorAliases[i]->replaceAllUsesWith(selPtr);
3926 selectorAliases[i]->eraseFromParent();
3929 llvm::GlobalVariable *symtab = [&] {
3931 auto symtab = builder.beginStruct();
3934 symtab.addInt(LongTy, selectorCount);
3936 symtab.add(selectorList);
3939 symtab.addInt(CGM.
Int16Ty, Classes.size());
3941 symtab.addInt(CGM.
Int16Ty, Categories.size());
3944 auto classList = symtab.beginArray(PtrToInt8Ty);
3945 classList.addAll(Classes);
3946 classList.addAll(Categories);
3948 classList.add(statics);
3949 classList.add(NULLPtr);
3950 classList.finishAndAddTo(symtab);
3958 llvm::Constant *module = [&] {
3959 llvm::Type *moduleEltTys[] = {
3960 LongTy, LongTy, PtrToInt8Ty, symtab->getType(), IntTy
3962 llvm::StructType *moduleTy = llvm::StructType::get(
3964 ArrayRef(moduleEltTys).drop_back(
unsigned(RuntimeVersion < 10)));
3967 auto module = builder.beginStruct(moduleTy);
3969 module.addInt(LongTy, RuntimeVersion);
3971 module.addInt(LongTy, CGM.
getDataLayout().getTypeStoreSize(moduleTy));
3978 module.add(MakeConstantString(path,
".objc_source_file_name"));
3981 if (RuntimeVersion >= 10) {
3983 case LangOptions::GCOnly:
3984 module.addInt(IntTy, 2);
3986 case LangOptions::NonGC:
3988 module.addInt(IntTy, 1);
3990 module.addInt(IntTy, 0);
3992 case LangOptions::HybridGC:
3993 module.addInt(IntTy, 1);
4003 llvm::Function * LoadFunction = llvm::Function::Create(
4004 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
4005 llvm::GlobalValue::InternalLinkage,
".objc_load_function",
4007 llvm::BasicBlock *EntryBB =
4008 llvm::BasicBlock::Create(VMContext,
"entry", LoadFunction);
4010 Builder.SetInsertPoint(EntryBB);
4012 llvm::FunctionType *FT =
4013 llvm::FunctionType::get(Builder.getVoidTy(), module->getType(),
true);
4014 llvm::FunctionCallee Register =
4016 Builder.CreateCall(Register, module);
4018 if (!ClassAliases.empty()) {
4019 llvm::Type *ArgTypes[2] = {PtrTy, PtrToInt8Ty};
4020 llvm::FunctionType *RegisterAliasTy =
4021 llvm::FunctionType::get(Builder.getVoidTy(),
4023 llvm::Function *RegisterAlias = llvm::Function::Create(
4025 llvm::GlobalValue::ExternalWeakLinkage,
"class_registerAlias_np",
4027 llvm::BasicBlock *AliasBB =
4028 llvm::BasicBlock::Create(VMContext,
"alias", LoadFunction);
4029 llvm::BasicBlock *NoAliasBB =
4030 llvm::BasicBlock::Create(VMContext,
"no_alias", LoadFunction);
4033 llvm::Value *HasRegisterAlias = Builder.CreateICmpNE(RegisterAlias,
4034 llvm::Constant::getNullValue(RegisterAlias->getType()));
4035 Builder.CreateCondBr(HasRegisterAlias, AliasBB, NoAliasBB);
4038 Builder.SetInsertPoint(AliasBB);
4040 for (std::vector<ClassAliasPair>::iterator iter = ClassAliases.begin();
4041 iter != ClassAliases.end(); ++iter) {
4042 llvm::Constant *TheClass =
4043 TheModule.getGlobalVariable(
"_OBJC_CLASS_" + iter->first,
true);
4045 Builder.CreateCall(RegisterAlias,
4046 {TheClass, MakeConstantString(iter->second)});
4050 Builder.CreateBr(NoAliasBB);
4053 Builder.SetInsertPoint(NoAliasBB);
4055 Builder.CreateRetVoid();
4057 return LoadFunction;
4060llvm::Function *CGObjCGNU::GenerateMethod(
const ObjCMethodDecl *OMD,
4063 llvm::FunctionType *MethodTy =
4064 Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
4067 std::string FunctionName =
4068 getSymbolNameForMethod(OMD, !isDirect);
4071 return llvm::Function::Create(MethodTy,
4072 llvm::GlobalVariable::InternalLinkage,
4073 FunctionName, &TheModule);
4076 auto I = DirectMethodDefinitions.find(COMD);
4077 llvm::Function *OldFn =
nullptr, *Fn =
nullptr;
4079 if (I == DirectMethodDefinitions.end()) {
4081 llvm::Function::Create(MethodTy, llvm::GlobalVariable::ExternalLinkage,
4082 FunctionName, &TheModule);
4083 DirectMethodDefinitions.insert(std::make_pair(COMD, F));
4100 Fn = llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,
"",
4102 Fn->takeName(OldFn);
4103 OldFn->replaceAllUsesWith(Fn);
4104 OldFn->eraseFromParent();
4118llvm::FunctionCallee CGObjCGNU::GetPropertyGetFunction() {
4119 return GetPropertyFn;
4122llvm::FunctionCallee CGObjCGNU::GetPropertySetFunction() {
4123 return SetPropertyFn;
4126llvm::FunctionCallee CGObjCGNU::GetOptimizedPropertySetFunction(
bool atomic,
4131llvm::FunctionCallee CGObjCGNU::GetGetStructFunction() {
4132 return GetStructPropertyFn;
4135llvm::FunctionCallee CGObjCGNU::GetSetStructFunction() {
4136 return SetStructPropertyFn;
4139llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectGetFunction() {
4143llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectSetFunction() {
4147llvm::FunctionCallee CGObjCGNU::EnumerationMutationFunction() {
4148 return EnumerationMutationFn;
4153 EmitAtSynchronizedStmt(CGF, S, SyncEnterFn, SyncExitFn);
4170 EmitTryCatchStmt(CGF, S, EnterCatchFn, ExitCatchFn, ExceptionReThrowFn);
4175 bool ClearInsertionPoint) {
4176 llvm::Value *ExceptionAsObject;
4177 bool isRethrow =
false;
4179 if (
const Expr *ThrowExpr = S.getThrowExpr()) {
4181 ExceptionAsObject = Exception;
4184 "Unexpected rethrow outside @catch block.");
4188 if (isRethrow && (usesSEHExceptions || usesCxxExceptions)) {
4197 Throw->setDoesNotReturn();
4199 ExceptionAsObject = CGF.
Builder.CreateBitCast(ExceptionAsObject, IdTy);
4200 llvm::CallBase *Throw =
4202 Throw->setDoesNotReturn();
4204 CGF.
Builder.CreateUnreachable();
4205 if (ClearInsertionPoint)
4206 CGF.
Builder.ClearInsertionPoint();
4212 return B.CreateCall(
4213 WeakReadFn, EnforceType(B, AddrWeakObj.
emitRawPointer(CGF), PtrToIdTy));
4217 llvm::Value *src,
Address dst) {
4219 src = EnforceType(B, src, IdTy);
4220 llvm::Value *dstVal = EnforceType(B, dst.
emitRawPointer(CGF), PtrToIdTy);
4221 B.CreateCall(WeakAssignFn, {src, dstVal});
4225 llvm::Value *src,
Address dst,
4228 src = EnforceType(B, src, IdTy);
4229 llvm::Value *dstVal = EnforceType(B, dst.
emitRawPointer(CGF), PtrToIdTy);
4231 assert(!threadlocal &&
"EmitObjCGlobalAssign - Threal Local API NYI");
4232 B.CreateCall(GlobalAssignFn, {src, dstVal});
4236 llvm::Value *src,
Address dst,
4237 llvm::Value *ivarOffset) {
4239 src = EnforceType(B, src, IdTy);
4240 llvm::Value *dstVal = EnforceType(B, dst.
emitRawPointer(CGF), IdTy);
4241 B.CreateCall(IvarAssignFn, {src, dstVal, ivarOffset});
4245 llvm::Value *src,
Address dst) {
4247 src = EnforceType(B, src, IdTy);
4248 llvm::Value *dstVal = EnforceType(B, dst.
emitRawPointer(CGF), PtrToIdTy);
4249 B.CreateCall(StrongCastAssignFn, {src, dstVal});
4255 llvm::Value *Size) {
4257 llvm::Value *DestPtrVal = EnforceType(B, DestPtr.
emitRawPointer(CGF), PtrTy);
4258 llvm::Value *SrcPtrVal = EnforceType(B, SrcPtr.
emitRawPointer(CGF), PtrTy);
4260 B.CreateCall(MemMoveFn, {DestPtrVal, SrcPtrVal,
Size});
4263llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
4266 const std::string Name = GetIVarOffsetVariableName(ID, Ivar);
4270 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
4271 if (!IvarOffsetPointer)
4272 IvarOffsetPointer =
new llvm::GlobalVariable(
4273 TheModule, llvm::PointerType::getUnqual(VMContext),
false,
4274 llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
4275 return IvarOffsetPointer;
4280 llvm::Value *BaseValue,
4282 unsigned CVRQualifiers) {
4285 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
4286 EmitIvarOffset(CGF, ID, Ivar));
4314 if (RuntimeVersion < 10 ||
4316 return CGF.
Builder.CreateZExtOrBitCast(
4320 llvm::PointerType::getUnqual(VMContext),
4321 ObjCIvarOffsetVariable(
Interface, Ivar),
4325 std::string
name =
"__objc_ivar_offset_value_" +
4328 llvm::Value *Offset = TheModule.getGlobalVariable(name);
4330 auto GV =
new llvm::GlobalVariable(TheModule, IntTy,
4331 false, llvm::GlobalValue::LinkOnceAnyLinkage,
4332 llvm::Constant::getNullValue(IntTy), name);
4337 if (Offset->getType() != PtrDiffTy)
4338 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
4342 return llvm::ConstantInt::get(PtrDiffTy, Offset,
true);
4348 switch (Runtime.getKind()) {
4350 if (Runtime.getVersion() >= VersionTuple(2, 0))
4351 return new CGObjCGNUstep2(CGM);
4352 return new CGObjCGNUstep(CGM);
4355 return new CGObjCGCC(CGM);
4358 return new CGObjCObjFW(CGM);
4364 llvm_unreachable(
"these runtimes are not GNU runtimes");
4366 llvm_unreachable(
"bad runtime");
Defines the clang::ASTContext interface.
static const ObjCInterfaceDecl * FindIvarInterface(ASTContext &Context, const ObjCInterfaceDecl *OID, const ObjCIvarDecl *OIVD)
static bool isNamed(const NamedDecl *ND, const char(&Str)[Len])
Defines the clang::FileManager interface and associated types.
Defines the SourceManager interface.
Defines the Objective-C statement AST node classes.
__device__ __2f16 float __ockl_bool s
__device__ __2f16 float c
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
TranslationUnitDecl * getTranslationUnitDecl() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
void getObjCEncodingForType(QualType T, std::string &S, const FieldDecl *Field=nullptr, QualType *NotEncodedT=nullptr) const
Emit the Objective-CC type encoding for the given type T into S.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
std::string getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, bool Extended=false) const
Emit the encoded type for the method declaration Decl into S.
std::string getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD, const Decl *Container) const
getObjCEncodingForPropertyDecl - Return the encoded type for this method declaration.
const ASTRecordLayout & getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const
Get or compute information about the layout of the specified Objective-C implementation.
const ASTRecordLayout & getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const
Get or compute information about the layout of the specified Objective-C interface.
QualType getObjCProtoType() const
Retrieve the type of the Objective-C Protocol class.
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
ObjCPropertyImplDecl * getObjCPropertyImplDeclForPropertyDecl(const ObjCPropertyDecl *PD, const Decl *Container) const
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
QualType getObjCIdType() const
Represents the Objective-CC id type.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
void getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT, QualType T, std::string &S, bool Extended) const
getObjCEncodingForMethodParameter - Return the encoded type for a single method parameter or return t...
const TargetInfo & getTargetInfo() const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
CharUnits getSize() const
getSize - Get the record size in characters.
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
CharUnits - This is an opaque type for sizes expressed in character units.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
CGBlockInfo - Information to generate a block literal.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
virtual llvm::Constant * getAddrOfRTTIDescriptor(QualType Ty)=0
virtual CatchTypeInfo getCatchAllTypeInfo()
Abstract information about a function or function prototype.
All available information about a concrete callee.
Implements runtime-specific code generation functions.
virtual llvm::Constant * GetEHType(QualType T)=0
Get the type constant to catch for the given ObjC pointer type.
virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest, llvm::Value *ivarOffset)=0
virtual llvm::FunctionCallee GetCppAtomicObjectGetFunction()=0
API for atomic copying of qualified aggregates with non-trivial copy assignment (c++) in getter.
virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest)=0
virtual llvm::Constant * BuildByrefLayout(CodeGen::CodeGenModule &CGM, QualType T)=0
Returns an i8* which points to the byref layout information.
virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, Address DestPtr, Address SrcPtr, llvm::Value *Size)=0
virtual llvm::FunctionCallee GetPropertySetFunction()=0
Return the runtime function for setting properties.
virtual llvm::FunctionCallee GetCppAtomicObjectSetFunction()=0
API for atomic copying of qualified aggregates with non-trivial copy assignment (c++) in setter.
virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtTryStmt &S)=0
virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, ReturnValueSlot ReturnSlot, QualType ResultType, Selector Sel, llvm::Value *Receiver, const CallArgList &CallArgs, const ObjCInterfaceDecl *Class=nullptr, const ObjCMethodDecl *Method=nullptr)=0
Generate an Objective-C message send operation.
virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy, llvm::Value *BaseValue, const ObjCIvarDecl *Ivar, unsigned CVRQualifiers)=0
virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD)=0
Register an class alias.
virtual void GenerateCategory(const ObjCCategoryImplDecl *OCD)=0
Generate a category.
virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S, bool ClearInsertionPoint=true)=0
virtual llvm::Value * EmitIvarOffset(CodeGen::CodeGenFunction &CGF, const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar)=0
virtual llvm::Function * GenerateMethod(const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD)=0
Generate a function preamble for a method with the specified types.
virtual llvm::Value * GenerateProtocolRef(CodeGenFunction &CGF, const ObjCProtocolDecl *OPD)=0
Emit the code to return the named protocol as an object, as in a @protocol expression.
virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, Address AddrWeakObj)=0
virtual llvm::Function * ModuleInitFunction()=0
Generate the function required to register all Objective-C components in this compilation unit with t...
virtual CodeGen::RValue GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, ReturnValueSlot ReturnSlot, QualType ResultType, Selector Sel, const ObjCInterfaceDecl *Class, bool isCategoryImpl, llvm::Value *Self, bool IsClassMessage, const CallArgList &CallArgs, const ObjCMethodDecl *Method=nullptr)=0
Generate an Objective-C message send operation to the super class initiated in a method for Class and...
virtual void GenerateClass(const ObjCImplementationDecl *OID)=0
Generate a class structure for this class.
virtual llvm::FunctionCallee EnumerationMutationFunction()=0
EnumerationMutationFunction - Return the function that's called by the compiler when a mutation is de...
virtual llvm::Constant * BuildGCBlockLayout(CodeGen::CodeGenModule &CGM, const CodeGen::CGBlockInfo &blockInfo)=0
virtual llvm::FunctionCallee GetGetStructFunction()=0
virtual llvm::Constant * GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0
GetOrEmitProtocol - Get the protocol object for the given declaration, emitting it if necessary.
virtual ConstantAddress GenerateConstantString(const StringLiteral *)=0
Generate a constant string object.
virtual llvm::Value * GetClass(CodeGenFunction &CGF, const ObjCInterfaceDecl *OID)=0
GetClass - Return a reference to the class for the given interface decl.
virtual void GenerateProtocol(const ObjCProtocolDecl *OPD)=0
Generate the named protocol.
virtual llvm::Constant * BuildRCBlockLayout(CodeGen::CodeGenModule &CGM, const CodeGen::CGBlockInfo &blockInfo)=0
virtual llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic, bool copy)=0
Return the runtime function for optimized setting properties.
virtual llvm::Value * GetSelector(CodeGenFunction &CGF, Selector Sel)=0
Get a selector for the specified name and type values.
virtual void GenerateDirectMethodPrologue(CodeGenFunction &CGF, llvm::Function *Fn, const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD)=0
Generates prologue for direct Objective-C Methods.
virtual Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel)=0
Get the address of a selector for the specified name and type values.
virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest)=0
virtual llvm::Value * EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF)
virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest, bool threadlocal=false)=0
virtual llvm::FunctionCallee GetPropertyGetFunction()=0
Return the runtime function for getting properties.
virtual llvm::FunctionCallee GetSetStructFunction()=0
virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S)=0
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
void addFrom(const CallArgList &other)
Add all the arguments from another CallArgList to this one.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
SmallVector< llvm::Value *, 8 > ObjCEHValueStack
ObjCEHValueStack - Stack of Objective-C exception values, used for rethrows.
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **callOrInvoke, bool IsMustTail, SourceLocation Loc)
EmitCall - Generate a call of the given function, expecting the given result type,...
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
JumpDest ReturnBlock
ReturnBlock - Unified return block.
llvm::Value * EmitObjCThrowOperand(const Expr *expr)
llvm::Value * LoadObjCSelf()
LoadObjCSelf - Load the value of self.
void EmitVarDecl(const VarDecl &D)
EmitVarDecl - Emit a local variable declaration.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
static bool hasAggregateEvaluationKind(QualType T)
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
This class organizes the cross-function state that is used while generating LLVM code.
void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const
Set visibility, dllimport/dllexport and dso_local.
llvm::Module & getModule() const
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
void addCompilerUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.compiler.used metadata.
bool ReturnTypeUsesFPRet(QualType ResultType)
Return true iff the given type uses 'fpret' when used as a return type.
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
void addUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.used metadata.
const llvm::DataLayout & getDataLayout() const
CGCXXABI & getCXXABI() const
const llvm::Triple & getTriple() const
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.
bool isZeroInitializable(QualType T)
IsZeroInitializable - Return whether a type can be zero-initialized (in the C++ sense) with an LLVM z...
llvm::Type * ConvertTypeForMem(QualType T, bool ForBitField=false)
ConvertTypeForMem - Convert type T into a llvm::Type.
A specialization of Address that requires the address to be an LLVM Constant.
ArrayBuilder beginArray(llvm::Type *eltTy=nullptr)
llvm::GlobalVariable * finishAndCreateGlobal(As &&...args)
Given that this builder was created by beginning an array or struct directly on a ConstantInitBuilder...
StructBuilder beginStruct(llvm::StructType *ty=nullptr)
void finishAndAddTo(AggregateBuilderBase &parent)
Given that this builder was created by beginning an array or struct component on the given parent bui...
A helper class of ConstantInitBuilder, used for building constant array initializers.
The standard implementation of ConstantInitBuilder used in Clang.
A helper class of ConstantInitBuilder, used for building constant struct initializers.
LValue - This represents an lvalue references.
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
An abstract representation of an aligned address.
llvm::Value * getPointer() const
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
Decl - This represents one declaration (or definition), e.g.
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
StringRef getName() const
This represents one expression.
StringRef getName() const
The name of this FileEntry.
DirectoryEntryRef getDir() const
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
std::string ObjCConstantStringClass
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Visibility getVisibility() const
Determines the visibility of this entity.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
Represents Objective-C's @synchronized statement.
Represents Objective-C's @throw statement.
Represents Objective-C's @try ... @catch ... @finally statement.
ObjCCategoryDecl - Represents a category declaration.
const ObjCProtocolList & getReferencedProtocols() const
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
ObjCCategoryDecl * getCategoryDecl() const
ObjCCompatibleAliasDecl - Represents alias of a class.
const ObjCInterfaceDecl * getClassInterface() const
ObjCContainerDecl - Represents a container for method declarations.
classmeth_iterator classmeth_end() const
classmeth_iterator classmeth_begin() const
instmeth_range instance_methods() const
instmeth_iterator instmeth_end() const
instmeth_iterator instmeth_begin() const
prop_range properties() const
classmeth_range class_methods() const
propimpl_range property_impls() const
const ObjCInterfaceDecl * getClassInterface() const
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Represents an ObjC class declaration.
all_protocol_range all_referenced_protocols() const
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
protocol_range protocols() const
protocol_iterator protocol_end() const
protocol_iterator protocol_begin() const
ObjCInterfaceDecl * getSuperClass() const
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
known_extensions_range known_extensions() const
Interfaces are the core concept in Objective-C for object oriented design.
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
ObjCIvarDecl - Represents an ObjC instance variable.
ObjCInterfaceDecl * getContainingInterface()
Return the class interface that this ivar is logically contained in; this is either the interface whe...
ObjCIvarDecl * getNextIvar()
ObjCMethodDecl - Represents an instance or class method declaration.
ImplicitParamDecl * getSelfDecl() const
bool hasParamDestroyedInCallee() const
True if the method has a parameter that's destroyed in the callee.
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
ObjCMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Selector getSelector() const
ImplicitParamDecl * getCmdDecl() const
QualType getReturnType() const
bool isClassMethod() const
ObjCInterfaceDecl * getClassInterface()
Represents a pointer to an Objective C object.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
const ObjCInterfaceType * getInterfaceType() const
If this pointer points to an Objective C @interface type, gets the type for that interface.
Represents a class type in Objective C.
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface.
Represents one property declaration in an Objective-C interface.
ObjCMethodDecl * getGetterMethodDecl() const
ObjCMethodDecl * getSetterMethodDecl() const
Represents an Objective-C protocol declaration.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
bool isNonRuntimeProtocol() const
This is true iff the protocol is tagged with the objc_non_runtime_protocol attribute.
protocol_iterator protocol_begin() const
protocol_range protocols() const
protocol_iterator protocol_end() const
The basic abstraction for the target Objective-C runtime.
const VersionTuple & getVersion() const
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
Kind
The basic Objective-C runtimes that we know about.
@ MacOSX
'macosx' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the non-fragile AB...
@ FragileMacOSX
'macosx-fragile' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the fragil...
@ GNUstep
'gnustep' is the modern non-fragile GNUstep runtime.
@ ObjFW
'objfw' is the Objective-C runtime included in ObjFW
@ iOS
'ios' is the Apple-provided NeXT-derived runtime on iOS or the iOS simulator; it is always non-fragil...
@ GCC
'gcc' is the Objective-C runtime shipped with GCC, implementing a fragile Objective-C ABI
@ WatchOS
'watchos' is a variant of iOS for Apple's watchOS.
A (possibly-)qualified type.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
This table allows us to fully hide how we implement multi-keyword caching.
Smart pointer class that efficiently represents Objective-C method names.
std::string getAsString() const
Derive the full selector name (e.g.
This class handles loading and caching of source files into memory.
StringLiteral - This represents a string literal expression, e.g.
bool containsNonAscii() const
unsigned getLength() const
uint32_t getCodeUnit(size_t i) const
StringRef getString() const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
The top declaration context.
static DeclContext * castToDeclContext(const TranslationUnitDecl *D)
const T * castAs() const
Member-template castAs<specific type>.
bool isObjCQualifiedIdType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isObjCIdType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
Represents a variable declaration or definition.
CGObjCRuntime * CreateGNUObjCRuntime(CodeGenModule &CGM)
Creates an instance of an Objective-C runtime class.
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
bool Zero(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
const FunctionProtoType * T
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ HiddenVisibility
Objects with "hidden" visibility are not seen by the dynamic linker.
The MS C++ ABI needs a pointer to RTTI data plus some flags to describe the type of a catch handler,...
CharUnits getIntAlign() const
llvm::IntegerType * Int16Ty
llvm::PointerType * Int8PtrTy
CharUnits getPointerAlign() const