31#include "llvm/ADT/SmallVector.h"
32#include "llvm/ADT/StringMap.h"
33#include "llvm/IR/DataLayout.h"
34#include "llvm/IR/Intrinsics.h"
35#include "llvm/IR/LLVMContext.h"
36#include "llvm/IR/Module.h"
37#include "llvm/Support/Compiler.h"
38#include "llvm/Support/ConvertUTF.h"
42using namespace CodeGen;
49class LazyRuntimeFunction {
51 llvm::FunctionType *FTy =
nullptr;
52 const char *FunctionName =
nullptr;
53 llvm::FunctionCallee
Function =
nullptr;
56 LazyRuntimeFunction() =
default;
60 template <
typename... Tys>
61 void init(
CodeGenModule *Mod,
const char *name, llvm::Type *RetTy,
68 FTy = llvm::FunctionType::get(RetTy, ArgTys,
false);
71 FTy = llvm::FunctionType::get(RetTy, {},
false);
75 llvm::FunctionType *getType() {
return FTy; }
79 operator llvm::FunctionCallee() {
96 llvm::Module &TheModule;
99 llvm::StructType *ObjCSuperTy;
102 llvm::PointerType *PtrToObjCSuperTy;
106 llvm::PointerType *SelectorTy;
108 llvm::Type *SelectorElemTy;
111 llvm::IntegerType *Int8Ty;
114 llvm::PointerType *PtrToInt8Ty;
116 llvm::StructType *ProtocolTy;
118 llvm::PointerType *ProtocolPtrTy;
124 llvm::PointerType *IMPTy;
129 llvm::PointerType *IdTy;
131 llvm::Type *IdElemTy;
134 llvm::PointerType *PtrToIdTy;
139 llvm::IntegerType *IntTy;
143 llvm::PointerType *PtrTy;
147 llvm::IntegerType *LongTy;
149 llvm::IntegerType *SizeTy;
151 llvm::IntegerType *IntPtrTy;
153 llvm::IntegerType *PtrDiffTy;
156 llvm::PointerType *PtrToIntTy;
160 llvm::IntegerType *Int32Ty;
162 llvm::IntegerType *Int64Ty;
164 llvm::StructType *PropertyMetadataTy;
168 unsigned msgSendMDKind;
171 bool usesSEHExceptions;
173 bool usesCxxExceptions;
178 return (R.
getKind() == kind) &&
179 (R.
getVersion() >= VersionTuple(major, minor));
182 std::string ManglePublicSymbol(StringRef Name) {
183 return (StringRef(CGM.
getTriple().isOSBinFormatCOFF() ?
"$_" :
"._") + Name).str();
186 std::string SymbolForProtocol(Twine Name) {
187 return (ManglePublicSymbol(
"OBJC_PROTOCOL_") + Name).str();
190 std::string SymbolForProtocolRef(StringRef Name) {
191 return (ManglePublicSymbol(
"OBJC_REF_PROTOCOL_") + Name).str();
198 llvm::Constant *MakeConstantString(StringRef Str,
const char *Name =
"") {
201 return Array.getPointer();
208 llvm::Constant *ExportUniqueString(
const std::string &Str,
209 const std::string &prefix,
210 bool Private=
false) {
211 std::string
name = prefix + Str;
212 auto *ConstStr = TheModule.getGlobalVariable(name);
214 llvm::Constant *value = llvm::ConstantDataArray::getString(VMContext,Str);
215 auto *GV =
new llvm::GlobalVariable(TheModule, value->getType(),
true,
216 llvm::GlobalValue::LinkOnceODRLinkage, value, name);
217 GV->setComdat(TheModule.getOrInsertComdat(name));
219 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
227 const Decl *Container) {
230 std::string NameAndAttributes;
231 std::string TypeStr =
233 NameAndAttributes +=
'\0';
234 NameAndAttributes += TypeStr.length() + 3;
235 NameAndAttributes += TypeStr;
236 NameAndAttributes +=
'\0';
238 return MakeConstantString(NameAndAttributes);
247 int attrs =
property->getPropertyAttributes();
250 attrs &= ~ObjCPropertyAttribute::kind_copy;
251 attrs &= ~ObjCPropertyAttribute::kind_retain;
252 attrs &= ~ObjCPropertyAttribute::kind_weak;
253 attrs &= ~ObjCPropertyAttribute::kind_strong;
256 Fields.addInt(Int8Ty, attrs & 0xff);
262 attrs |= isSynthesized ? (1<<0) : 0;
263 attrs |= isDynamic ? (1<<1) : 0;
266 Fields.addInt(Int8Ty, attrs & 0xff);
268 Fields.addInt(Int8Ty, 0);
269 Fields.addInt(Int8Ty, 0);
272 virtual llvm::Constant *GenerateCategoryProtocolList(
const
277 Fields.addInt(IntTy, count);
280 const llvm::DataLayout &DL = TheModule.getDataLayout();
281 Fields.addInt(IntTy, DL.getTypeSizeInBits(PropertyMetadataTy) /
292 bool isSynthesized=
true,
bool
294 auto Fields = PropertiesArray.
beginStruct(PropertyMetadataTy);
296 Fields.add(MakePropertyEncodingString(property, OCD));
297 PushPropertyAttributes(Fields, property, isSynthesized, isDynamic);
301 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
302 Fields.add(MakeConstantString(accessor->getSelector().getAsString()));
303 Fields.add(TypeEncoding);
317 llvm::Value *EnforceType(
CGBuilderTy &B, llvm::Value *
V, llvm::Type *Ty) {
318 if (
V->getType() == Ty)
320 return B.CreateBitCast(
V, Ty);
324 llvm::Constant *Zeros[2];
326 llvm::Constant *NULLPtr;
328 llvm::LLVMContext &VMContext;
336 llvm::GlobalAlias *ClassPtrAlias;
341 llvm::GlobalAlias *MetaClassPtrAlias;
343 std::vector<llvm::Constant*> Classes;
345 std::vector<llvm::Constant*> Categories;
348 std::vector<llvm::Constant*> ConstantStrings;
352 llvm::StringMap<llvm::Constant*> ObjCStrings;
354 llvm::StringMap<llvm::Constant*> ExistingProtocols;
360 typedef std::pair<std::string, llvm::GlobalAlias*> TypedSelector;
364 typedef llvm::DenseMap<Selector, SmallVector<TypedSelector, 2> >
372 Selector RetainSel, ReleaseSel, AutoreleaseSel;
376 LazyRuntimeFunction IvarAssignFn, StrongCastAssignFn, MemMoveFn, WeakReadFn,
377 WeakAssignFn, GlobalAssignFn;
379 typedef std::pair<std::string, std::string> ClassAliasPair;
381 std::vector<ClassAliasPair> ClassAliases;
385 LazyRuntimeFunction ExceptionThrowFn;
388 LazyRuntimeFunction ExceptionReThrowFn;
391 LazyRuntimeFunction EnterCatchFn;
394 LazyRuntimeFunction ExitCatchFn;
396 LazyRuntimeFunction SyncEnterFn;
398 LazyRuntimeFunction SyncExitFn;
403 LazyRuntimeFunction EnumerationMutationFn;
406 LazyRuntimeFunction GetPropertyFn;
409 LazyRuntimeFunction SetPropertyFn;
411 LazyRuntimeFunction GetStructPropertyFn;
413 LazyRuntimeFunction SetStructPropertyFn;
425 const int ProtocolVersion;
428 const int ClassABIVersion;
444 llvm::Constant *GenerateMethodList(StringRef ClassName,
445 StringRef CategoryName,
447 bool isClassMethodList);
452 virtual llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName);
456 llvm::Constant *GeneratePropertyList(
const Decl *Container,
458 bool isClassProperty=
false,
459 bool protocolOptionalProperties=
false);
469 void GenerateProtocolHolderCategory();
472 llvm::Constant *GenerateClassStructure(
473 llvm::Constant *MetaClass,
474 llvm::Constant *SuperClass,
477 llvm::Constant *Version,
478 llvm::Constant *InstanceSize,
479 llvm::Constant *IVars,
480 llvm::Constant *Methods,
481 llvm::Constant *Protocols,
482 llvm::Constant *IvarOffsets,
483 llvm::Constant *Properties,
484 llvm::Constant *StrongIvarBitmap,
485 llvm::Constant *WeakIvarBitmap,
490 virtual llvm::Constant *GenerateProtocolMethodList(
494 void EmitProtocolMethodList(
T &&Methods, llvm::Constant *&
Required,
498 for (
const auto *I : Methods)
500 OptionalMethods.push_back(I);
502 RequiredMethods.push_back(I);
503 Required = GenerateProtocolMethodList(RequiredMethods);
504 Optional = GenerateProtocolMethodList(OptionalMethods);
510 const std::string &TypeEncoding);
517 const std::string Name =
"__objc_ivar_offset_" +
ID->getNameAsString()
526 void EmitClassRef(
const std::string &className);
530 const std::string &Name,
bool isWeak);
536 llvm::Value *&Receiver,
539 MessageSendInfo &MSI) = 0;
547 MessageSendInfo &MSI) = 0;
564 unsigned protocolClassVersion,
unsigned classABI=1);
571 llvm::Value *Receiver,
const CallArgList &CallArgs,
578 bool isCategoryImpl, llvm::Value *Receiver,
587 virtual llvm::Constant *GetConstantSelector(
Selector Sel,
588 const std::string &TypeEncoding) {
589 llvm_unreachable(
"Runtime unable to generate constant selector");
601 llvm::DenseMap<const ObjCMethodDecl *, llvm::Function *>
602 DirectMethodDefinitions;
636 bool ClearInsertionPoint=
true)
override;
640 llvm::Value *src,
Address dst)
override;
642 llvm::Value *src,
Address dest,
643 bool threadlocal=
false)
override;
645 Address dest, llvm::Value *ivarOffset)
override;
647 llvm::Value *src,
Address dest)
override;
650 llvm::Value *Size)
override;
653 unsigned CVRQualifiers)
override;
680class CGObjCGCC :
public CGObjCGNU {
683 LazyRuntimeFunction MsgLookupFn;
687 LazyRuntimeFunction MsgLookupSuperFn;
691 llvm::Value *cmd, llvm::MDNode *node,
692 MessageSendInfo &MSI)
override {
694 llvm::Value *args[] = {
695 EnforceType(Builder, Receiver, IdTy),
696 EnforceType(Builder, cmd, SelectorTy) };
698 imp->setMetadata(msgSendMDKind, node);
703 llvm::Value *cmd, MessageSendInfo &MSI)
override {
705 llvm::Value *lookupArgs[] = {
706 EnforceType(Builder, ObjCSuper.
emitRawPointer(CGF), PtrToObjCSuperTy),
714 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
716 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
717 PtrToObjCSuperTy, SelectorTy);
722class CGObjCGNUstep :
public CGObjCGNU {
725 LazyRuntimeFunction SlotLookupFn;
730 LazyRuntimeFunction SlotLookupSuperFn;
732 LazyRuntimeFunction SetPropertyAtomic;
734 LazyRuntimeFunction SetPropertyAtomicCopy;
736 LazyRuntimeFunction SetPropertyNonAtomic;
738 LazyRuntimeFunction SetPropertyNonAtomicCopy;
741 LazyRuntimeFunction CxxAtomicObjectGetFn;
744 LazyRuntimeFunction CxxAtomicObjectSetFn;
749 llvm::Type *SlotStructTy;
752 llvm::Constant *GetEHType(
QualType T)
override;
756 llvm::Value *cmd, llvm::MDNode *node,
757 MessageSendInfo &MSI)
override {
759 llvm::FunctionCallee LookupFn = SlotLookupFn;
764 Builder.CreateStore(Receiver, ReceiverPtr);
771 self = llvm::ConstantPointerNull::get(IdTy);
775 if (
auto *LookupFn2 = dyn_cast<llvm::Function>(LookupFn.getCallee()))
776 LookupFn2->addParamAttr(
778 llvm::CaptureInfo::none()));
780 llvm::Value *args[] = {
781 EnforceType(Builder, ReceiverPtr.
getPointer(), PtrToIdTy),
782 EnforceType(Builder, cmd, SelectorTy),
783 EnforceType(Builder, self, IdTy)};
785 slot->setOnlyReadsMemory();
786 slot->setMetadata(msgSendMDKind, node);
789 llvm::Value *imp = Builder.CreateAlignedLoad(
790 IMPTy, Builder.CreateStructGEP(SlotStructTy, slot, 4),
795 Receiver = Builder.CreateLoad(ReceiverPtr,
true);
801 MessageSendInfo &MSI)
override {
805 llvm::CallInst *slot =
807 slot->setOnlyReadsMemory();
809 return Builder.CreateAlignedLoad(
810 IMPTy, Builder.CreateStructGEP(SlotStructTy, slot, 4),
815 CGObjCGNUstep(
CodeGenModule &Mod) : CGObjCGNUstep(Mod, 9, 3, 1) {}
816 CGObjCGNUstep(
CodeGenModule &Mod,
unsigned ABI,
unsigned ProtocolABI,
818 CGObjCGNU(Mod, ABI, ProtocolABI, ClassABI) {
821 SlotStructTy = llvm::StructType::get(PtrTy, PtrTy, PtrTy, IntTy, IMPTy);
822 SlotTy = llvm::PointerType::getUnqual(SlotStructTy);
824 SlotLookupFn.init(&CGM,
"objc_msg_lookup_sender", SlotTy, PtrToIdTy,
827 SlotLookupSuperFn.init(&CGM,
"objc_slot_lookup_super", SlotTy,
828 PtrToObjCSuperTy, SelectorTy);
830 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
831 if (usesCxxExceptions) {
833 EnterCatchFn.init(&CGM,
"__cxa_begin_catch", PtrTy, PtrTy);
835 ExitCatchFn.init(&CGM,
"__cxa_end_catch", VoidTy);
837 ExceptionReThrowFn.init(&CGM,
"__cxa_rethrow", PtrTy);
838 }
else if (usesSEHExceptions) {
840 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy);
843 EnterCatchFn.init(&CGM,
"__cxa_begin_catch", PtrTy, PtrTy);
845 ExitCatchFn.init(&CGM,
"__cxa_end_catch", VoidTy);
847 ExceptionReThrowFn.init(&CGM,
"_Unwind_Resume_or_Rethrow", VoidTy,
849 }
else if (R.
getVersion() >= VersionTuple(1, 7)) {
851 EnterCatchFn.init(&CGM,
"objc_begin_catch", IdTy, PtrTy);
853 ExitCatchFn.init(&CGM,
"objc_end_catch", VoidTy);
855 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy, PtrTy);
857 SetPropertyAtomic.init(&CGM,
"objc_setProperty_atomic", VoidTy, IdTy,
858 SelectorTy, IdTy, PtrDiffTy);
859 SetPropertyAtomicCopy.init(&CGM,
"objc_setProperty_atomic_copy", VoidTy,
860 IdTy, SelectorTy, IdTy, PtrDiffTy);
861 SetPropertyNonAtomic.init(&CGM,
"objc_setProperty_nonatomic", VoidTy,
862 IdTy, SelectorTy, IdTy, PtrDiffTy);
863 SetPropertyNonAtomicCopy.init(&CGM,
"objc_setProperty_nonatomic_copy",
864 VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy);
867 CxxAtomicObjectSetFn.init(&CGM,
"objc_setCppObjectAtomic", VoidTy, PtrTy,
871 CxxAtomicObjectGetFn.init(&CGM,
"objc_getCppObjectAtomic", VoidTy, PtrTy,
875 llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override {
880 return CxxAtomicObjectGetFn;
883 llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override {
888 return CxxAtomicObjectSetFn;
891 llvm::FunctionCallee GetOptimizedPropertySetFunction(
bool atomic,
892 bool copy)
override {
896 assert ((CGM.
getLangOpts().getGC() == LangOptions::NonGC));
903 if (copy)
return SetPropertyAtomicCopy;
904 return SetPropertyAtomic;
907 return copy ? SetPropertyNonAtomicCopy : SetPropertyNonAtomic;
914class CGObjCGNUstep2 :
public CGObjCGNUstep {
919 ClassReferenceSection,
922 ProtocolReferenceSection,
924 ConstantStringSection
929 ClassFlagMeta = (1 << 0),
932 ClassFlagInitialized = (1 << 8),
934 static const char *
const SectionsBaseNames[8];
935 static const char *
const PECOFFSectionsBaseNames[8];
936 template<SectionKind K>
937 std::string sectionName() {
938 if (CGM.
getTriple().isOSBinFormatCOFF()) {
939 std::string
name(PECOFFSectionsBaseNames[K]);
943 return SectionsBaseNames[K];
948 LazyRuntimeFunction MsgLookupSuperFn;
950 LazyRuntimeFunction SentInitializeFn;
954 bool EmittedProtocol =
false;
959 bool EmittedProtocolRef =
false;
963 bool EmittedClass =
false;
967 typedef std::pair<std::string, std::pair<llvm::GlobalVariable*, int>>
969 std::vector<EarlyInitPair> EarlyInitList;
971 std::string SymbolForClassRef(StringRef Name,
bool isWeak) {
973 return (ManglePublicSymbol(
"OBJC_WEAK_REF_CLASS_") + Name).str();
975 return (ManglePublicSymbol(
"OBJC_REF_CLASS_") + Name).str();
978 std::string SymbolForClass(StringRef Name) {
979 return (ManglePublicSymbol(
"OBJC_CLASS_") + Name).str();
981 void CallRuntimeFunction(
CGBuilderTy &B, StringRef FunctionName,
984 for (
auto *Arg : Args)
985 Types.push_back(Arg->getType());
986 llvm::FunctionType *FT = llvm::FunctionType::get(B.getVoidTy(), Types,
989 B.CreateCall(Fn, Args);
998 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
999 if (old != ObjCStrings.end())
1007 (LiteralLength < 9) && !isNonASCII) {
1013 for (
unsigned i=0 ; i<LiteralLength ; i++)
1014 str |= ((uint64_t)SL->
getCodeUnit(i)) << ((64 - 4 - 3) - (i*7));
1016 str |= LiteralLength << 3;
1019 auto *ObjCStr = llvm::ConstantExpr::getIntToPtr(
1020 llvm::ConstantInt::get(Int64Ty, str), IdTy);
1021 ObjCStrings[Str] = ObjCStr;
1027 if (StringClass.empty()) StringClass =
"NSConstantString";
1029 std::string Sym = SymbolForClass(StringClass);
1031 llvm::Constant *
isa = TheModule.getNamedGlobal(Sym);
1034 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
1035 llvm::GlobalValue::ExternalLinkage,
nullptr, Sym);
1036 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1037 cast<llvm::GlobalValue>(isa)->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
1052 auto Fields = Builder.beginStruct();
1053 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
1056 Fields.addNullPointer(PtrTy);
1063 unsigned NumU8CodeUnits = Str.size();
1068 const llvm::UTF8 *FromPtr = (
const llvm::UTF8 *)Str.data();
1069 llvm::UTF16 *ToPtr = &ToBuf[0];
1070 (void)llvm::ConvertUTF8toUTF16(&FromPtr, FromPtr + NumU8CodeUnits,
1071 &ToPtr, ToPtr + NumU8CodeUnits, llvm::strictConversion);
1072 uint32_t StringLength = ToPtr - &ToBuf[0];
1076 Fields.addInt(Int32Ty, 2);
1078 Fields.addInt(Int32Ty, StringLength);
1080 Fields.addInt(Int32Ty, StringLength * 2);
1082 Fields.addInt(Int32Ty, 0);
1085 auto *
C = llvm::ConstantDataArray::get(VMContext, Arr);
1086 auto *Buffer =
new llvm::GlobalVariable(TheModule,
C->getType(),
1087 true, llvm::GlobalValue::PrivateLinkage,
C,
".str");
1088 Buffer->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1092 Fields.addInt(Int32Ty, 0);
1094 Fields.addInt(Int32Ty, Str.size());
1096 Fields.addInt(Int32Ty, Str.size());
1098 Fields.addInt(Int32Ty, 0);
1100 Fields.add(MakeConstantString(Str));
1102 std::string StringName;
1105 StringName =
".objc_str_";
1106 for (
int i=0,e=Str.size() ; i<e ; ++i) {
1107 unsigned char c = Str[i];
1118 llvm::GlobalVariable *ObjCStrGV =
1120 isNamed ? StringRef(StringName) :
".objc_string",
1121 Align,
false,
isNamed ? llvm::GlobalValue::LinkOnceODRLinkage
1122 : llvm::GlobalValue::PrivateLinkage);
1123 ObjCStrGV->setSection(sectionName<ConstantStringSection>());
1125 ObjCStrGV->setComdat(TheModule.getOrInsertComdat(StringName));
1126 ObjCStrGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1128 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1129 std::pair<llvm::GlobalVariable*, int>
v{ObjCStrGV, 0};
1130 EarlyInitList.emplace_back(Sym,
v);
1132 ObjCStrings[Str] = ObjCStrGV;
1133 ConstantStrings.push_back(ObjCStrGV);
1140 bool isSynthesized=
true,
bool
1141 isDynamic=
true)
override {
1150 auto Fields = PropertiesArray.
beginStruct(PropertyMetadataTy);
1153 std::string TypeStr =
1155 Fields.add(MakeConstantString(TypeStr));
1156 std::string typeStr;
1158 Fields.add(MakeConstantString(typeStr));
1162 Fields.add(GetConstantSelector(accessor->getSelector(), TypeStr));
1164 Fields.add(NULLPtr);
1179 llvm::StructType *ObjCMethodDescTy =
1181 { PtrToInt8Ty, PtrToInt8Ty });
1190 auto MethodList = Builder.beginStruct();
1192 MethodList.addInt(IntTy, Methods.size());
1194 const llvm::DataLayout &DL = TheModule.getDataLayout();
1195 MethodList.addInt(IntTy, DL.getTypeSizeInBits(ObjCMethodDescTy) /
1198 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
1199 for (
auto *M : Methods) {
1200 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
1201 Method.add(CGObjCGNU::GetConstantSelector(M));
1203 Method.finishAndAddTo(MethodArray);
1205 MethodArray.finishAndAddTo(MethodList);
1206 return MethodList.finishAndCreateGlobal(
".objc_protocol_method_list",
1212 auto RuntimeProtocols = GetRuntimeProtocolList(ReferencedProtocols.begin(),
1213 ReferencedProtocols.end());
1215 for (
const auto *PI : RuntimeProtocols)
1216 Protocols.push_back(GenerateProtocolRef(PI));
1217 return GenerateProtocolList(Protocols);
1221 llvm::Value *cmd, MessageSendInfo &MSI)
override {
1224 llvm::Value *lookupArgs[] = {
1231 llvm::GlobalVariable *GetClassVar(StringRef Name,
bool isWeak=
false) {
1232 std::string SymbolName = SymbolForClassRef(Name, isWeak);
1233 auto *ClassSymbol = TheModule.getNamedGlobal(SymbolName);
1236 ClassSymbol =
new llvm::GlobalVariable(TheModule,
1237 IdTy,
false, llvm::GlobalValue::ExternalLinkage,
1238 nullptr, SymbolName);
1244 ClassSymbol->setInitializer(
new llvm::GlobalVariable(TheModule,
1245 Int8Ty,
false, llvm::GlobalValue::ExternalWeakLinkage,
1246 nullptr, SymbolForClass(Name)));
1248 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1254 for (
const auto *Result : DC->
lookup(&II))
1255 if ((OID = dyn_cast<ObjCInterfaceDecl>(Result)))
1261 assert(OID &&
"Failed to find ObjCInterfaceDecl");
1263 if (OIDDef !=
nullptr)
1266 auto Storage = llvm::GlobalValue::DefaultStorageClass;
1267 if (OID->
hasAttr<DLLImportAttr>())
1268 Storage = llvm::GlobalValue::DLLImportStorageClass;
1269 else if (OID->
hasAttr<DLLExportAttr>())
1270 Storage = llvm::GlobalValue::DLLExportStorageClass;
1272 cast<llvm::GlobalValue>(ClassSymbol)->setDLLStorageClass(Storage);
1275 assert(ClassSymbol->getName() == SymbolName);
1279 const std::string &Name,
1280 bool isWeak)
override {
1292 switch (Ownership) {
1314 llvm_unreachable(
"Method should not be called!");
1317 llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName)
override {
1318 std::string Name = SymbolForProtocol(ProtocolName);
1319 auto *GV = TheModule.getGlobalVariable(Name);
1322 GV =
new llvm::GlobalVariable(TheModule, ProtocolTy,
false,
1323 llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
1330 llvm::StringMap<llvm::Constant*> ExistingProtocolRefs;
1335 auto *&Ref = ExistingProtocolRefs[Name];
1337 auto *&
Protocol = ExistingProtocols[Name];
1339 Protocol = GenerateProtocolRef(PD);
1340 std::string RefName = SymbolForProtocolRef(Name);
1341 assert(!TheModule.getGlobalVariable(RefName));
1343 auto GV =
new llvm::GlobalVariable(TheModule, ProtocolPtrTy,
false,
1344 llvm::GlobalValue::LinkOnceODRLinkage,
1346 GV->setComdat(TheModule.getOrInsertComdat(RefName));
1347 GV->setSection(sectionName<ProtocolReferenceSection>());
1351 EmittedProtocolRef =
true;
1357 llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(ProtocolPtrTy,
1359 llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
1362 auto ProtocolBuilder = builder.beginStruct();
1363 ProtocolBuilder.addNullPointer(PtrTy);
1364 ProtocolBuilder.addInt(SizeTy, Protocols.size());
1365 ProtocolBuilder.add(ProtocolArray);
1366 return ProtocolBuilder.finishAndCreateGlobal(
".objc_protocol_list",
1375 auto *&
Protocol = ExistingProtocols[ProtocolName];
1379 EmittedProtocol =
true;
1381 auto SymName = SymbolForProtocol(ProtocolName);
1382 auto *OldGV = TheModule.getGlobalVariable(SymName);
1392 Protocol =
new llvm::GlobalVariable(TheModule, ProtocolTy,
1394 llvm::GlobalValue::ExternalLinkage,
nullptr, SymName);
1399 auto RuntimeProtocols =
1401 for (
const auto *PI : RuntimeProtocols)
1402 Protocols.push_back(GenerateProtocolRef(PI));
1403 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
1406 llvm::Constant *InstanceMethodList, *OptionalInstanceMethodList;
1407 llvm::Constant *ClassMethodList, *OptionalClassMethodList;
1409 OptionalInstanceMethodList);
1410 EmitProtocolMethodList(PD->
class_methods(), ClassMethodList,
1411 OptionalClassMethodList);
1416 auto ProtocolBuilder = builder.beginStruct();
1417 ProtocolBuilder.add(llvm::ConstantExpr::getIntToPtr(
1418 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
1419 ProtocolBuilder.add(MakeConstantString(ProtocolName));
1420 ProtocolBuilder.add(ProtocolList);
1421 ProtocolBuilder.add(InstanceMethodList);
1422 ProtocolBuilder.add(ClassMethodList);
1423 ProtocolBuilder.add(OptionalInstanceMethodList);
1424 ProtocolBuilder.add(OptionalClassMethodList);
1426 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
false,
false));
1428 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
false,
true));
1430 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
true,
false));
1432 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
true,
true));
1434 auto *GV = ProtocolBuilder.finishAndCreateGlobal(SymName,
1436 GV->setSection(sectionName<ProtocolSection>());
1437 GV->setComdat(TheModule.getOrInsertComdat(SymName));
1439 OldGV->replaceAllUsesWith(GV);
1440 OldGV->removeFromParent();
1441 GV->setName(SymName);
1447 const std::string &TypeEncoding)
override {
1448 return GetConstantSelector(Sel, TypeEncoding);
1450 std::string GetSymbolNameForTypeEncoding(
const std::string &TypeEncoding) {
1451 std::string MangledTypes = std::string(TypeEncoding);
1457 std::replace(MangledTypes.begin(), MangledTypes.end(),
'@',
'\1');
1460 std::replace(MangledTypes.begin(), MangledTypes.end(),
'=',
'\2');
1461 return MangledTypes;
1463 llvm::Constant *GetTypeString(llvm::StringRef TypeEncoding) {
1464 if (TypeEncoding.empty())
1466 std::string MangledTypes =
1467 GetSymbolNameForTypeEncoding(std::string(TypeEncoding));
1468 std::string TypesVarName =
".objc_sel_types_" + MangledTypes;
1469 auto *TypesGlobal = TheModule.getGlobalVariable(TypesVarName);
1471 llvm::Constant *
Init = llvm::ConstantDataArray::getString(VMContext,
1473 auto *GV =
new llvm::GlobalVariable(TheModule,
Init->getType(),
1474 true, llvm::GlobalValue::LinkOnceODRLinkage,
Init, TypesVarName);
1475 GV->setComdat(TheModule.getOrInsertComdat(TypesVarName));
1476 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1481 llvm::Constant *GetConstantSelector(
Selector Sel,
1482 const std::string &TypeEncoding)
override {
1483 std::string MangledTypes = GetSymbolNameForTypeEncoding(TypeEncoding);
1484 auto SelVarName = (StringRef(
".objc_selector_") + Sel.
getAsString() +
"_" +
1485 MangledTypes).str();
1486 if (
auto *GV = TheModule.getNamedGlobal(SelVarName))
1489 auto SelBuilder = builder.beginStruct();
1490 SelBuilder.add(ExportUniqueString(Sel.
getAsString(),
".objc_sel_name_",
1492 SelBuilder.add(GetTypeString(TypeEncoding));
1493 auto *GV = SelBuilder.finishAndCreateGlobal(SelVarName,
1495 GV->setComdat(TheModule.getOrInsertComdat(SelVarName));
1496 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1497 GV->setSection(sectionName<SelectorSection>());
1500 llvm::StructType *emptyStruct =
nullptr;
1509 std::pair<llvm::Constant*,llvm::Constant*>
1510 GetSectionBounds(StringRef Section) {
1511 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1512 if (emptyStruct ==
nullptr) {
1513 emptyStruct = llvm::StructType::create(
1514 VMContext, {},
".objc_section_sentinel",
true);
1516 auto ZeroInit = llvm::Constant::getNullValue(emptyStruct);
1517 auto Sym = [&](StringRef Prefix, StringRef SecSuffix) {
1518 auto *Sym =
new llvm::GlobalVariable(TheModule, emptyStruct,
1520 llvm::GlobalValue::LinkOnceODRLinkage, ZeroInit, Prefix +
1522 Sym->setVisibility(llvm::GlobalValue::HiddenVisibility);
1523 Sym->setSection((Section + SecSuffix).str());
1524 Sym->setComdat(TheModule.getOrInsertComdat((Prefix +
1529 return { Sym(
"__start_",
"$a"), Sym(
"__stop",
"$z") };
1531 auto *Start =
new llvm::GlobalVariable(TheModule, PtrTy,
1533 llvm::GlobalValue::ExternalLinkage,
nullptr, StringRef(
"__start_") +
1535 Start->setVisibility(llvm::GlobalValue::HiddenVisibility);
1536 auto *Stop =
new llvm::GlobalVariable(TheModule, PtrTy,
1538 llvm::GlobalValue::ExternalLinkage,
nullptr, StringRef(
"__stop_") +
1540 Stop->setVisibility(llvm::GlobalValue::HiddenVisibility);
1541 return { Start, Stop };
1546 llvm::Function *ModuleInitFunction()
override {
1547 llvm::Function *LoadFunction = llvm::Function::Create(
1548 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
1549 llvm::GlobalValue::LinkOnceODRLinkage,
".objcv2_load_function",
1551 LoadFunction->setVisibility(llvm::GlobalValue::HiddenVisibility);
1552 LoadFunction->setComdat(TheModule.getOrInsertComdat(
".objcv2_load_function"));
1554 llvm::BasicBlock *EntryBB =
1555 llvm::BasicBlock::Create(VMContext,
"entry", LoadFunction);
1557 B.SetInsertPoint(EntryBB);
1559 auto InitStructBuilder = builder.beginStruct();
1560 InitStructBuilder.addInt(Int64Ty, 0);
1561 auto §ionVec = CGM.
getTriple().isOSBinFormatCOFF() ? PECOFFSectionsBaseNames : SectionsBaseNames;
1562 for (
auto *
s : sectionVec) {
1563 auto bounds = GetSectionBounds(
s);
1564 InitStructBuilder.add(bounds.first);
1565 InitStructBuilder.add(bounds.second);
1567 auto *InitStruct = InitStructBuilder.finishAndCreateGlobal(
".objc_init",
1569 InitStruct->setVisibility(llvm::GlobalValue::HiddenVisibility);
1570 InitStruct->setComdat(TheModule.getOrInsertComdat(
".objc_init"));
1572 CallRuntimeFunction(B,
"__objc_load", {InitStruct});;
1579 auto *InitVar =
new llvm::GlobalVariable(TheModule, LoadFunction->getType(),
1580 false, llvm::GlobalValue::LinkOnceAnyLinkage,
1581 LoadFunction,
".objc_ctor");
1584 assert(InitVar->getName() ==
".objc_ctor");
1590 if (CGM.
getTriple().isOSBinFormatCOFF())
1591 InitVar->setSection(
".CRT$XCLz");
1595 InitVar->setSection(
".init_array");
1597 InitVar->setSection(
".ctors");
1599 InitVar->setVisibility(llvm::GlobalValue::HiddenVisibility);
1600 InitVar->setComdat(TheModule.getOrInsertComdat(
".objc_ctor"));
1602 for (
auto *
C : Categories) {
1603 auto *Cat = cast<llvm::GlobalVariable>(
C->stripPointerCasts());
1604 Cat->setSection(sectionName<CategorySection>());
1608 StringRef Section) {
1609 auto nullBuilder = builder.beginStruct();
1610 for (
auto *F :
Init)
1612 auto GV = nullBuilder.finishAndCreateGlobal(Name, CGM.
getPointerAlign(),
1613 false, llvm::GlobalValue::LinkOnceODRLinkage);
1614 GV->setSection(Section);
1615 GV->setComdat(TheModule.getOrInsertComdat(Name));
1616 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1620 for (
auto clsAlias : ClassAliases)
1621 createNullGlobal(std::string(
".objc_class_alias") +
1622 clsAlias.second, { MakeConstantString(clsAlias.second),
1623 GetClassVar(clsAlias.first) }, sectionName<ClassAliasSection>());
1628 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
1629 createNullGlobal(
".objc_null_selector", {NULLPtr, NULLPtr},
1630 sectionName<SelectorSection>());
1631 if (Categories.empty())
1632 createNullGlobal(
".objc_null_category", {NULLPtr, NULLPtr,
1633 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr},
1634 sectionName<CategorySection>());
1635 if (!EmittedClass) {
1636 createNullGlobal(
".objc_null_cls_init_ref", NULLPtr,
1637 sectionName<ClassSection>());
1638 createNullGlobal(
".objc_null_class_ref", { NULLPtr, NULLPtr },
1639 sectionName<ClassReferenceSection>());
1641 if (!EmittedProtocol)
1642 createNullGlobal(
".objc_null_protocol", {NULLPtr, NULLPtr, NULLPtr,
1643 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr,
1644 NULLPtr}, sectionName<ProtocolSection>());
1645 if (!EmittedProtocolRef)
1646 createNullGlobal(
".objc_null_protocol_ref", {NULLPtr},
1647 sectionName<ProtocolReferenceSection>());
1648 if (ClassAliases.empty())
1649 createNullGlobal(
".objc_null_class_alias", { NULLPtr, NULLPtr },
1650 sectionName<ClassAliasSection>());
1651 if (ConstantStrings.empty()) {
1652 auto i32Zero = llvm::ConstantInt::get(Int32Ty, 0);
1653 createNullGlobal(
".objc_null_constant_string", { NULLPtr, i32Zero,
1654 i32Zero, i32Zero, i32Zero, NULLPtr },
1655 sectionName<ConstantStringSection>());
1658 ConstantStrings.clear();
1662 if (EarlyInitList.size() > 0) {
1663 auto *
Init = llvm::Function::Create(llvm::FunctionType::get(CGM.
VoidTy,
1664 {}), llvm::GlobalValue::InternalLinkage,
".objc_early_init",
1666 llvm::IRBuilder<>
b(llvm::BasicBlock::Create(CGM.
getLLVMContext(),
"entry",
1668 for (
const auto &lateInit : EarlyInitList) {
1669 auto *global = TheModule.getGlobalVariable(lateInit.first);
1671 llvm::GlobalVariable *GV = lateInit.second.first;
1672 b.CreateAlignedStore(
1674 b.CreateStructGEP(GV->getValueType(), GV, lateInit.second.second),
1681 auto *InitVar =
new llvm::GlobalVariable(CGM.
getModule(),
Init->getType(),
1682 true, llvm::GlobalValue::InternalLinkage,
1683 Init,
".objc_early_init_ptr");
1684 InitVar->setSection(
".CRT$XCLb");
1693 std::string TypeEncoding;
1695 TypeEncoding = GetSymbolNameForTypeEncoding(TypeEncoding);
1696 const std::string Name =
"__objc_ivar_offset_" +
ID->getNameAsString()
1705 const std::string Name =
1706 GetIVarOffsetVariableName(ContainingInterface, Ivar);
1707 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
1708 if (!IvarOffsetPointer) {
1709 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule, IntTy,
false,
1710 llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
1716 llvm::Value *Offset =
1718 if (Offset->getType() != PtrDiffTy)
1719 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
1724 bool IsCOFF = CGM.
getTriple().isOSBinFormatCOFF();
1730 auto *classNameConstant = MakeConstantString(className);
1733 auto metaclassFields = builder.beginStruct();
1735 metaclassFields.addNullPointer(PtrTy);
1737 metaclassFields.addNullPointer(PtrTy);
1739 metaclassFields.add(classNameConstant);
1741 metaclassFields.addInt(LongTy, 0);
1744 metaclassFields.addInt(LongTy, ClassFlags::ClassFlagMeta);
1748 metaclassFields.addInt(LongTy, 0);
1750 metaclassFields.addNullPointer(PtrTy);
1755 metaclassFields.addNullPointer(PtrTy);
1760 metaclassFields.add(
1761 GenerateMethodList(className,
"", ClassMethods,
true));
1764 metaclassFields.addNullPointer(PtrTy);
1766 metaclassFields.addNullPointer(PtrTy);
1768 metaclassFields.addNullPointer(PtrTy);
1770 metaclassFields.addNullPointer(PtrTy);
1772 metaclassFields.addNullPointer(PtrTy);
1774 metaclassFields.addNullPointer(PtrTy);
1776 metaclassFields.addNullPointer(PtrTy);
1778 metaclassFields.addInt(LongTy, 0);
1780 metaclassFields.add(GeneratePropertyList(OID, classDecl,
true));
1782 auto *metaclass = metaclassFields.finishAndCreateGlobal(
1783 ManglePublicSymbol(
"OBJC_METACLASS_") + className,
1786 auto classFields = builder.beginStruct();
1788 classFields.add(metaclass);
1793 llvm::Constant *SuperClass =
nullptr;
1794 if (SuperClassDecl) {
1795 auto SuperClassName = SymbolForClass(SuperClassDecl->
getNameAsString());
1796 SuperClass = TheModule.getNamedGlobal(SuperClassName);
1799 SuperClass =
new llvm::GlobalVariable(TheModule, PtrTy,
false,
1800 llvm::GlobalValue::ExternalLinkage,
nullptr, SuperClassName);
1802 auto Storage = llvm::GlobalValue::DefaultStorageClass;
1803 if (SuperClassDecl->
hasAttr<DLLImportAttr>())
1804 Storage = llvm::GlobalValue::DLLImportStorageClass;
1805 else if (SuperClassDecl->
hasAttr<DLLExportAttr>())
1806 Storage = llvm::GlobalValue::DLLExportStorageClass;
1808 cast<llvm::GlobalValue>(SuperClass)->setDLLStorageClass(Storage);
1812 classFields.add(SuperClass);
1814 classFields.addNullPointer(PtrTy);
1816 classFields.addNullPointer(PtrTy);
1818 classFields.add(classNameConstant);
1820 classFields.addInt(LongTy, 0);
1823 classFields.addInt(LongTy, 0);
1825 int superInstanceSize = !SuperClassDecl ? 0 :
1829 classFields.addInt(LongTy,
1831 superInstanceSize));
1834 classFields.addNullPointer(PtrTy);
1839 const llvm::DataLayout &DL = TheModule.getDataLayout();
1842 auto ivarListBuilder =
b.beginStruct();
1844 ivarListBuilder.addInt(IntTy, ivar_count);
1846 llvm::StructType *ObjCIvarTy = llvm::StructType::get(
1852 ivarListBuilder.addInt(SizeTy, DL.getTypeSizeInBits(ObjCIvarTy) /
1855 auto ivarArrayBuilder = ivarListBuilder.beginArray();
1858 auto ivarTy = IVD->getType();
1859 auto ivarBuilder = ivarArrayBuilder.beginStruct();
1861 ivarBuilder.add(MakeConstantString(IVD->getNameAsString()));
1863 std::string TypeStr;
1866 ivarBuilder.add(MakeConstantString(TypeStr));
1868 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
1869 uint64_t Offset = BaseOffset - superInstanceSize;
1870 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
1871 std::string OffsetName = GetIVarOffsetVariableName(classDecl, IVD);
1872 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
1874 OffsetVar->setInitializer(OffsetValue);
1876 OffsetVar =
new llvm::GlobalVariable(TheModule, IntTy,
1877 false, llvm::GlobalValue::ExternalLinkage,
1878 OffsetValue, OffsetName);
1879 auto ivarVisibility =
1883 llvm::GlobalValue::HiddenVisibility :
1884 llvm::GlobalValue::DefaultVisibility;
1885 OffsetVar->setVisibility(ivarVisibility);
1886 if (ivarVisibility != llvm::GlobalValue::HiddenVisibility)
1888 ivarBuilder.add(OffsetVar);
1890 ivarBuilder.addInt(Int32Ty,
1901 ivarBuilder.addInt(Int32Ty,
1902 (align << 3) | (1<<2) |
1903 FlagsForOwnership(ivarTy.getQualifiers().getObjCLifetime()));
1904 ivarBuilder.finishAndAddTo(ivarArrayBuilder);
1906 ivarArrayBuilder.finishAndAddTo(ivarListBuilder);
1907 auto ivarList = ivarListBuilder.finishAndCreateGlobal(
".objc_ivar_list",
1909 llvm::GlobalValue::PrivateLinkage);
1910 classFields.add(ivarList);
1914 InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
1917 if (propImpl->getPropertyImplementation() ==
1920 if (OMD && OMD->hasBody())
1921 InstanceMethods.push_back(OMD);
1923 addIfExists(propImpl->getGetterMethodDecl());
1924 addIfExists(propImpl->getSetterMethodDecl());
1927 if (InstanceMethods.size() == 0)
1928 classFields.addNullPointer(PtrTy);
1931 GenerateMethodList(className,
"", InstanceMethods,
false));
1934 classFields.addNullPointer(PtrTy);
1936 classFields.addNullPointer(PtrTy);
1938 classFields.addNullPointer(PtrTy);
1940 classFields.addNullPointer(PtrTy);
1942 classFields.addNullPointer(PtrTy);
1944 auto RuntimeProtocols = GetRuntimeProtocolList(classDecl->
protocol_begin(),
1947 for (
const auto *I : RuntimeProtocols)
1948 Protocols.push_back(GenerateProtocolRef(I));
1950 if (Protocols.empty())
1951 classFields.addNullPointer(PtrTy);
1953 classFields.add(GenerateProtocolList(Protocols));
1955 classFields.addNullPointer(PtrTy);
1957 classFields.addInt(LongTy, 0);
1959 classFields.add(GeneratePropertyList(OID, classDecl));
1961 llvm::GlobalVariable *classStruct =
1962 classFields.finishAndCreateGlobal(SymbolForClass(className),
1965 auto *classRefSymbol = GetClassVar(className);
1966 classRefSymbol->setSection(sectionName<ClassReferenceSection>());
1967 classRefSymbol->setInitializer(classStruct);
1972 classStruct->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1973 cast<llvm::GlobalValue>(classRefSymbol)->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1977 std::pair<llvm::GlobalVariable*, int>
v{classStruct, 1};
1978 EarlyInitList.emplace_back(std::string(SuperClass->getName()),
1987 if (ClassPtrAlias) {
1988 ClassPtrAlias->replaceAllUsesWith(classStruct);
1989 ClassPtrAlias->eraseFromParent();
1990 ClassPtrAlias =
nullptr;
1992 if (
auto Placeholder =
1993 TheModule.getNamedGlobal(SymbolForClass(className)))
1994 if (Placeholder != classStruct) {
1995 Placeholder->replaceAllUsesWith(classStruct);
1996 Placeholder->eraseFromParent();
1997 classStruct->setName(SymbolForClass(className));
1999 if (MetaClassPtrAlias) {
2000 MetaClassPtrAlias->replaceAllUsesWith(metaclass);
2001 MetaClassPtrAlias->eraseFromParent();
2002 MetaClassPtrAlias =
nullptr;
2004 assert(classStruct->getName() == SymbolForClass(className));
2006 auto classInitRef =
new llvm::GlobalVariable(TheModule,
2007 classStruct->getType(),
false, llvm::GlobalValue::ExternalLinkage,
2008 classStruct, ManglePublicSymbol(
"OBJC_INIT_CLASS_") + className);
2009 classInitRef->setSection(sectionName<ClassSection>());
2012 EmittedClass =
true;
2015 CGObjCGNUstep2(
CodeGenModule &Mod) : CGObjCGNUstep(Mod, 10, 4, 2) {
2016 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
2017 PtrToObjCSuperTy, SelectorTy);
2018 SentInitializeFn.init(&CGM,
"objc_send_initialize",
2019 llvm::Type::getVoidTy(VMContext), IdTy);
2028 PropertyMetadataTy =
2030 { PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty });
2033 void GenerateDirectMethodPrologue(
CodeGenFunction &CGF, llvm::Function *Fn,
2037 bool ReceiverCanBeNull =
true;
2039 auto selfValue = Builder.CreateLoad(selfAddr);
2064 ReceiverCanBeNull = isWeakLinkedClass(OID);
2068 if (ReceiverCanBeNull) {
2069 llvm::BasicBlock *SelfIsNilBlock =
2071 llvm::BasicBlock *ContBlock =
2075 auto selfTy = cast<llvm::PointerType>(selfValue->getType());
2076 auto Zero = llvm::ConstantPointerNull::get(selfTy);
2078 Builder.CreateCondBr(Builder.CreateICmpEQ(selfValue, Zero),
2079 SelfIsNilBlock, ContBlock,
2080 MDHelper.createUnlikelyBranchWeights());
2086 Builder.SetInsertPoint(SelfIsNilBlock);
2087 if (!retTy->isVoidType()) {
2095 Builder.SetInsertPoint(ContBlock);
2101 llvm::StructType::get(PtrTy, PtrTy, PtrTy, LongTy, LongTy);
2108 llvm::Value *Val = Builder.CreateStructGEP(classStart, selfValue, 4);
2110 astContext.getTypeAlign(astContext.UnsignedLongTy));
2111 auto flags = Builder.CreateLoad(
Address{Val, LongTy, Align});
2112 auto isInitialized =
2113 Builder.CreateAnd(flags, ClassFlags::ClassFlagInitialized);
2114 llvm::BasicBlock *notInitializedBlock =
2116 llvm::BasicBlock *initializedBlock =
2118 Builder.CreateCondBr(Builder.CreateICmpEQ(isInitialized, Zeros[0]),
2119 notInitializedBlock, initializedBlock,
2120 MDHelper.createUnlikelyBranchWeights());
2122 Builder.SetInsertPoint(notInitializedBlock);
2124 Builder.CreateBr(initializedBlock);
2126 Builder.SetInsertPoint(initializedBlock);
2134 Builder.CreateStore(GetSelector(CGF, OMD),
2140const char *
const CGObjCGNUstep2::SectionsBaseNames[8] =
2147"__objc_protocol_refs",
2148"__objc_class_aliases",
2149"__objc_constant_string"
2152const char *
const CGObjCGNUstep2::PECOFFSectionsBaseNames[8] =
2165class CGObjCObjFW:
public CGObjCGNU {
2169 LazyRuntimeFunction MsgLookupFn;
2172 LazyRuntimeFunction MsgLookupFnSRet;
2176 LazyRuntimeFunction MsgLookupSuperFn, MsgLookupSuperFnSRet;
2179 llvm::Value *cmd, llvm::MDNode *node,
2180 MessageSendInfo &MSI)
override {
2182 llvm::Value *args[] = {
2183 EnforceType(Builder, Receiver, IdTy),
2184 EnforceType(Builder, cmd, SelectorTy) };
2186 llvm::CallBase *imp;
2192 imp->setMetadata(msgSendMDKind, node);
2197 llvm::Value *cmd, MessageSendInfo &MSI)
override {
2199 llvm::Value *lookupArgs[] = {
2200 EnforceType(Builder, ObjCSuper.
emitRawPointer(CGF), PtrToObjCSuperTy),
2210 llvm::Value *GetClassNamed(
CodeGenFunction &CGF,
const std::string &Name,
2211 bool isWeak)
override {
2213 return CGObjCGNU::GetClassNamed(CGF, Name, isWeak);
2216 std::string SymbolName =
"_OBJC_CLASS_" + Name;
2217 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(SymbolName);
2219 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
2220 llvm::GlobalValue::ExternalLinkage,
2221 nullptr, SymbolName);
2228 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
2229 MsgLookupFnSRet.init(&CGM,
"objc_msg_lookup_stret", IMPTy, IdTy,
2232 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
2233 PtrToObjCSuperTy, SelectorTy);
2234 MsgLookupSuperFnSRet.init(&CGM,
"objc_msg_lookup_super_stret", IMPTy,
2235 PtrToObjCSuperTy, SelectorTy);
2243void CGObjCGNU::EmitClassRef(
const std::string &className) {
2244 std::string symbolRef =
"__objc_class_ref_" + className;
2246 if (TheModule.getGlobalVariable(symbolRef))
2248 std::string symbolName =
"__objc_class_name_" + className;
2249 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
2251 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
2252 llvm::GlobalValue::ExternalLinkage,
2253 nullptr, symbolName);
2255 new llvm::GlobalVariable(TheModule, ClassSymbol->getType(),
true,
2256 llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef);
2259CGObjCGNU::CGObjCGNU(
CodeGenModule &cgm,
unsigned runtimeABIVersion,
2260 unsigned protocolClassVersion,
unsigned classABI)
2262 VMContext(cgm.getLLVMContext()), ClassPtrAlias(nullptr),
2263 MetaClassPtrAlias(nullptr), RuntimeVersion(runtimeABIVersion),
2264 ProtocolVersion(protocolClassVersion), ClassABIVersion(classABI) {
2266 msgSendMDKind = VMContext.getMDKindID(
"GNUObjCMessageSend");
2274 IntTy = cast<llvm::IntegerType>(
2276 LongTy = cast<llvm::IntegerType>(
2278 SizeTy = cast<llvm::IntegerType>(
2280 PtrDiffTy = cast<llvm::IntegerType>(
2284 Int8Ty = llvm::Type::getInt8Ty(VMContext);
2286 PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
2287 ProtocolPtrTy = llvm::PointerType::getUnqual(
2290 Zeros[0] = llvm::ConstantInt::get(LongTy, 0);
2291 Zeros[1] = Zeros[0];
2292 NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty);
2296 SelectorTy = PtrToInt8Ty;
2297 SelectorElemTy = Int8Ty;
2303 PtrToIntTy = llvm::PointerType::getUnqual(IntTy);
2304 PtrTy = PtrToInt8Ty;
2306 Int32Ty = llvm::Type::getInt32Ty(VMContext);
2307 Int64Ty = llvm::Type::getInt64Ty(VMContext);
2310 CGM.
getDataLayout().getPointerSizeInBits() == 32 ? Int32Ty : Int64Ty;
2324 PtrToIdTy = llvm::PointerType::getUnqual(IdTy);
2325 ProtocolTy = llvm::StructType::get(IdTy,
2347 PropertyMetadataTy = llvm::StructType::get(CGM.
getLLVMContext(), {
2348 PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty,
2349 PtrToInt8Ty, PtrToInt8Ty });
2351 ObjCSuperTy = llvm::StructType::get(IdTy, IdTy);
2352 PtrToObjCSuperTy = llvm::PointerType::getUnqual(ObjCSuperTy);
2354 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
2357 ExceptionThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy);
2358 ExceptionReThrowFn.init(&CGM,
2359 usesCxxExceptions ?
"objc_exception_rethrow"
2360 :
"objc_exception_throw",
2363 SyncEnterFn.init(&CGM,
"objc_sync_enter", IntTy, IdTy);
2365 SyncExitFn.init(&CGM,
"objc_sync_exit", IntTy, IdTy);
2368 EnumerationMutationFn.init(&CGM,
"objc_enumerationMutation", VoidTy, IdTy);
2371 GetPropertyFn.init(&CGM,
"objc_getProperty", IdTy, IdTy, SelectorTy,
2374 SetPropertyFn.init(&CGM,
"objc_setProperty", VoidTy, IdTy, SelectorTy,
2375 PtrDiffTy, IdTy, BoolTy, BoolTy);
2377 GetStructPropertyFn.init(&CGM,
"objc_getPropertyStruct", VoidTy, PtrTy, PtrTy,
2378 PtrDiffTy, BoolTy, BoolTy);
2380 SetStructPropertyFn.init(&CGM,
"objc_setPropertyStruct", VoidTy, PtrTy, PtrTy,
2381 PtrDiffTy, BoolTy, BoolTy);
2384 llvm::Type *IMPArgs[] = { IdTy, SelectorTy };
2385 IMPTy = llvm::PointerType::getUnqual(llvm::FunctionType::get(IdTy, IMPArgs,
2389 if ((Opts.getGC() != LangOptions::NonGC) || Opts.ObjCAutoRefCount)
2390 RuntimeVersion = 10;
2393 if (Opts.getGC() != LangOptions::NonGC) {
2405 IvarAssignFn.init(&CGM,
"objc_assign_ivar", IdTy, IdTy, IdTy, PtrDiffTy);
2407 StrongCastAssignFn.init(&CGM,
"objc_assign_strongCast", IdTy, IdTy,
2410 GlobalAssignFn.init(&CGM,
"objc_assign_global", IdTy, IdTy, PtrToIdTy);
2412 WeakAssignFn.init(&CGM,
"objc_assign_weak", IdTy, IdTy, PtrToIdTy);
2414 WeakReadFn.init(&CGM,
"objc_read_weak", IdTy, PtrToIdTy);
2416 MemMoveFn.init(&CGM,
"objc_memmove_collectable", PtrTy, PtrTy, PtrTy,
2422 const std::string &Name,
bool isWeak) {
2423 llvm::Constant *ClassName = MakeConstantString(Name);
2435 llvm::FunctionType::get(IdTy, PtrToInt8Ty,
true),
"objc_lookup_class");
2445 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value))
2450llvm::Value *CGObjCGNU::EmitNSAutoreleasePoolClassRef(
CodeGenFunction &CGF) {
2451 auto *
Value = GetClassNamed(CGF,
"NSAutoreleasePool",
false);
2452 if (CGM.
getTriple().isOSBinFormatCOFF()) {
2453 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value)) {
2459 for (
const auto *Result : DC->
lookup(&II))
2460 if ((VD = dyn_cast<VarDecl>(Result)))
2470 const std::string &TypeEncoding) {
2472 llvm::GlobalAlias *SelValue =
nullptr;
2475 e = Types.end() ; i!=e ; i++) {
2476 if (i->first == TypeEncoding) {
2477 SelValue = i->second;
2482 SelValue = llvm::GlobalAlias::create(SelectorElemTy, 0,
2483 llvm::GlobalValue::PrivateLinkage,
2486 Types.emplace_back(TypeEncoding, SelValue);
2493 llvm::Value *SelValue = GetSelector(CGF, Sel);
2504 return GetTypedSelector(CGF, Sel, std::string());
2510 return GetTypedSelector(CGF, Method->
getSelector(), SelTypes);
2513llvm::Constant *CGObjCGNU::GetEHType(
QualType T) {
2520 return MakeConstantString(
"@id");
2528 assert(OPT &&
"Invalid @catch type.");
2530 assert(IDecl &&
"Invalid @catch type.");
2534llvm::Constant *CGObjCGNUstep::GetEHType(
QualType T) {
2535 if (usesSEHExceptions)
2538 if (!CGM.
getLangOpts().CPlusPlus && !usesCxxExceptions)
2539 return CGObjCGNU::GetEHType(
T);
2547 llvm::Constant *IDEHType =
2548 CGM.
getModule().getGlobalVariable(
"__objc_id_type_info");
2551 new llvm::GlobalVariable(CGM.
getModule(), PtrToInt8Ty,
2553 llvm::GlobalValue::ExternalLinkage,
2554 nullptr,
"__objc_id_type_info");
2560 assert(PT &&
"Invalid @catch type.");
2562 assert(IT &&
"Invalid @catch type.");
2563 std::string className =
2566 std::string typeinfoName =
"__objc_eh_typeinfo_" + className;
2569 if (llvm::Constant *typeinfo = TheModule.getGlobalVariable(typeinfoName))
2577 const char *vtableName =
"_ZTVN7gnustep7libobjc22__objc_class_type_infoE";
2578 auto *Vtable = TheModule.getGlobalVariable(vtableName);
2580 Vtable =
new llvm::GlobalVariable(TheModule, PtrToInt8Ty,
true,
2581 llvm::GlobalValue::ExternalLinkage,
2582 nullptr, vtableName);
2584 llvm::Constant *Two = llvm::ConstantInt::get(IntTy, 2);
2586 llvm::ConstantExpr::getGetElementPtr(Vtable->getValueType(), Vtable, Two);
2588 llvm::Constant *typeName =
2589 ExportUniqueString(className,
"__objc_eh_typename_");
2592 auto fields = builder.beginStruct();
2593 fields.add(BVtable);
2594 fields.add(typeName);
2595 llvm::Constant *TI =
2596 fields.finishAndCreateGlobal(
"__objc_eh_typeinfo_" + className,
2599 llvm::GlobalValue::LinkOnceODRLinkage);
2606 std::string Str = SL->
getString().str();
2610 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
2611 if (old != ObjCStrings.end())
2616 if (StringClass.empty()) StringClass =
"NSConstantString";
2618 std::string Sym =
"_OBJC_CLASS_";
2621 llvm::Constant *
isa = TheModule.getNamedGlobal(Sym);
2624 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
2625 llvm::GlobalValue::ExternalWeakLinkage,
2629 auto Fields = Builder.beginStruct();
2631 Fields.add(MakeConstantString(Str));
2632 Fields.addInt(IntTy, Str.size());
2634 ObjCStrings[Str] = ObjCStr;
2635 ConstantStrings.push_back(ObjCStr);
2648 bool isCategoryImpl,
2649 llvm::Value *Receiver,
2650 bool IsClassMessage,
2654 if (CGM.
getLangOpts().getGC() == LangOptions::GCOnly) {
2655 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2659 if (Sel == ReleaseSel) {
2664 llvm::Value *cmd = GetSelector(CGF, Sel);
2667 ActualArgs.
add(
RValue::get(EnforceType(Builder, Receiver, IdTy)), ASTIdTy);
2671 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2673 llvm::Value *ReceiverClass =
nullptr;
2676 ReceiverClass = GetClassNamed(CGF,
2677 Class->getSuperClass()->getNameAsString(),
false);
2678 if (IsClassMessage) {
2680 ReceiverClass = Builder.CreateBitCast(ReceiverClass,
2681 llvm::PointerType::getUnqual(IdTy));
2683 Builder.CreateAlignedLoad(IdTy, ReceiverClass, CGF.
getPointerAlign());
2685 ReceiverClass = EnforceType(Builder, ReceiverClass, IdTy);
2687 if (isCategoryImpl) {
2688 llvm::FunctionCallee classLookupFunction =
nullptr;
2689 if (IsClassMessage) {
2691 IdTy, PtrTy,
true),
"objc_get_meta_class");
2694 IdTy, PtrTy,
true),
"objc_get_class");
2696 ReceiverClass = Builder.CreateCall(classLookupFunction,
2697 MakeConstantString(
Class->getNameAsString()));
2704 if (IsClassMessage) {
2705 if (!MetaClassPtrAlias) {
2706 MetaClassPtrAlias = llvm::GlobalAlias::create(
2707 IdElemTy, 0, llvm::GlobalValue::InternalLinkage,
2708 ".objc_metaclass_ref" +
Class->getNameAsString(), &TheModule);
2710 ReceiverClass = MetaClassPtrAlias;
2712 if (!ClassPtrAlias) {
2713 ClassPtrAlias = llvm::GlobalAlias::create(
2714 IdElemTy, 0, llvm::GlobalValue::InternalLinkage,
2715 ".objc_class_ref" +
Class->getNameAsString(), &TheModule);
2717 ReceiverClass = ClassPtrAlias;
2721 llvm::Type *CastTy = llvm::StructType::get(IdTy, IdTy);
2722 ReceiverClass = Builder.CreateBitCast(ReceiverClass,
2723 llvm::PointerType::getUnqual(CastTy));
2725 ReceiverClass = Builder.CreateStructGEP(CastTy, ReceiverClass, 1);
2728 Builder.CreateAlignedLoad(IdTy, ReceiverClass, CGF.
getPointerAlign());
2731 llvm::StructType *ObjCSuperTy =
2732 llvm::StructType::get(Receiver->getType(), IdTy);
2737 Builder.CreateStore(Receiver, Builder.CreateStructGEP(ObjCSuper, 0));
2738 Builder.CreateStore(ReceiverClass, Builder.CreateStructGEP(ObjCSuper, 1));
2741 llvm::Value *imp = LookupIMPSuper(CGF, ObjCSuper, cmd, MSI);
2742 imp = EnforceType(Builder, imp, MSI.MessengerType);
2744 llvm::Metadata *impMD[] = {
2745 llvm::MDString::get(VMContext, Sel.
getAsString()),
2746 llvm::MDString::get(VMContext,
Class->getSuperClass()->getNameAsString()),
2747 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2748 llvm::Type::getInt1Ty(VMContext), IsClassMessage))};
2749 llvm::MDNode *
node = llvm::MDNode::get(VMContext, impMD);
2753 llvm::CallBase *call;
2754 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2755 call->setMetadata(msgSendMDKind, node);
2765 llvm::Value *Receiver,
2772 if (CGM.
getLangOpts().getGC() == LangOptions::GCOnly) {
2773 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2777 if (Sel == ReleaseSel) {
2788 cmd = GetSelector(CGF, Method);
2790 cmd = GetSelector(CGF, Sel);
2791 cmd = EnforceType(Builder, cmd, SelectorTy);
2794 Receiver = EnforceType(Builder, Receiver, IdTy);
2796 llvm::Metadata *impMD[] = {
2797 llvm::MDString::get(VMContext, Sel.
getAsString()),
2798 llvm::MDString::get(VMContext, Class ?
Class->getNameAsString() :
""),
2799 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2800 llvm::Type::getInt1Ty(VMContext), Class !=
nullptr))};
2801 llvm::MDNode *
node = llvm::MDNode::get(VMContext, impMD);
2809 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2830 bool hasParamDestroyedInCallee =
false;
2831 bool requiresExplicitZeroResult =
false;
2832 bool requiresNilReceiverCheck = [&] {
2834 if (!canMessageReceiverBeNull(CGF, Method,
false,
2840 hasParamDestroyedInCallee =
true;
2861 requiresExplicitZeroResult = !isDirect;
2865 return hasParamDestroyedInCallee || requiresExplicitZeroResult;
2871 bool requiresExplicitAggZeroing =
2875 llvm::BasicBlock *continueBB =
nullptr;
2877 llvm::BasicBlock *nilPathBB =
nullptr;
2879 llvm::BasicBlock *nilCleanupBB =
nullptr;
2882 if (requiresNilReceiverCheck) {
2889 if (requiresExplicitAggZeroing || hasParamDestroyedInCallee) {
2892 nilPathBB = Builder.GetInsertBlock();
2895 llvm::Value *isNil = Builder.CreateICmpEQ(Receiver,
2896 llvm::Constant::getNullValue(Receiver->getType()));
2897 Builder.CreateCondBr(isNil, nilCleanupBB ? nilCleanupBB : continueBB,
2914 imp = LookupIMP(CGF, Receiver, cmd, node, MSI);
2918 StringRef
name =
"objc_msgSend";
2920 name =
"objc_msgSend_fpret";
2922 name =
"objc_msgSend_stret";
2926 bool shouldCheckForInReg =
2930 .isWindowsMSVCEnvironment() &&
2933 name =
"objc_msgSend_stret2";
2946 imp = EnforceType(Builder, imp, MSI.MessengerType);
2948 llvm::CallBase *call;
2950 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2952 call->setMetadata(msgSendMDKind, node);
2954 if (requiresNilReceiverCheck) {
2955 llvm::BasicBlock *nonNilPathBB = CGF.
Builder.GetInsertBlock();
2956 CGF.
Builder.CreateBr(continueBB);
2962 if (hasParamDestroyedInCallee) {
2963 destroyCalleeDestroyedArguments(CGF, Method, CallArgs);
2966 if (requiresExplicitAggZeroing) {
2972 nilPathBB = CGF.
Builder.GetInsertBlock();
2973 CGF.
Builder.CreateBr(continueBB);
2981 llvm::PHINode *phi = Builder.CreatePHI(
v->getType(), 2);
2982 phi->addIncoming(
v, nonNilPathBB);
2990 llvm::PHINode *phi = Builder.CreatePHI(
v.first->getType(), 2);
2991 phi->addIncoming(
v.first, nonNilPathBB);
2992 phi->addIncoming(llvm::Constant::getNullValue(
v.first->getType()),
2994 llvm::PHINode *phi2 = Builder.CreatePHI(
v.second->getType(), 2);
2995 phi2->addIncoming(
v.second, nonNilPathBB);
2996 phi2->addIncoming(llvm::Constant::getNullValue(
v.second->getType()),
3006llvm::Constant *CGObjCGNU::
3007GenerateMethodList(StringRef ClassName,
3008 StringRef CategoryName,
3010 bool isClassMethodList) {
3011 if (Methods.empty())
3016 auto MethodList = Builder.beginStruct();
3017 MethodList.addNullPointer(CGM.
Int8PtrTy);
3018 MethodList.addInt(Int32Ty, Methods.size());
3021 llvm::StructType *ObjCMethodTy =
3030 const llvm::DataLayout &DL = TheModule.getDataLayout();
3031 MethodList.addInt(SizeTy, DL.getTypeSizeInBits(ObjCMethodTy) /
3047 auto MethodArray = MethodList.beginArray();
3049 for (
const auto *OMD : Methods) {
3050 llvm::Constant *FnPtr =
3051 TheModule.getFunction(getSymbolNameForMethod(OMD));
3052 assert(FnPtr &&
"Can't generate metadata for method that doesn't exist");
3053 auto Method = MethodArray.beginStruct(ObjCMethodTy);
3064 Method.finishAndAddTo(MethodArray);
3066 MethodArray.finishAndAddTo(MethodList);
3069 return MethodList.finishAndCreateGlobal(
".objc_method_list",
3074llvm::Constant *CGObjCGNU::
3080 if (IvarNames.empty())
3086 auto IvarList = Builder.beginStruct();
3087 IvarList.addInt(IntTy, (
int)IvarNames.size());
3090 llvm::StructType *ObjCIvarTy =
3091 llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, IntTy);
3094 auto Ivars = IvarList.beginArray(ObjCIvarTy);
3095 for (
unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {
3096 auto Ivar = Ivars.beginStruct(ObjCIvarTy);
3097 Ivar.
add(IvarNames[i]);
3098 Ivar.
add(IvarTypes[i]);
3099 Ivar.
add(IvarOffsets[i]);
3100 Ivar.finishAndAddTo(Ivars);
3102 Ivars.finishAndAddTo(IvarList);
3105 return IvarList.finishAndCreateGlobal(
".objc_ivar_list",
3110llvm::Constant *CGObjCGNU::GenerateClassStructure(
3111 llvm::Constant *MetaClass,
3112 llvm::Constant *SuperClass,
3115 llvm::Constant *Version,
3116 llvm::Constant *InstanceSize,
3117 llvm::Constant *IVars,
3118 llvm::Constant *Methods,
3119 llvm::Constant *Protocols,
3120 llvm::Constant *IvarOffsets,
3121 llvm::Constant *Properties,
3122 llvm::Constant *StrongIvarBitmap,
3123 llvm::Constant *WeakIvarBitmap,
3132 llvm::StructType *ClassTy = llvm::StructType::get(
3149 IvarOffsets->getType(),
3150 Properties->getType(),
3156 auto Elements = Builder.beginStruct(ClassTy);
3161 Elements.add(MetaClass);
3163 Elements.add(SuperClass);
3165 Elements.add(MakeConstantString(Name,
".class_name"));
3167 Elements.addInt(LongTy, 0);
3169 Elements.addInt(LongTy, info);
3172 const llvm::DataLayout &DL = TheModule.getDataLayout();
3173 Elements.addInt(LongTy, DL.getTypeSizeInBits(ClassTy) /
3176 Elements.add(InstanceSize);
3178 Elements.add(IVars);
3180 Elements.add(Methods);
3183 Elements.add(NULLPtr);
3185 Elements.add(NULLPtr);
3187 Elements.add(NULLPtr);
3189 Elements.add(Protocols);
3191 Elements.add(NULLPtr);
3193 Elements.addInt(LongTy, ClassABIVersion);
3195 Elements.add(IvarOffsets);
3197 Elements.add(Properties);
3199 Elements.add(StrongIvarBitmap);
3201 Elements.add(WeakIvarBitmap);
3206 std::string ClassSym((isMeta ?
"_OBJC_METACLASS_":
"_OBJC_CLASS_") +
3208 llvm::GlobalVariable *ClassRef = TheModule.getNamedGlobal(ClassSym);
3209 llvm::Constant *
Class =
3210 Elements.finishAndCreateGlobal(ClassSym, CGM.
getPointerAlign(),
false,
3211 llvm::GlobalValue::ExternalLinkage);
3213 ClassRef->replaceAllUsesWith(Class);
3214 ClassRef->removeFromParent();
3215 Class->setName(ClassSym);
3220llvm::Constant *CGObjCGNU::
3223 llvm::StructType *ObjCMethodDescTy =
3224 llvm::StructType::get(CGM.
getLLVMContext(), { PtrToInt8Ty, PtrToInt8Ty });
3227 auto MethodList = Builder.beginStruct();
3228 MethodList.addInt(IntTy, Methods.size());
3229 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
3230 for (
auto *M : Methods) {
3231 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
3232 Method.
add(MakeConstantString(M->getSelector().getAsString()));
3234 Method.finishAndAddTo(MethodArray);
3236 MethodArray.finishAndAddTo(MethodList);
3237 return MethodList.finishAndCreateGlobal(
".objc_method_list",
3246 auto ProtocolList = Builder.beginStruct();
3247 ProtocolList.add(NULLPtr);
3248 ProtocolList.addInt(LongTy, Protocols.size());
3250 auto Elements = ProtocolList.beginArray(PtrToInt8Ty);
3251 for (
const std::string *iter = Protocols.begin(), *endIter = Protocols.end();
3252 iter != endIter ; iter++) {
3253 llvm::Constant *protocol =
nullptr;
3254 llvm::StringMap<llvm::Constant*>::iterator value =
3255 ExistingProtocols.find(*iter);
3256 if (value == ExistingProtocols.end()) {
3257 protocol = GenerateEmptyProtocol(*iter);
3259 protocol = value->getValue();
3261 Elements.add(protocol);
3263 Elements.finishAndAddTo(ProtocolList);
3264 return ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
3270 auto protocol = GenerateProtocolRef(PD);
3273 return CGF.
Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(
T));
3276llvm::Constant *CGObjCGNU::GenerateProtocolRef(
const ObjCProtocolDecl *PD) {
3279 GenerateProtocol(PD);
3280 assert(protocol &&
"Unknown protocol");
3285CGObjCGNU::GenerateEmptyProtocol(StringRef ProtocolName) {
3286 llvm::Constant *ProtocolList = GenerateProtocolList({});
3287 llvm::Constant *MethodList = GenerateProtocolMethodList({});
3291 auto Elements = Builder.beginStruct();
3295 Elements.add(llvm::ConstantExpr::getIntToPtr(
3296 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3298 Elements.add(MakeConstantString(ProtocolName,
".objc_protocol_name"));
3299 Elements.add(ProtocolList);
3300 Elements.add(MethodList);
3301 Elements.add(MethodList);
3302 Elements.add(MethodList);
3303 Elements.add(MethodList);
3304 Elements.add(NULLPtr);
3305 Elements.add(NULLPtr);
3306 return Elements.finishAndCreateGlobal(SymbolForProtocol(ProtocolName),
3322 Protocols.push_back(PI->getNameAsString());
3326 if (I->isOptional())
3327 OptionalInstanceMethods.push_back(I);
3329 InstanceMethods.push_back(I);
3334 if (I->isOptional())
3335 OptionalClassMethods.push_back(I);
3337 ClassMethods.push_back(I);
3339 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
3340 llvm::Constant *InstanceMethodList =
3341 GenerateProtocolMethodList(InstanceMethods);
3342 llvm::Constant *ClassMethodList =
3343 GenerateProtocolMethodList(ClassMethods);
3344 llvm::Constant *OptionalInstanceMethodList =
3345 GenerateProtocolMethodList(OptionalInstanceMethods);
3346 llvm::Constant *OptionalClassMethodList =
3347 GenerateProtocolMethodList(OptionalClassMethods);
3355 llvm::Constant *PropertyList =
3356 GeneratePropertyList(
nullptr, PD,
false,
false);
3357 llvm::Constant *OptionalPropertyList =
3358 GeneratePropertyList(
nullptr, PD,
false,
true);
3365 auto Elements = Builder.beginStruct();
3367 llvm::ConstantExpr::getIntToPtr(
3368 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3369 Elements.add(MakeConstantString(ProtocolName));
3370 Elements.add(ProtocolList);
3371 Elements.add(InstanceMethodList);
3372 Elements.add(ClassMethodList);
3373 Elements.add(OptionalInstanceMethodList);
3374 Elements.add(OptionalClassMethodList);
3375 Elements.add(PropertyList);
3376 Elements.add(OptionalPropertyList);
3377 ExistingProtocols[ProtocolName] =
3378 Elements.finishAndCreateGlobal(
".objc_protocol", CGM.
getPointerAlign());
3380void CGObjCGNU::GenerateProtocolHolderCategory() {
3384 auto Elements = Builder.beginStruct();
3386 const std::string ClassName =
"__ObjC_Protocol_Holder_Ugly_Hack";
3387 const std::string CategoryName =
"AnotherHack";
3388 Elements.add(MakeConstantString(CategoryName));
3389 Elements.add(MakeConstantString(ClassName));
3391 Elements.add(GenerateMethodList(ClassName, CategoryName, {},
false));
3393 Elements.add(GenerateMethodList(ClassName, CategoryName, {},
true));
3397 auto ProtocolList = ProtocolListBuilder.beginStruct();
3398 ProtocolList.add(NULLPtr);
3399 ProtocolList.addInt(LongTy, ExistingProtocols.size());
3400 auto ProtocolElements = ProtocolList.beginArray(PtrTy);
3401 for (
auto iter = ExistingProtocols.begin(), endIter = ExistingProtocols.end();
3402 iter != endIter ; iter++) {
3403 ProtocolElements.add(iter->getValue());
3405 ProtocolElements.finishAndAddTo(ProtocolList);
3406 Elements.add(ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
3408 Categories.push_back(
3424 int bitCount = bits.size();
3426 if (bitCount < ptrBits) {
3428 for (
int i=0 ; i<bitCount ; ++i) {
3429 if (bits[i]) val |= 1ULL<<(i+1);
3431 return llvm::ConstantInt::get(IntPtrTy, val);
3435 while (
v < bitCount) {
3437 for (
int i=0 ; (i<32) && (
v<bitCount) ; ++i) {
3438 if (bits[
v]) word |= 1<<i;
3441 values.push_back(llvm::ConstantInt::get(Int32Ty, word));
3445 auto fields = builder.beginStruct();
3446 fields.addInt(Int32Ty, values.size());
3447 auto array = fields.beginArray();
3448 for (
auto *
v : values) array.add(
v);
3449 array.finishAndAddTo(fields);
3451 llvm::Constant *GS =
3453 llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy);
3457llvm::Constant *CGObjCGNU::GenerateCategoryProtocolList(
const
3460 const auto RuntimeProtos =
3461 GetRuntimeProtocolList(RefPro.begin(), RefPro.end());
3463 for (
const auto *PD : RuntimeProtos)
3465 return GenerateProtocolList(Protocols);
3470 std::string ClassName =
Class->getNameAsString();
3477 auto Elements = Builder.beginStruct();
3478 Elements.add(MakeConstantString(CategoryName));
3479 Elements.add(MakeConstantString(ClassName));
3482 InstanceMethods.insert(InstanceMethods.begin(), OCD->
instmeth_begin(),
3485 GenerateMethodList(ClassName, CategoryName, InstanceMethods,
false));
3492 Elements.add(GenerateMethodList(ClassName, CategoryName, ClassMethods,
true));
3495 Elements.add(GenerateCategoryProtocolList(CatDecl));
3501 Elements.add(GeneratePropertyList(OCD,
Category,
false));
3503 Elements.add(GeneratePropertyList(OCD,
Category,
true));
3505 Elements.addNullPointer(PtrTy);
3506 Elements.addNullPointer(PtrTy);
3510 Categories.push_back(Elements.finishAndCreateGlobal(
3511 std::string(
".objc_category_") + ClassName + CategoryName,
3515llvm::Constant *CGObjCGNU::GeneratePropertyList(
const Decl *Container,
3517 bool isClassProperty,
3518 bool protocolOptionalProperties) {
3522 bool isProtocol = isa<ObjCProtocolDecl>(OCD);
3525 std::function<void(
const ObjCProtocolDecl *Proto)> collectProtocolProperties
3527 for (
const auto *
P : Proto->protocols())
3528 collectProtocolProperties(
P);
3529 for (
const auto *PD : Proto->properties()) {
3530 if (isClassProperty != PD->isClassProperty())
3538 Properties.push_back(PD);
3544 for (
auto *PD : ClassExt->properties()) {
3545 if (isClassProperty != PD->isClassProperty())
3548 Properties.push_back(PD);
3552 if (isClassProperty != PD->isClassProperty())
3556 if (isProtocol && (protocolOptionalProperties != PD->isOptional()))
3563 Properties.push_back(PD);
3568 collectProtocolProperties(
P);
3570 for (
const auto *
P : CD->protocols())
3571 collectProtocolProperties(
P);
3573 auto numProperties = Properties.size();
3575 if (numProperties == 0)
3579 auto propertyList = builder.beginStruct();
3580 auto properties = PushPropertyListHeader(propertyList, numProperties);
3584 for (
auto *property : Properties) {
3585 bool isSynthesized =
false;
3586 bool isDynamic =
false;
3590 isSynthesized = (propertyImpl->getPropertyImplementation() ==
3592 isDynamic = (propertyImpl->getPropertyImplementation() ==
3596 PushProperty(properties, property, Container, isSynthesized, isDynamic);
3598 properties.finishAndAddTo(propertyList);
3600 return propertyList.finishAndCreateGlobal(
".objc_property_list",
3618 std::string SuperClassName;
3619 if (SuperClassDecl) {
3621 EmitClassRef(SuperClassName);
3631 std::string classSymbolName =
"__objc_class_name_" + ClassName;
3632 if (
auto *symbol = TheModule.getGlobalVariable(classSymbolName)) {
3633 symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0));
3635 new llvm::GlobalVariable(TheModule, LongTy,
false,
3636 llvm::GlobalValue::ExternalLinkage,
3637 llvm::ConstantInt::get(LongTy, 0),
3653 auto IvarOffsetValues = IvarOffsetBuilder.beginArray(PtrToIntTy);
3657 int superInstanceSize = !SuperClassDecl ? 0 :
3662 instanceSize = 0 - (instanceSize - superInstanceSize);
3668 IvarNames.push_back(MakeConstantString(IVD->getNameAsString()));
3670 std::string TypeStr;
3672 IvarTypes.push_back(MakeConstantString(TypeStr));
3673 IvarAligns.push_back(llvm::ConstantInt::get(IntTy,
3676 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
3679 Offset = BaseOffset - superInstanceSize;
3681 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
3683 std::string OffsetName =
"__objc_ivar_offset_value_" + ClassName +
"." +
3684 IVD->getNameAsString();
3686 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
3688 OffsetVar->setInitializer(OffsetValue);
3692 OffsetVar->setLinkage(llvm::GlobalValue::ExternalLinkage);
3694 OffsetVar =
new llvm::GlobalVariable(TheModule, Int32Ty,
3695 false, llvm::GlobalValue::ExternalLinkage,
3696 OffsetValue, OffsetName);
3697 IvarOffsets.push_back(OffsetValue);
3698 IvarOffsetValues.add(OffsetVar);
3700 IvarOwnership.push_back(lt);
3703 StrongIvars.push_back(
true);
3704 WeakIvars.push_back(
false);
3707 StrongIvars.push_back(
false);
3708 WeakIvars.push_back(
true);
3711 StrongIvars.push_back(
false);
3712 WeakIvars.push_back(
false);
3715 llvm::Constant *StrongIvarBitmap = MakeBitField(StrongIvars);
3716 llvm::Constant *WeakIvarBitmap = MakeBitField(WeakIvars);
3717 llvm::GlobalVariable *IvarOffsetArray =
3718 IvarOffsetValues.finishAndCreateGlobal(
".ivar.offsets",
3723 InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
3730 llvm::Constant *Properties = GeneratePropertyList(OID, ClassDecl);
3733 auto RefProtocols = ClassDecl->
protocols();
3734 auto RuntimeProtocols =
3735 GetRuntimeProtocolList(RefProtocols.begin(), RefProtocols.end());
3737 for (
const auto *I : RuntimeProtocols)
3738 Protocols.push_back(I->getNameAsString());
3741 llvm::Constant *SuperClass;
3742 if (!SuperClassName.empty()) {
3743 SuperClass = MakeConstantString(SuperClassName,
".super_class_name");
3745 SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty);
3750 llvm::Constant *MethodList = GenerateMethodList(ClassName,
"",
3751 InstanceMethods,
false);
3752 llvm::Constant *ClassMethodList = GenerateMethodList(ClassName,
"",
3753 ClassMethods,
true);
3754 llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
3755 IvarOffsets, IvarAligns, IvarOwnership);
3766 llvm::Type *IndexTy = Int32Ty;
3767 llvm::Constant *offsetPointerIndexes[] = {Zeros[0],
3768 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 2 : 1),
nullptr,
3769 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 3 : 2) };
3771 unsigned ivarIndex = 0;
3774 const std::string Name = GetIVarOffsetVariableName(ClassDecl, IVD);
3775 offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, ivarIndex);
3777 llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr(
3778 cast<llvm::GlobalVariable>(IvarList)->getValueType(), IvarList,
3779 offsetPointerIndexes);
3781 llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name);
3783 offset->setInitializer(offsetValue);
3787 offset->setLinkage(llvm::GlobalValue::ExternalLinkage);
3790 new llvm::GlobalVariable(TheModule, offsetValue->getType(),
3791 false, llvm::GlobalValue::ExternalLinkage, offsetValue, Name);
3794 llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0);
3797 llvm::Constant *MetaClassStruct = GenerateClassStructure(
3798 NULLPtr, NULLPtr, 0x12L, ClassName.c_str(),
nullptr, Zeros[0],
3799 NULLPtr, ClassMethodList, NULLPtr, NULLPtr,
3800 GeneratePropertyList(OID, ClassDecl,
true), ZeroPtr, ZeroPtr,
true);
3805 llvm::Constant *ClassStruct = GenerateClassStructure(
3806 MetaClassStruct, SuperClass, 0x11L, ClassName.c_str(),
nullptr,
3807 llvm::ConstantInt::get(LongTy, instanceSize), IvarList, MethodList,
3808 GenerateProtocolList(Protocols), IvarOffsetArray, Properties,
3809 StrongIvarBitmap, WeakIvarBitmap);
3814 if (ClassPtrAlias) {
3815 ClassPtrAlias->replaceAllUsesWith(ClassStruct);
3816 ClassPtrAlias->eraseFromParent();
3817 ClassPtrAlias =
nullptr;
3819 if (MetaClassPtrAlias) {
3820 MetaClassPtrAlias->replaceAllUsesWith(MetaClassStruct);
3821 MetaClassPtrAlias->eraseFromParent();
3822 MetaClassPtrAlias =
nullptr;
3826 Classes.push_back(ClassStruct);
3829llvm::Function *CGObjCGNU::ModuleInitFunction() {
3831 if (Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
3836 GenerateProtocolHolderCategory();
3838 llvm::StructType *selStructTy = dyn_cast<llvm::StructType>(SelectorElemTy);
3841 { PtrToInt8Ty, PtrToInt8Ty });
3845 llvm::Constant *statics = NULLPtr;
3846 if (!ConstantStrings.empty()) {
3847 llvm::GlobalVariable *fileStatics = [&] {
3849 auto staticsStruct = builder.beginStruct();
3852 if (stringClass.empty()) stringClass =
"NXConstantString";
3853 staticsStruct.add(MakeConstantString(stringClass,
3854 ".objc_static_class_name"));
3856 auto array = staticsStruct.beginArray();
3857 array.addAll(ConstantStrings);
3859 array.finishAndAddTo(staticsStruct);
3861 return staticsStruct.finishAndCreateGlobal(
".objc_statics",
3866 auto allStaticsArray = builder.beginArray(fileStatics->getType());
3867 allStaticsArray.add(fileStatics);
3868 allStaticsArray.addNullPointer(fileStatics->getType());
3870 statics = allStaticsArray.finishAndCreateGlobal(
".objc_statics_ptr",
3877 unsigned selectorCount;
3880 llvm::GlobalVariable *selectorList = [&] {
3882 auto selectors = builder.beginArray(selStructTy);
3884 std::vector<Selector> allSelectors;
3885 for (
auto &entry : table)
3886 allSelectors.push_back(entry.first);
3887 llvm::sort(allSelectors);
3889 for (
auto &untypedSel : allSelectors) {
3890 std::string selNameStr = untypedSel.getAsString();
3891 llvm::Constant *selName = ExportUniqueString(selNameStr,
".objc_sel_name");
3893 for (TypedSelector &sel : table[untypedSel]) {
3894 llvm::Constant *selectorTypeEncoding = NULLPtr;
3895 if (!sel.first.empty())
3896 selectorTypeEncoding =
3897 MakeConstantString(sel.first,
".objc_sel_types");
3899 auto selStruct = selectors.beginStruct(selStructTy);
3900 selStruct.add(selName);
3901 selStruct.add(selectorTypeEncoding);
3902 selStruct.finishAndAddTo(selectors);
3905 selectorAliases.push_back(sel.second);
3910 selectorCount = selectors.size();
3916 auto selStruct = selectors.beginStruct(selStructTy);
3917 selStruct.add(NULLPtr);
3918 selStruct.add(NULLPtr);
3919 selStruct.finishAndAddTo(selectors);
3921 return selectors.finishAndCreateGlobal(
".objc_selector_list",
3926 for (
unsigned i = 0; i < selectorCount; ++i) {
3927 llvm::Constant *idxs[] = {
3929 llvm::ConstantInt::get(Int32Ty, i)
3932 llvm::Constant *selPtr = llvm::ConstantExpr::getGetElementPtr(
3933 selectorList->getValueType(), selectorList, idxs);
3934 selectorAliases[i]->replaceAllUsesWith(selPtr);
3935 selectorAliases[i]->eraseFromParent();
3938 llvm::GlobalVariable *symtab = [&] {
3940 auto symtab = builder.beginStruct();
3943 symtab.addInt(LongTy, selectorCount);
3945 symtab.add(selectorList);
3948 symtab.addInt(CGM.
Int16Ty, Classes.size());
3950 symtab.addInt(CGM.
Int16Ty, Categories.size());
3953 auto classList = symtab.beginArray(PtrToInt8Ty);
3954 classList.addAll(Classes);
3955 classList.addAll(Categories);
3957 classList.add(statics);
3958 classList.add(NULLPtr);
3959 classList.finishAndAddTo(symtab);
3967 llvm::Constant *module = [&] {
3968 llvm::Type *moduleEltTys[] = {
3969 LongTy, LongTy, PtrToInt8Ty, symtab->getType(), IntTy
3971 llvm::StructType *moduleTy = llvm::StructType::get(
3973 ArrayRef(moduleEltTys).drop_back(
unsigned(RuntimeVersion < 10)));
3976 auto module = builder.beginStruct(moduleTy);
3978 module.addInt(LongTy, RuntimeVersion);
3980 module.addInt(LongTy, CGM.
getDataLayout().getTypeStoreSize(moduleTy));
3987 module.add(MakeConstantString(path,
".objc_source_file_name"));
3990 if (RuntimeVersion >= 10) {
3992 case LangOptions::GCOnly:
3993 module.addInt(IntTy, 2);
3995 case LangOptions::NonGC:
3997 module.addInt(IntTy, 1);
3999 module.addInt(IntTy, 0);
4001 case LangOptions::HybridGC:
4002 module.addInt(IntTy, 1);
4012 llvm::Function * LoadFunction = llvm::Function::Create(
4013 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
4014 llvm::GlobalValue::InternalLinkage,
".objc_load_function",
4016 llvm::BasicBlock *EntryBB =
4017 llvm::BasicBlock::Create(VMContext,
"entry", LoadFunction);
4019 Builder.SetInsertPoint(EntryBB);
4021 llvm::FunctionType *FT =
4022 llvm::FunctionType::get(Builder.getVoidTy(), module->getType(),
true);
4023 llvm::FunctionCallee Register =
4025 Builder.CreateCall(Register, module);
4027 if (!ClassAliases.empty()) {
4028 llvm::Type *ArgTypes[2] = {PtrTy, PtrToInt8Ty};
4029 llvm::FunctionType *RegisterAliasTy =
4030 llvm::FunctionType::get(Builder.getVoidTy(),
4032 llvm::Function *RegisterAlias = llvm::Function::Create(
4034 llvm::GlobalValue::ExternalWeakLinkage,
"class_registerAlias_np",
4036 llvm::BasicBlock *AliasBB =
4037 llvm::BasicBlock::Create(VMContext,
"alias", LoadFunction);
4038 llvm::BasicBlock *NoAliasBB =
4039 llvm::BasicBlock::Create(VMContext,
"no_alias", LoadFunction);
4042 llvm::Value *HasRegisterAlias = Builder.CreateICmpNE(RegisterAlias,
4043 llvm::Constant::getNullValue(RegisterAlias->getType()));
4044 Builder.CreateCondBr(HasRegisterAlias, AliasBB, NoAliasBB);
4047 Builder.SetInsertPoint(AliasBB);
4049 for (std::vector<ClassAliasPair>::iterator iter = ClassAliases.begin();
4050 iter != ClassAliases.end(); ++iter) {
4051 llvm::Constant *TheClass =
4052 TheModule.getGlobalVariable(
"_OBJC_CLASS_" + iter->first,
true);
4054 Builder.CreateCall(RegisterAlias,
4055 {TheClass, MakeConstantString(iter->second)});
4059 Builder.CreateBr(NoAliasBB);
4062 Builder.SetInsertPoint(NoAliasBB);
4064 Builder.CreateRetVoid();
4066 return LoadFunction;
4069llvm::Function *CGObjCGNU::GenerateMethod(
const ObjCMethodDecl *OMD,
4072 llvm::FunctionType *MethodTy =
4073 Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
4076 std::string FunctionName =
4077 getSymbolNameForMethod(OMD, !isDirect);
4080 return llvm::Function::Create(MethodTy,
4081 llvm::GlobalVariable::InternalLinkage,
4082 FunctionName, &TheModule);
4085 auto I = DirectMethodDefinitions.find(COMD);
4086 llvm::Function *OldFn =
nullptr, *
Fn =
nullptr;
4088 if (I == DirectMethodDefinitions.end()) {
4090 llvm::Function::Create(MethodTy, llvm::GlobalVariable::ExternalLinkage,
4091 FunctionName, &TheModule);
4092 DirectMethodDefinitions.insert(std::make_pair(COMD, F));
4109 Fn = llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,
"",
4111 Fn->takeName(OldFn);
4112 OldFn->replaceAllUsesWith(Fn);
4113 OldFn->eraseFromParent();
4127llvm::FunctionCallee CGObjCGNU::GetPropertyGetFunction() {
4128 return GetPropertyFn;
4131llvm::FunctionCallee CGObjCGNU::GetPropertySetFunction() {
4132 return SetPropertyFn;
4135llvm::FunctionCallee CGObjCGNU::GetOptimizedPropertySetFunction(
bool atomic,
4140llvm::FunctionCallee CGObjCGNU::GetGetStructFunction() {
4141 return GetStructPropertyFn;
4144llvm::FunctionCallee CGObjCGNU::GetSetStructFunction() {
4145 return SetStructPropertyFn;
4148llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectGetFunction() {
4152llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectSetFunction() {
4156llvm::FunctionCallee CGObjCGNU::EnumerationMutationFunction() {
4157 return EnumerationMutationFn;
4162 EmitAtSynchronizedStmt(CGF, S, SyncEnterFn, SyncExitFn);
4179 EmitTryCatchStmt(CGF, S, EnterCatchFn, ExitCatchFn, ExceptionReThrowFn);
4184 bool ClearInsertionPoint) {
4185 llvm::Value *ExceptionAsObject;
4186 bool isRethrow =
false;
4188 if (
const Expr *ThrowExpr = S.getThrowExpr()) {
4190 ExceptionAsObject = Exception;
4193 "Unexpected rethrow outside @catch block.");
4197 if (isRethrow && (usesSEHExceptions || usesCxxExceptions)) {
4206 Throw->setDoesNotReturn();
4208 ExceptionAsObject = CGF.
Builder.CreateBitCast(ExceptionAsObject, IdTy);
4209 llvm::CallBase *Throw =
4211 Throw->setDoesNotReturn();
4213 CGF.
Builder.CreateUnreachable();
4214 if (ClearInsertionPoint)
4215 CGF.
Builder.ClearInsertionPoint();
4221 return B.CreateCall(
4222 WeakReadFn, EnforceType(B, AddrWeakObj.
emitRawPointer(CGF), PtrToIdTy));
4226 llvm::Value *src,
Address dst) {
4228 src = EnforceType(B, src, IdTy);
4229 llvm::Value *dstVal = EnforceType(B, dst.
emitRawPointer(CGF), PtrToIdTy);
4230 B.CreateCall(WeakAssignFn, {src, dstVal});
4234 llvm::Value *src,
Address dst,
4237 src = EnforceType(B, src, IdTy);
4238 llvm::Value *dstVal = EnforceType(B, dst.
emitRawPointer(CGF), PtrToIdTy);
4240 assert(!threadlocal &&
"EmitObjCGlobalAssign - Threal Local API NYI");
4241 B.CreateCall(GlobalAssignFn, {src, dstVal});
4245 llvm::Value *src,
Address dst,
4246 llvm::Value *ivarOffset) {
4248 src = EnforceType(B, src, IdTy);
4249 llvm::Value *dstVal = EnforceType(B, dst.
emitRawPointer(CGF), IdTy);
4250 B.CreateCall(IvarAssignFn, {src, dstVal, ivarOffset});
4254 llvm::Value *src,
Address dst) {
4256 src = EnforceType(B, src, IdTy);
4257 llvm::Value *dstVal = EnforceType(B, dst.
emitRawPointer(CGF), PtrToIdTy);
4258 B.CreateCall(StrongCastAssignFn, {src, dstVal});
4264 llvm::Value *Size) {
4266 llvm::Value *DestPtrVal = EnforceType(B, DestPtr.
emitRawPointer(CGF), PtrTy);
4267 llvm::Value *SrcPtrVal = EnforceType(B, SrcPtr.
emitRawPointer(CGF), PtrTy);
4269 B.CreateCall(MemMoveFn, {DestPtrVal, SrcPtrVal,
Size});
4272llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
4275 const std::string Name = GetIVarOffsetVariableName(ID, Ivar);
4279 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
4280 if (!IvarOffsetPointer)
4281 IvarOffsetPointer =
new llvm::GlobalVariable(
4282 TheModule, llvm::PointerType::getUnqual(VMContext),
false,
4283 llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
4284 return IvarOffsetPointer;
4289 llvm::Value *BaseValue,
4291 unsigned CVRQualifiers) {
4294 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
4295 EmitIvarOffset(CGF, ID, Ivar));
4323 if (RuntimeVersion < 10 ||
4325 return CGF.
Builder.CreateZExtOrBitCast(
4329 llvm::PointerType::getUnqual(VMContext),
4330 ObjCIvarOffsetVariable(
Interface, Ivar),
4334 std::string
name =
"__objc_ivar_offset_value_" +
4337 llvm::Value *Offset = TheModule.getGlobalVariable(name);
4339 auto GV =
new llvm::GlobalVariable(TheModule, IntTy,
4340 false, llvm::GlobalValue::LinkOnceAnyLinkage,
4341 llvm::Constant::getNullValue(IntTy), name);
4346 if (Offset->getType() != PtrDiffTy)
4347 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
4351 return llvm::ConstantInt::get(PtrDiffTy, Offset,
true);
4357 switch (Runtime.getKind()) {
4359 if (Runtime.getVersion() >= VersionTuple(2, 0))
4360 return new CGObjCGNUstep2(CGM);
4361 return new CGObjCGNUstep(CGM);
4364 return new CGObjCGCC(CGM);
4367 return new CGObjCObjFW(CGM);
4373 llvm_unreachable(
"these runtimes are not GNU runtimes");
4375 llvm_unreachable(
"bad runtime");
Defines the clang::ASTContext interface.
static const ObjCInterfaceDecl * FindIvarInterface(ASTContext &Context, const ObjCInterfaceDecl *OID, const ObjCIvarDecl *OIVD)
static bool isNamed(const NamedDecl *ND, const char(&Str)[Len])
Defines the SourceManager interface.
Defines the Objective-C statement AST node classes.
__device__ __2f16 float __ockl_bool s
__device__ __2f16 float c
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
TranslationUnitDecl * getTranslationUnitDecl() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
void getObjCEncodingForType(QualType T, std::string &S, const FieldDecl *Field=nullptr, QualType *NotEncodedT=nullptr) const
Emit the Objective-CC type encoding for the given type T into S.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
std::string getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, bool Extended=false) const
Emit the encoded type for the method declaration Decl into S.
std::string getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD, const Decl *Container) const
getObjCEncodingForPropertyDecl - Return the encoded type for this method declaration.
const ASTRecordLayout & getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const
Get or compute information about the layout of the specified Objective-C implementation.
const ASTRecordLayout & getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const
Get or compute information about the layout of the specified Objective-C interface.
QualType getObjCProtoType() const
Retrieve the type of the Objective-C Protocol class.
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
ObjCPropertyImplDecl * getObjCPropertyImplDeclForPropertyDecl(const ObjCPropertyDecl *PD, const Decl *Container) const
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
QualType getObjCIdType() const
Represents the Objective-CC id type.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
void getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT, QualType T, std::string &S, bool Extended) const
getObjCEncodingForMethodParameter - Return the encoded type for a single method parameter or return t...
const TargetInfo & getTargetInfo() const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
CharUnits getSize() const
getSize - Get the record size in characters.
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
CharUnits - This is an opaque type for sizes expressed in character units.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
CGBlockInfo - Information to generate a block literal.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
virtual llvm::Constant * getAddrOfRTTIDescriptor(QualType Ty)=0
virtual CatchTypeInfo getCatchAllTypeInfo()
Abstract information about a function or function prototype.
All available information about a concrete callee.
Implements runtime-specific code generation functions.
virtual llvm::Constant * GetEHType(QualType T)=0
Get the type constant to catch for the given ObjC pointer type.
virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest, llvm::Value *ivarOffset)=0
virtual llvm::FunctionCallee GetCppAtomicObjectGetFunction()=0
API for atomic copying of qualified aggregates with non-trivial copy assignment (c++) in getter.
virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest)=0
virtual llvm::Constant * BuildByrefLayout(CodeGen::CodeGenModule &CGM, QualType T)=0
Returns an i8* which points to the byref layout information.
virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, Address DestPtr, Address SrcPtr, llvm::Value *Size)=0
virtual llvm::FunctionCallee GetPropertySetFunction()=0
Return the runtime function for setting properties.
virtual llvm::FunctionCallee GetCppAtomicObjectSetFunction()=0
API for atomic copying of qualified aggregates with non-trivial copy assignment (c++) in setter.
virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtTryStmt &S)=0
virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, ReturnValueSlot ReturnSlot, QualType ResultType, Selector Sel, llvm::Value *Receiver, const CallArgList &CallArgs, const ObjCInterfaceDecl *Class=nullptr, const ObjCMethodDecl *Method=nullptr)=0
Generate an Objective-C message send operation.
virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy, llvm::Value *BaseValue, const ObjCIvarDecl *Ivar, unsigned CVRQualifiers)=0
virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD)=0
Register an class alias.
virtual void GenerateCategory(const ObjCCategoryImplDecl *OCD)=0
Generate a category.
virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S, bool ClearInsertionPoint=true)=0
virtual llvm::Value * EmitIvarOffset(CodeGen::CodeGenFunction &CGF, const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar)=0
virtual llvm::Function * GenerateMethod(const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD)=0
Generate a function preamble for a method with the specified types.
virtual llvm::Value * GenerateProtocolRef(CodeGenFunction &CGF, const ObjCProtocolDecl *OPD)=0
Emit the code to return the named protocol as an object, as in a @protocol expression.
virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, Address AddrWeakObj)=0
virtual llvm::Function * ModuleInitFunction()=0
Generate the function required to register all Objective-C components in this compilation unit with t...
virtual CodeGen::RValue GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, ReturnValueSlot ReturnSlot, QualType ResultType, Selector Sel, const ObjCInterfaceDecl *Class, bool isCategoryImpl, llvm::Value *Self, bool IsClassMessage, const CallArgList &CallArgs, const ObjCMethodDecl *Method=nullptr)=0
Generate an Objective-C message send operation to the super class initiated in a method for Class and...
virtual void GenerateClass(const ObjCImplementationDecl *OID)=0
Generate a class structure for this class.
virtual llvm::FunctionCallee EnumerationMutationFunction()=0
EnumerationMutationFunction - Return the function that's called by the compiler when a mutation is de...
virtual llvm::Constant * BuildGCBlockLayout(CodeGen::CodeGenModule &CGM, const CodeGen::CGBlockInfo &blockInfo)=0
virtual llvm::FunctionCallee GetGetStructFunction()=0
virtual llvm::Constant * GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0
GetOrEmitProtocol - Get the protocol object for the given declaration, emitting it if necessary.
virtual ConstantAddress GenerateConstantString(const StringLiteral *)=0
Generate a constant string object.
virtual llvm::Value * GetClass(CodeGenFunction &CGF, const ObjCInterfaceDecl *OID)=0
GetClass - Return a reference to the class for the given interface decl.
virtual void GenerateProtocol(const ObjCProtocolDecl *OPD)=0
Generate the named protocol.
virtual llvm::Constant * BuildRCBlockLayout(CodeGen::CodeGenModule &CGM, const CodeGen::CGBlockInfo &blockInfo)=0
virtual llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic, bool copy)=0
Return the runtime function for optimized setting properties.
virtual llvm::Value * GetSelector(CodeGenFunction &CGF, Selector Sel)=0
Get a selector for the specified name and type values.
virtual void GenerateDirectMethodPrologue(CodeGenFunction &CGF, llvm::Function *Fn, const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD)=0
Generates prologue for direct Objective-C Methods.
virtual Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel)=0
Get the address of a selector for the specified name and type values.
virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest)=0
virtual llvm::Value * EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF)
virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest, bool threadlocal=false)=0
virtual llvm::FunctionCallee GetPropertyGetFunction()=0
Return the runtime function for getting properties.
virtual llvm::FunctionCallee GetSetStructFunction()=0
virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S)=0
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
void addFrom(const CallArgList &other)
Add all the arguments from another CallArgList to this one.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
SmallVector< llvm::Value *, 8 > ObjCEHValueStack
ObjCEHValueStack - Stack of Objective-C exception values, used for rethrows.
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
JumpDest ReturnBlock
ReturnBlock - Unified return block.
llvm::Value * EmitObjCThrowOperand(const Expr *expr)
llvm::Value * LoadObjCSelf()
LoadObjCSelf - Load the value of self.
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
void EmitVarDecl(const VarDecl &D)
EmitVarDecl - Emit a local variable declaration.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
static bool hasAggregateEvaluationKind(QualType T)
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
llvm::LLVMContext & getLLVMContext()
This class organizes the cross-function state that is used while generating LLVM code.
void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const
Set visibility, dllimport/dllexport and dso_local.
llvm::Module & getModule() const
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
void addCompilerUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.compiler.used metadata.
bool ReturnTypeUsesFPRet(QualType ResultType)
Return true iff the given type uses 'fpret' when used as a return type.
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
void addUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.used metadata.
const llvm::DataLayout & getDataLayout() const
CGCXXABI & getCXXABI() const
const llvm::Triple & getTriple() const
bool ReturnTypeHasInReg(const CGFunctionInfo &FI)
Return true iff the given type has inreg set.
ASTContext & getContext() const
bool ReturnTypeUsesSRet(const CGFunctionInfo &FI)
Return true iff the given type uses 'sret' when used as a return type.
const CodeGenOptions & getCodeGenOpts() const
llvm::LLVMContext & getLLVMContext()
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
ConstantAddress GetAddrOfConstantCString(const std::string &Str, const char *GlobalName=nullptr)
Returns a pointer to a character array containing the literal and a terminating '\0' character.
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
bool isZeroInitializable(QualType T)
IsZeroInitializable - Return whether a type can be zero-initialized (in the C++ sense) with an LLVM z...
A specialization of Address that requires the address to be an LLVM Constant.
ArrayBuilder beginArray(llvm::Type *eltTy=nullptr)
llvm::GlobalVariable * finishAndCreateGlobal(As &&...args)
Given that this builder was created by beginning an array or struct directly on a ConstantInitBuilder...
StructBuilder beginStruct(llvm::StructType *ty=nullptr)
void finishAndAddTo(AggregateBuilderBase &parent)
Given that this builder was created by beginning an array or struct component on the given parent bui...
A helper class of ConstantInitBuilder, used for building constant array initializers.
The standard implementation of ConstantInitBuilder used in Clang.
A helper class of ConstantInitBuilder, used for building constant struct initializers.
LValue - This represents an lvalue references.
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
An abstract representation of an aligned address.
llvm::Value * getPointer() const
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
Decl - This represents one declaration (or definition), e.g.
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
StringRef getName() const
This represents one expression.
StringRef getName() const
The name of this FileEntry.
DirectoryEntryRef getDir() const
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
std::string ObjCConstantStringClass
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Visibility getVisibility() const
Determines the visibility of this entity.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
Represents Objective-C's @synchronized statement.
Represents Objective-C's @throw statement.
Represents Objective-C's @try ... @catch ... @finally statement.
ObjCCategoryDecl - Represents a category declaration.
const ObjCProtocolList & getReferencedProtocols() const
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
ObjCCategoryDecl * getCategoryDecl() const
ObjCCompatibleAliasDecl - Represents alias of a class.
const ObjCInterfaceDecl * getClassInterface() const
ObjCContainerDecl - Represents a container for method declarations.
classmeth_iterator classmeth_end() const
classmeth_iterator classmeth_begin() const
instmeth_range instance_methods() const
instmeth_iterator instmeth_end() const
instmeth_iterator instmeth_begin() const
prop_range properties() const
classmeth_range class_methods() const
propimpl_range property_impls() const
const ObjCInterfaceDecl * getClassInterface() const
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Represents an ObjC class declaration.
all_protocol_range all_referenced_protocols() const
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
protocol_range protocols() const
protocol_iterator protocol_end() const
protocol_iterator protocol_begin() const
ObjCInterfaceDecl * getSuperClass() const
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
known_extensions_range known_extensions() const
Interfaces are the core concept in Objective-C for object oriented design.
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
ObjCIvarDecl - Represents an ObjC instance variable.
AccessControl getAccessControl() const
ObjCInterfaceDecl * getContainingInterface()
Return the class interface that this ivar is logically contained in; this is either the interface whe...
ObjCIvarDecl * getNextIvar()
ObjCMethodDecl - Represents an instance or class method declaration.
ImplicitParamDecl * getSelfDecl() const
bool hasParamDestroyedInCallee() const
True if the method has a parameter that's destroyed in the callee.
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
ObjCMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Selector getSelector() const
ImplicitParamDecl * getCmdDecl() const
QualType getReturnType() const
bool isClassMethod() const
ObjCInterfaceDecl * getClassInterface()
Represents a pointer to an Objective C object.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
const ObjCInterfaceType * getInterfaceType() const
If this pointer points to an Objective C @interface type, gets the type for that interface.
Represents a class type in Objective C.
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface.
Represents one property declaration in an Objective-C interface.
ObjCMethodDecl * getGetterMethodDecl() const
ObjCMethodDecl * getSetterMethodDecl() const
Represents an Objective-C protocol declaration.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
bool isNonRuntimeProtocol() const
This is true iff the protocol is tagged with the objc_non_runtime_protocol attribute.
protocol_iterator protocol_begin() const
protocol_range protocols() const
protocol_iterator protocol_end() const
The basic abstraction for the target Objective-C runtime.
const VersionTuple & getVersion() const
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
Kind
The basic Objective-C runtimes that we know about.
@ MacOSX
'macosx' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the non-fragile AB...
@ FragileMacOSX
'macosx-fragile' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the fragil...
@ GNUstep
'gnustep' is the modern non-fragile GNUstep runtime.
@ ObjFW
'objfw' is the Objective-C runtime included in ObjFW
@ iOS
'ios' is the Apple-provided NeXT-derived runtime on iOS or the iOS simulator; it is always non-fragil...
@ GCC
'gcc' is the Objective-C runtime shipped with GCC, implementing a fragile Objective-C ABI
@ WatchOS
'watchos' is a variant of iOS for Apple's watchOS.
A (possibly-)qualified type.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
This table allows us to fully hide how we implement multi-keyword caching.
Smart pointer class that efficiently represents Objective-C method names.
std::string getAsString() const
Derive the full selector name (e.g.
This class handles loading and caching of source files into memory.
StringLiteral - This represents a string literal expression, e.g.
bool containsNonAscii() const
unsigned getLength() const
uint32_t getCodeUnit(size_t i) const
StringRef getString() const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
The top declaration context.
static DeclContext * castToDeclContext(const TranslationUnitDecl *D)
const T * castAs() const
Member-template castAs<specific type>.
bool isObjCQualifiedIdType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isObjCIdType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
Represents a variable declaration or definition.
CGObjCRuntime * CreateGNUObjCRuntime(CodeGenModule &CGM)
Creates an instance of an Objective-C runtime class.
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
bool Zero(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
const FunctionProtoType * T
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ HiddenVisibility
Objects with "hidden" visibility are not seen by the dynamic linker.
The MS C++ ABI needs a pointer to RTTI data plus some flags to describe the type of a catch handler,...
CharUnits getIntAlign() const
llvm::IntegerType * Int16Ty
llvm::PointerType * Int8PtrTy
CharUnits getPointerAlign() const