32#include "llvm/ADT/SmallVector.h"
33#include "llvm/ADT/StringMap.h"
34#include "llvm/IR/DataLayout.h"
35#include "llvm/IR/Intrinsics.h"
36#include "llvm/IR/LLVMContext.h"
37#include "llvm/IR/Module.h"
38#include "llvm/Support/Compiler.h"
39#include "llvm/Support/ConvertUTF.h"
43using namespace CodeGen;
50class LazyRuntimeFunction {
52 llvm::FunctionType *FTy =
nullptr;
53 const char *FunctionName =
nullptr;
54 llvm::FunctionCallee
Function =
nullptr;
57 LazyRuntimeFunction() =
default;
61 template <
typename... Tys>
62 void init(
CodeGenModule *Mod,
const char *name, llvm::Type *RetTy,
69 FTy = llvm::FunctionType::get(RetTy, ArgTys,
false);
72 FTy = llvm::FunctionType::get(RetTy, std::nullopt,
false);
76 llvm::FunctionType *getType() {
return FTy; }
80 operator llvm::FunctionCallee() {
97 llvm::Module &TheModule;
100 llvm::StructType *ObjCSuperTy;
103 llvm::PointerType *PtrToObjCSuperTy;
107 llvm::PointerType *SelectorTy;
109 llvm::Type *SelectorElemTy;
112 llvm::IntegerType *Int8Ty;
115 llvm::PointerType *PtrToInt8Ty;
117 llvm::StructType *ProtocolTy;
119 llvm::PointerType *ProtocolPtrTy;
125 llvm::PointerType *IMPTy;
130 llvm::PointerType *IdTy;
132 llvm::Type *IdElemTy;
135 llvm::PointerType *PtrToIdTy;
140 llvm::IntegerType *IntTy;
144 llvm::PointerType *PtrTy;
148 llvm::IntegerType *LongTy;
150 llvm::IntegerType *SizeTy;
152 llvm::IntegerType *IntPtrTy;
154 llvm::IntegerType *PtrDiffTy;
157 llvm::PointerType *PtrToIntTy;
161 llvm::IntegerType *Int32Ty;
163 llvm::IntegerType *Int64Ty;
165 llvm::StructType *PropertyMetadataTy;
169 unsigned msgSendMDKind;
172 bool usesSEHExceptions;
174 bool usesCxxExceptions;
179 return (R.
getKind() == kind) &&
180 (R.
getVersion() >= VersionTuple(major, minor));
183 std::string ManglePublicSymbol(StringRef Name) {
184 return (StringRef(CGM.
getTriple().isOSBinFormatCOFF() ?
"$_" :
"._") + Name).str();
187 std::string SymbolForProtocol(Twine Name) {
188 return (ManglePublicSymbol(
"OBJC_PROTOCOL_") + Name).str();
191 std::string SymbolForProtocolRef(StringRef Name) {
192 return (ManglePublicSymbol(
"OBJC_REF_PROTOCOL_") + Name).str();
199 llvm::Constant *MakeConstantString(StringRef Str,
const char *Name =
"") {
202 return llvm::ConstantExpr::getGetElementPtr(Array.getElementType(),
203 Array.getPointer(), Zeros);
210 llvm::Constant *ExportUniqueString(
const std::string &Str,
211 const std::string &prefix,
212 bool Private=
false) {
213 std::string
name = prefix + Str;
214 auto *ConstStr = TheModule.getGlobalVariable(name);
216 llvm::Constant *value = llvm::ConstantDataArray::getString(VMContext,Str);
217 auto *GV =
new llvm::GlobalVariable(TheModule, value->getType(),
true,
218 llvm::GlobalValue::LinkOnceODRLinkage, value, name);
219 GV->setComdat(TheModule.getOrInsertComdat(name));
221 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
224 return llvm::ConstantExpr::getGetElementPtr(ConstStr->getValueType(),
230 const Decl *Container) {
233 std::string NameAndAttributes;
234 std::string TypeStr =
236 NameAndAttributes +=
'\0';
237 NameAndAttributes += TypeStr.length() + 3;
238 NameAndAttributes += TypeStr;
239 NameAndAttributes +=
'\0';
241 return MakeConstantString(NameAndAttributes);
250 int attrs =
property->getPropertyAttributes();
253 attrs &= ~ObjCPropertyAttribute::kind_copy;
254 attrs &= ~ObjCPropertyAttribute::kind_retain;
255 attrs &= ~ObjCPropertyAttribute::kind_weak;
256 attrs &= ~ObjCPropertyAttribute::kind_strong;
259 Fields.addInt(Int8Ty, attrs & 0xff);
265 attrs |= isSynthesized ? (1<<0) : 0;
266 attrs |= isDynamic ? (1<<1) : 0;
269 Fields.addInt(Int8Ty, attrs & 0xff);
271 Fields.addInt(Int8Ty, 0);
272 Fields.addInt(Int8Ty, 0);
275 virtual llvm::Constant *GenerateCategoryProtocolList(
const
280 Fields.addInt(IntTy, count);
283 llvm::DataLayout td(&TheModule);
284 Fields.addInt(IntTy, td.getTypeSizeInBits(PropertyMetadataTy) /
295 bool isSynthesized=
true,
bool
297 auto Fields = PropertiesArray.
beginStruct(PropertyMetadataTy);
299 Fields.add(MakePropertyEncodingString(property, OCD));
300 PushPropertyAttributes(Fields, property, isSynthesized, isDynamic);
304 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
305 Fields.add(MakeConstantString(accessor->getSelector().getAsString()));
306 Fields.add(TypeEncoding);
320 llvm::Value *EnforceType(
CGBuilderTy &B, llvm::Value *
V, llvm::Type *Ty) {
321 if (
V->getType() == Ty)
323 return B.CreateBitCast(
V, Ty);
327 llvm::Constant *Zeros[2];
329 llvm::Constant *NULLPtr;
331 llvm::LLVMContext &VMContext;
339 llvm::GlobalAlias *ClassPtrAlias;
344 llvm::GlobalAlias *MetaClassPtrAlias;
346 std::vector<llvm::Constant*> Classes;
348 std::vector<llvm::Constant*> Categories;
351 std::vector<llvm::Constant*> ConstantStrings;
355 llvm::StringMap<llvm::Constant*> ObjCStrings;
357 llvm::StringMap<llvm::Constant*> ExistingProtocols;
363 typedef std::pair<std::string, llvm::GlobalAlias*> TypedSelector;
367 typedef llvm::DenseMap<Selector, SmallVector<TypedSelector, 2> >
375 Selector RetainSel, ReleaseSel, AutoreleaseSel;
379 LazyRuntimeFunction IvarAssignFn, StrongCastAssignFn, MemMoveFn, WeakReadFn,
380 WeakAssignFn, GlobalAssignFn;
382 typedef std::pair<std::string, std::string> ClassAliasPair;
384 std::vector<ClassAliasPair> ClassAliases;
388 LazyRuntimeFunction ExceptionThrowFn;
391 LazyRuntimeFunction ExceptionReThrowFn;
394 LazyRuntimeFunction EnterCatchFn;
397 LazyRuntimeFunction ExitCatchFn;
399 LazyRuntimeFunction SyncEnterFn;
401 LazyRuntimeFunction SyncExitFn;
406 LazyRuntimeFunction EnumerationMutationFn;
409 LazyRuntimeFunction GetPropertyFn;
412 LazyRuntimeFunction SetPropertyFn;
414 LazyRuntimeFunction GetStructPropertyFn;
416 LazyRuntimeFunction SetStructPropertyFn;
428 const int ProtocolVersion;
431 const int ClassABIVersion;
447 llvm::Constant *GenerateMethodList(StringRef ClassName,
448 StringRef CategoryName,
450 bool isClassMethodList);
455 virtual llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName);
459 llvm::Constant *GeneratePropertyList(
const Decl *Container,
461 bool isClassProperty=
false,
462 bool protocolOptionalProperties=
false);
472 void GenerateProtocolHolderCategory();
475 llvm::Constant *GenerateClassStructure(
476 llvm::Constant *MetaClass,
477 llvm::Constant *SuperClass,
480 llvm::Constant *Version,
481 llvm::Constant *InstanceSize,
482 llvm::Constant *IVars,
483 llvm::Constant *Methods,
484 llvm::Constant *Protocols,
485 llvm::Constant *IvarOffsets,
486 llvm::Constant *Properties,
487 llvm::Constant *StrongIvarBitmap,
488 llvm::Constant *WeakIvarBitmap,
493 virtual llvm::Constant *GenerateProtocolMethodList(
497 void EmitProtocolMethodList(T &&Methods, llvm::Constant *&
Required,
501 for (
const auto *I : Methods)
503 OptionalMethods.push_back(I);
505 RequiredMethods.push_back(I);
506 Required = GenerateProtocolMethodList(RequiredMethods);
507 Optional = GenerateProtocolMethodList(OptionalMethods);
513 const std::string &TypeEncoding);
520 const std::string Name =
"__objc_ivar_offset_" +
ID->getNameAsString()
529 void EmitClassRef(
const std::string &className);
533 const std::string &Name,
bool isWeak);
539 llvm::Value *&Receiver,
542 MessageSendInfo &MSI) = 0;
550 MessageSendInfo &MSI) = 0;
567 unsigned protocolClassVersion,
unsigned classABI=1);
574 llvm::Value *Receiver,
const CallArgList &CallArgs,
581 bool isCategoryImpl, llvm::Value *Receiver,
590 virtual llvm::Constant *GetConstantSelector(
Selector Sel,
591 const std::string &TypeEncoding) {
592 llvm_unreachable(
"Runtime unable to generate constant selector");
604 llvm::DenseMap<const ObjCMethodDecl *, llvm::Function *>
605 DirectMethodDefinitions;
639 bool ClearInsertionPoint=
true)
override;
643 llvm::Value *src,
Address dst)
override;
645 llvm::Value *src,
Address dest,
646 bool threadlocal=
false)
override;
648 Address dest, llvm::Value *ivarOffset)
override;
650 llvm::Value *src,
Address dest)
override;
653 llvm::Value *Size)
override;
656 unsigned CVRQualifiers)
override;
683class CGObjCGCC :
public CGObjCGNU {
686 LazyRuntimeFunction MsgLookupFn;
690 LazyRuntimeFunction MsgLookupSuperFn;
694 llvm::Value *cmd, llvm::MDNode *node,
695 MessageSendInfo &MSI)
override {
697 llvm::Value *args[] = {
698 EnforceType(Builder, Receiver, IdTy),
699 EnforceType(Builder, cmd, SelectorTy) };
701 imp->setMetadata(msgSendMDKind, node);
706 llvm::Value *cmd, MessageSendInfo &MSI)
override {
708 llvm::Value *lookupArgs[] = {
709 EnforceType(Builder, ObjCSuper.
getPointer(), PtrToObjCSuperTy), cmd};
716 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
718 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
719 PtrToObjCSuperTy, SelectorTy);
724class CGObjCGNUstep :
public CGObjCGNU {
727 LazyRuntimeFunction SlotLookupFn;
732 LazyRuntimeFunction SlotLookupSuperFn;
734 LazyRuntimeFunction SetPropertyAtomic;
736 LazyRuntimeFunction SetPropertyAtomicCopy;
738 LazyRuntimeFunction SetPropertyNonAtomic;
740 LazyRuntimeFunction SetPropertyNonAtomicCopy;
743 LazyRuntimeFunction CxxAtomicObjectGetFn;
746 LazyRuntimeFunction CxxAtomicObjectSetFn;
751 llvm::Type *SlotStructTy;
754 llvm::Constant *GetEHType(
QualType T)
override;
758 llvm::Value *cmd, llvm::MDNode *node,
759 MessageSendInfo &MSI)
override {
761 llvm::FunctionCallee LookupFn = SlotLookupFn;
766 Builder.CreateStore(Receiver, ReceiverPtr);
773 self = llvm::ConstantPointerNull::get(IdTy);
777 if (
auto *LookupFn2 = dyn_cast<llvm::Function>(LookupFn.getCallee()))
778 LookupFn2->addParamAttr(0, llvm::Attribute::NoCapture);
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 {
803 llvm::Value *lookupArgs[] = {ObjCSuper.
getPointer(), cmd};
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 llvm::DataLayout td(&TheModule);
1195 MethodList.addInt(IntTy, td.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[] = {CGObjCGNU::EnforceType(Builder,
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);
1479 return llvm::ConstantExpr::getGetElementPtr(TypesGlobal->getValueType(),
1480 TypesGlobal, Zeros);
1482 llvm::Constant *GetConstantSelector(
Selector Sel,
1483 const std::string &TypeEncoding)
override {
1484 std::string MangledTypes = GetSymbolNameForTypeEncoding(TypeEncoding);
1485 auto SelVarName = (StringRef(
".objc_selector_") + Sel.
getAsString() +
"_" +
1486 MangledTypes).str();
1487 if (
auto *GV = TheModule.getNamedGlobal(SelVarName))
1490 auto SelBuilder = builder.beginStruct();
1491 SelBuilder.add(ExportUniqueString(Sel.
getAsString(),
".objc_sel_name_",
1493 SelBuilder.add(GetTypeString(TypeEncoding));
1494 auto *GV = SelBuilder.finishAndCreateGlobal(SelVarName,
1496 GV->setComdat(TheModule.getOrInsertComdat(SelVarName));
1497 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1498 GV->setSection(sectionName<SelectorSection>());
1501 llvm::StructType *emptyStruct =
nullptr;
1510 std::pair<llvm::Constant*,llvm::Constant*>
1511 GetSectionBounds(StringRef Section) {
1512 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1513 if (emptyStruct ==
nullptr) {
1514 emptyStruct = llvm::StructType::create(VMContext,
".objc_section_sentinel");
1515 emptyStruct->setBody({},
true);
1517 auto ZeroInit = llvm::Constant::getNullValue(emptyStruct);
1518 auto Sym = [&](StringRef Prefix, StringRef SecSuffix) {
1519 auto *Sym =
new llvm::GlobalVariable(TheModule, emptyStruct,
1521 llvm::GlobalValue::LinkOnceODRLinkage, ZeroInit, Prefix +
1523 Sym->setVisibility(llvm::GlobalValue::HiddenVisibility);
1524 Sym->setSection((Section + SecSuffix).str());
1525 Sym->setComdat(TheModule.getOrInsertComdat((Prefix +
1530 return { Sym(
"__start_",
"$a"), Sym(
"__stop",
"$z") };
1532 auto *Start =
new llvm::GlobalVariable(TheModule, PtrTy,
1534 llvm::GlobalValue::ExternalLinkage,
nullptr, StringRef(
"__start_") +
1536 Start->setVisibility(llvm::GlobalValue::HiddenVisibility);
1537 auto *Stop =
new llvm::GlobalVariable(TheModule, PtrTy,
1539 llvm::GlobalValue::ExternalLinkage,
nullptr, StringRef(
"__stop_") +
1541 Stop->setVisibility(llvm::GlobalValue::HiddenVisibility);
1542 return { Start, Stop };
1547 llvm::Function *ModuleInitFunction()
override {
1548 llvm::Function *LoadFunction = llvm::Function::Create(
1549 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
1550 llvm::GlobalValue::LinkOnceODRLinkage,
".objcv2_load_function",
1552 LoadFunction->setVisibility(llvm::GlobalValue::HiddenVisibility);
1553 LoadFunction->setComdat(TheModule.getOrInsertComdat(
".objcv2_load_function"));
1555 llvm::BasicBlock *EntryBB =
1556 llvm::BasicBlock::Create(VMContext,
"entry", LoadFunction);
1558 B.SetInsertPoint(EntryBB);
1560 auto InitStructBuilder = builder.beginStruct();
1561 InitStructBuilder.addInt(Int64Ty, 0);
1562 auto §ionVec = CGM.
getTriple().isOSBinFormatCOFF() ? PECOFFSectionsBaseNames : SectionsBaseNames;
1563 for (
auto *
s : sectionVec) {
1564 auto bounds = GetSectionBounds(
s);
1565 InitStructBuilder.add(bounds.first);
1566 InitStructBuilder.add(bounds.second);
1568 auto *InitStruct = InitStructBuilder.finishAndCreateGlobal(
".objc_init",
1570 InitStruct->setVisibility(llvm::GlobalValue::HiddenVisibility);
1571 InitStruct->setComdat(TheModule.getOrInsertComdat(
".objc_init"));
1573 CallRuntimeFunction(B,
"__objc_load", {InitStruct});;
1580 auto *InitVar =
new llvm::GlobalVariable(TheModule, LoadFunction->getType(),
1581 false, llvm::GlobalValue::LinkOnceAnyLinkage,
1582 LoadFunction,
".objc_ctor");
1585 assert(InitVar->getName() ==
".objc_ctor");
1591 if (CGM.
getTriple().isOSBinFormatCOFF())
1592 InitVar->setSection(
".CRT$XCLz");
1596 InitVar->setSection(
".init_array");
1598 InitVar->setSection(
".ctors");
1600 InitVar->setVisibility(llvm::GlobalValue::HiddenVisibility);
1601 InitVar->setComdat(TheModule.getOrInsertComdat(
".objc_ctor"));
1603 for (
auto *
C : Categories) {
1604 auto *Cat = cast<llvm::GlobalVariable>(
C->stripPointerCasts());
1605 Cat->setSection(sectionName<CategorySection>());
1609 StringRef Section) {
1610 auto nullBuilder = builder.beginStruct();
1611 for (
auto *F :
Init)
1613 auto GV = nullBuilder.finishAndCreateGlobal(Name, CGM.
getPointerAlign(),
1614 false, llvm::GlobalValue::LinkOnceODRLinkage);
1615 GV->setSection(Section);
1616 GV->setComdat(TheModule.getOrInsertComdat(Name));
1617 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1621 for (
auto clsAlias : ClassAliases)
1622 createNullGlobal(std::string(
".objc_class_alias") +
1623 clsAlias.second, { MakeConstantString(clsAlias.second),
1624 GetClassVar(clsAlias.first) }, sectionName<ClassAliasSection>());
1629 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
1630 createNullGlobal(
".objc_null_selector", {NULLPtr, NULLPtr},
1631 sectionName<SelectorSection>());
1632 if (Categories.empty())
1633 createNullGlobal(
".objc_null_category", {NULLPtr, NULLPtr,
1634 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr},
1635 sectionName<CategorySection>());
1636 if (!EmittedClass) {
1637 createNullGlobal(
".objc_null_cls_init_ref", NULLPtr,
1638 sectionName<ClassSection>());
1639 createNullGlobal(
".objc_null_class_ref", { NULLPtr, NULLPtr },
1640 sectionName<ClassReferenceSection>());
1642 if (!EmittedProtocol)
1643 createNullGlobal(
".objc_null_protocol", {NULLPtr, NULLPtr, NULLPtr,
1644 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr,
1645 NULLPtr}, sectionName<ProtocolSection>());
1646 if (!EmittedProtocolRef)
1647 createNullGlobal(
".objc_null_protocol_ref", {NULLPtr},
1648 sectionName<ProtocolReferenceSection>());
1649 if (ClassAliases.empty())
1650 createNullGlobal(
".objc_null_class_alias", { NULLPtr, NULLPtr },
1651 sectionName<ClassAliasSection>());
1652 if (ConstantStrings.empty()) {
1653 auto i32Zero = llvm::ConstantInt::get(Int32Ty, 0);
1654 createNullGlobal(
".objc_null_constant_string", { NULLPtr, i32Zero,
1655 i32Zero, i32Zero, i32Zero, NULLPtr },
1656 sectionName<ConstantStringSection>());
1659 ConstantStrings.clear();
1663 if (EarlyInitList.size() > 0) {
1664 auto *
Init = llvm::Function::Create(llvm::FunctionType::get(CGM.
VoidTy,
1665 {}), llvm::GlobalValue::InternalLinkage,
".objc_early_init",
1667 llvm::IRBuilder<>
b(llvm::BasicBlock::Create(CGM.
getLLVMContext(),
"entry",
1669 for (
const auto &lateInit : EarlyInitList) {
1670 auto *global = TheModule.getGlobalVariable(lateInit.first);
1672 llvm::GlobalVariable *GV = lateInit.second.first;
1673 b.CreateAlignedStore(
1675 b.CreateStructGEP(GV->getValueType(), GV, lateInit.second.second),
1682 auto *InitVar =
new llvm::GlobalVariable(CGM.
getModule(),
Init->getType(),
1683 true, llvm::GlobalValue::InternalLinkage,
1684 Init,
".objc_early_init_ptr");
1685 InitVar->setSection(
".CRT$XCLb");
1694 std::string TypeEncoding;
1696 TypeEncoding = GetSymbolNameForTypeEncoding(TypeEncoding);
1697 const std::string Name =
"__objc_ivar_offset_" +
ID->getNameAsString()
1705 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
1706 if (!IvarOffsetPointer)
1707 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule, IntTy,
false,
1708 llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
1710 llvm::Value *Offset =
1712 if (Offset->getType() != PtrDiffTy)
1713 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
1718 bool IsCOFF = CGM.
getTriple().isOSBinFormatCOFF();
1724 auto *classNameConstant = MakeConstantString(className);
1727 auto metaclassFields = builder.beginStruct();
1729 metaclassFields.addNullPointer(PtrTy);
1731 metaclassFields.addNullPointer(PtrTy);
1733 metaclassFields.add(classNameConstant);
1735 metaclassFields.addInt(LongTy, 0);
1738 metaclassFields.addInt(LongTy, ClassFlags::ClassFlagMeta);
1742 metaclassFields.addInt(LongTy, 0);
1744 metaclassFields.addNullPointer(PtrTy);
1749 metaclassFields.addNullPointer(PtrTy);
1754 metaclassFields.add(
1755 GenerateMethodList(className,
"", ClassMethods,
true));
1758 metaclassFields.addNullPointer(PtrTy);
1760 metaclassFields.addNullPointer(PtrTy);
1762 metaclassFields.addNullPointer(PtrTy);
1764 metaclassFields.addNullPointer(PtrTy);
1766 metaclassFields.addNullPointer(PtrTy);
1768 metaclassFields.addNullPointer(PtrTy);
1770 metaclassFields.addNullPointer(PtrTy);
1772 metaclassFields.addInt(LongTy, 0);
1774 metaclassFields.add(GeneratePropertyList(OID, classDecl,
true));
1776 auto *metaclass = metaclassFields.finishAndCreateGlobal(
1777 ManglePublicSymbol(
"OBJC_METACLASS_") + className,
1780 auto classFields = builder.beginStruct();
1782 classFields.add(metaclass);
1787 llvm::Constant *SuperClass =
nullptr;
1788 if (SuperClassDecl) {
1789 auto SuperClassName = SymbolForClass(SuperClassDecl->
getNameAsString());
1790 SuperClass = TheModule.getNamedGlobal(SuperClassName);
1793 SuperClass =
new llvm::GlobalVariable(TheModule, PtrTy,
false,
1794 llvm::GlobalValue::ExternalLinkage,
nullptr, SuperClassName);
1796 auto Storage = llvm::GlobalValue::DefaultStorageClass;
1797 if (SuperClassDecl->
hasAttr<DLLImportAttr>())
1798 Storage = llvm::GlobalValue::DLLImportStorageClass;
1799 else if (SuperClassDecl->
hasAttr<DLLExportAttr>())
1800 Storage = llvm::GlobalValue::DLLExportStorageClass;
1802 cast<llvm::GlobalValue>(SuperClass)->setDLLStorageClass(Storage);
1806 classFields.add(SuperClass);
1808 classFields.addNullPointer(PtrTy);
1810 classFields.addNullPointer(PtrTy);
1812 classFields.add(classNameConstant);
1814 classFields.addInt(LongTy, 0);
1817 classFields.addInt(LongTy, 0);
1819 int superInstanceSize = !SuperClassDecl ? 0 :
1823 classFields.addInt(LongTy,
1825 superInstanceSize));
1828 classFields.addNullPointer(PtrTy);
1833 llvm::DataLayout td(&TheModule);
1836 auto ivarListBuilder =
b.beginStruct();
1838 ivarListBuilder.addInt(IntTy, ivar_count);
1840 llvm::StructType *ObjCIvarTy = llvm::StructType::get(
1846 ivarListBuilder.addInt(SizeTy, td.getTypeSizeInBits(ObjCIvarTy) /
1849 auto ivarArrayBuilder = ivarListBuilder.beginArray();
1852 auto ivarTy = IVD->getType();
1853 auto ivarBuilder = ivarArrayBuilder.beginStruct();
1855 ivarBuilder.add(MakeConstantString(IVD->getNameAsString()));
1857 std::string TypeStr;
1860 ivarBuilder.add(MakeConstantString(TypeStr));
1862 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
1863 uint64_t Offset = BaseOffset - superInstanceSize;
1864 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
1865 std::string OffsetName = GetIVarOffsetVariableName(classDecl, IVD);
1866 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
1868 OffsetVar->setInitializer(OffsetValue);
1870 OffsetVar =
new llvm::GlobalVariable(TheModule, IntTy,
1871 false, llvm::GlobalValue::ExternalLinkage,
1872 OffsetValue, OffsetName);
1873 auto ivarVisibility =
1877 llvm::GlobalValue::HiddenVisibility :
1878 llvm::GlobalValue::DefaultVisibility;
1879 OffsetVar->setVisibility(ivarVisibility);
1880 if (ivarVisibility != llvm::GlobalValue::HiddenVisibility)
1882 ivarBuilder.add(OffsetVar);
1884 ivarBuilder.addInt(Int32Ty,
1895 ivarBuilder.addInt(Int32Ty,
1896 (align << 3) | (1<<2) |
1897 FlagsForOwnership(ivarTy.getQualifiers().getObjCLifetime()));
1898 ivarBuilder.finishAndAddTo(ivarArrayBuilder);
1900 ivarArrayBuilder.finishAndAddTo(ivarListBuilder);
1901 auto ivarList = ivarListBuilder.finishAndCreateGlobal(
".objc_ivar_list",
1903 llvm::GlobalValue::PrivateLinkage);
1904 classFields.add(ivarList);
1908 InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
1911 if (propImpl->getPropertyImplementation() ==
1914 if (OMD && OMD->hasBody())
1915 InstanceMethods.push_back(OMD);
1917 addIfExists(propImpl->getGetterMethodDecl());
1918 addIfExists(propImpl->getSetterMethodDecl());
1921 if (InstanceMethods.size() == 0)
1922 classFields.addNullPointer(PtrTy);
1925 GenerateMethodList(className,
"", InstanceMethods,
false));
1928 classFields.addNullPointer(PtrTy);
1930 classFields.addNullPointer(PtrTy);
1932 classFields.addNullPointer(PtrTy);
1934 classFields.addNullPointer(PtrTy);
1936 classFields.addNullPointer(PtrTy);
1938 auto RuntimeProtocols = GetRuntimeProtocolList(classDecl->
protocol_begin(),
1941 for (
const auto *I : RuntimeProtocols)
1942 Protocols.push_back(GenerateProtocolRef(I));
1944 if (Protocols.empty())
1945 classFields.addNullPointer(PtrTy);
1947 classFields.add(GenerateProtocolList(Protocols));
1949 classFields.addNullPointer(PtrTy);
1951 classFields.addInt(LongTy, 0);
1953 classFields.add(GeneratePropertyList(OID, classDecl));
1955 llvm::GlobalVariable *classStruct =
1956 classFields.finishAndCreateGlobal(SymbolForClass(className),
1959 auto *classRefSymbol = GetClassVar(className);
1960 classRefSymbol->setSection(sectionName<ClassReferenceSection>());
1961 classRefSymbol->setInitializer(classStruct);
1966 classStruct->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1967 cast<llvm::GlobalValue>(classRefSymbol)->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1971 std::pair<llvm::GlobalVariable*, int>
v{classStruct, 1};
1972 EarlyInitList.emplace_back(std::string(SuperClass->getName()),
1981 if (ClassPtrAlias) {
1982 ClassPtrAlias->replaceAllUsesWith(classStruct);
1983 ClassPtrAlias->eraseFromParent();
1984 ClassPtrAlias =
nullptr;
1986 if (
auto Placeholder =
1987 TheModule.getNamedGlobal(SymbolForClass(className)))
1988 if (Placeholder != classStruct) {
1989 Placeholder->replaceAllUsesWith(classStruct);
1990 Placeholder->eraseFromParent();
1991 classStruct->setName(SymbolForClass(className));
1993 if (MetaClassPtrAlias) {
1994 MetaClassPtrAlias->replaceAllUsesWith(metaclass);
1995 MetaClassPtrAlias->eraseFromParent();
1996 MetaClassPtrAlias =
nullptr;
1998 assert(classStruct->getName() == SymbolForClass(className));
2000 auto classInitRef =
new llvm::GlobalVariable(TheModule,
2001 classStruct->getType(),
false, llvm::GlobalValue::ExternalLinkage,
2002 classStruct, ManglePublicSymbol(
"OBJC_INIT_CLASS_") + className);
2003 classInitRef->setSection(sectionName<ClassSection>());
2006 EmittedClass =
true;
2009 CGObjCGNUstep2(
CodeGenModule &Mod) : CGObjCGNUstep(Mod, 10, 4, 2) {
2010 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
2011 PtrToObjCSuperTy, SelectorTy);
2012 SentInitializeFn.init(&CGM,
"objc_send_initialize",
2013 llvm::Type::getVoidTy(VMContext), IdTy);
2022 PropertyMetadataTy =
2024 { PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty });
2027 void GenerateDirectMethodPrologue(
CodeGenFunction &CGF, llvm::Function *Fn,
2031 bool ReceiverCanBeNull =
true;
2033 auto selfValue = Builder.CreateLoad(selfAddr);
2058 ReceiverCanBeNull = isWeakLinkedClass(OID);
2062 if (ReceiverCanBeNull) {
2063 llvm::BasicBlock *SelfIsNilBlock =
2065 llvm::BasicBlock *ContBlock =
2069 auto selfTy = cast<llvm::PointerType>(selfValue->getType());
2070 auto Zero = llvm::ConstantPointerNull::get(selfTy);
2072 Builder.CreateCondBr(Builder.CreateICmpEQ(selfValue, Zero),
2073 SelfIsNilBlock, ContBlock,
2074 MDHelper.createBranchWeights(1, 1 << 20));
2080 Builder.SetInsertPoint(SelfIsNilBlock);
2081 if (!retTy->isVoidType()) {
2089 Builder.SetInsertPoint(ContBlock);
2095 llvm::StructType::get(PtrTy, PtrTy, PtrTy, LongTy, LongTy);
2097 auto flags = Builder.CreateLoad(
2098 Address{Builder.CreateStructGEP(classStart, selfValue, 4), LongTy,
2100 astContext.getTypeAlign(astContext.UnsignedLongTy))});
2101 auto isInitialized =
2102 Builder.CreateAnd(flags, ClassFlags::ClassFlagInitialized);
2103 llvm::BasicBlock *notInitializedBlock =
2105 llvm::BasicBlock *initializedBlock =
2107 Builder.CreateCondBr(Builder.CreateICmpEQ(isInitialized, Zeros[0]),
2108 notInitializedBlock, initializedBlock,
2109 MDHelper.createBranchWeights(1, 1 << 20));
2111 Builder.SetInsertPoint(notInitializedBlock);
2113 Builder.CreateBr(initializedBlock);
2115 Builder.SetInsertPoint(initializedBlock);
2123 Builder.CreateStore(GetSelector(CGF, OMD),
2129const char *
const CGObjCGNUstep2::SectionsBaseNames[8] =
2136"__objc_protocol_refs",
2137"__objc_class_aliases",
2138"__objc_constant_string"
2141const char *
const CGObjCGNUstep2::PECOFFSectionsBaseNames[8] =
2154class CGObjCObjFW:
public CGObjCGNU {
2158 LazyRuntimeFunction MsgLookupFn;
2161 LazyRuntimeFunction MsgLookupFnSRet;
2165 LazyRuntimeFunction MsgLookupSuperFn, MsgLookupSuperFnSRet;
2168 llvm::Value *cmd, llvm::MDNode *node,
2169 MessageSendInfo &MSI)
override {
2171 llvm::Value *args[] = {
2172 EnforceType(Builder, Receiver, IdTy),
2173 EnforceType(Builder, cmd, SelectorTy) };
2175 llvm::CallBase *imp;
2181 imp->setMetadata(msgSendMDKind, node);
2186 llvm::Value *cmd, MessageSendInfo &MSI)
override {
2188 llvm::Value *lookupArgs[] = {
2189 EnforceType(Builder, ObjCSuper.
getPointer(), PtrToObjCSuperTy), cmd,
2198 llvm::Value *GetClassNamed(
CodeGenFunction &CGF,
const std::string &Name,
2199 bool isWeak)
override {
2201 return CGObjCGNU::GetClassNamed(CGF, Name, isWeak);
2204 std::string SymbolName =
"_OBJC_CLASS_" + Name;
2205 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(SymbolName);
2207 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
2208 llvm::GlobalValue::ExternalLinkage,
2209 nullptr, SymbolName);
2216 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
2217 MsgLookupFnSRet.init(&CGM,
"objc_msg_lookup_stret", IMPTy, IdTy,
2220 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
2221 PtrToObjCSuperTy, SelectorTy);
2222 MsgLookupSuperFnSRet.init(&CGM,
"objc_msg_lookup_super_stret", IMPTy,
2223 PtrToObjCSuperTy, SelectorTy);
2231void CGObjCGNU::EmitClassRef(
const std::string &className) {
2232 std::string symbolRef =
"__objc_class_ref_" + className;
2234 if (TheModule.getGlobalVariable(symbolRef))
2236 std::string symbolName =
"__objc_class_name_" + className;
2237 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
2239 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
2240 llvm::GlobalValue::ExternalLinkage,
2241 nullptr, symbolName);
2243 new llvm::GlobalVariable(TheModule, ClassSymbol->getType(),
true,
2244 llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef);
2247CGObjCGNU::CGObjCGNU(
CodeGenModule &cgm,
unsigned runtimeABIVersion,
2248 unsigned protocolClassVersion,
unsigned classABI)
2250 VMContext(cgm.getLLVMContext()), ClassPtrAlias(nullptr),
2251 MetaClassPtrAlias(nullptr), RuntimeVersion(runtimeABIVersion),
2252 ProtocolVersion(protocolClassVersion), ClassABIVersion(classABI) {
2254 msgSendMDKind = VMContext.getMDKindID(
"GNUObjCMessageSend");
2262 IntTy = cast<llvm::IntegerType>(
2264 LongTy = cast<llvm::IntegerType>(
2266 SizeTy = cast<llvm::IntegerType>(
2268 PtrDiffTy = cast<llvm::IntegerType>(
2272 Int8Ty = llvm::Type::getInt8Ty(VMContext);
2274 PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
2275 ProtocolPtrTy = llvm::PointerType::getUnqual(
2278 Zeros[0] = llvm::ConstantInt::get(LongTy, 0);
2279 Zeros[1] = Zeros[0];
2280 NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty);
2284 SelectorTy = PtrToInt8Ty;
2285 SelectorElemTy = Int8Ty;
2291 PtrToIntTy = llvm::PointerType::getUnqual(IntTy);
2292 PtrTy = PtrToInt8Ty;
2294 Int32Ty = llvm::Type::getInt32Ty(VMContext);
2295 Int64Ty = llvm::Type::getInt64Ty(VMContext);
2298 CGM.
getDataLayout().getPointerSizeInBits() == 32 ? Int32Ty : Int64Ty;
2312 PtrToIdTy = llvm::PointerType::getUnqual(IdTy);
2313 ProtocolTy = llvm::StructType::get(IdTy,
2335 PropertyMetadataTy = llvm::StructType::get(CGM.
getLLVMContext(), {
2336 PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty,
2337 PtrToInt8Ty, PtrToInt8Ty });
2339 ObjCSuperTy = llvm::StructType::get(IdTy, IdTy);
2340 PtrToObjCSuperTy = llvm::PointerType::getUnqual(ObjCSuperTy);
2342 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
2345 ExceptionThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy);
2346 ExceptionReThrowFn.init(&CGM,
2347 usesCxxExceptions ?
"objc_exception_rethrow"
2348 :
"objc_exception_throw",
2351 SyncEnterFn.init(&CGM,
"objc_sync_enter", IntTy, IdTy);
2353 SyncExitFn.init(&CGM,
"objc_sync_exit", IntTy, IdTy);
2356 EnumerationMutationFn.init(&CGM,
"objc_enumerationMutation", VoidTy, IdTy);
2359 GetPropertyFn.init(&CGM,
"objc_getProperty", IdTy, IdTy, SelectorTy,
2362 SetPropertyFn.init(&CGM,
"objc_setProperty", VoidTy, IdTy, SelectorTy,
2363 PtrDiffTy, IdTy, BoolTy, BoolTy);
2365 GetStructPropertyFn.init(&CGM,
"objc_getPropertyStruct", VoidTy, PtrTy, PtrTy,
2366 PtrDiffTy, BoolTy, BoolTy);
2368 SetStructPropertyFn.init(&CGM,
"objc_setPropertyStruct", VoidTy, PtrTy, PtrTy,
2369 PtrDiffTy, BoolTy, BoolTy);
2372 llvm::Type *IMPArgs[] = { IdTy, SelectorTy };
2373 IMPTy = llvm::PointerType::getUnqual(llvm::FunctionType::get(IdTy, IMPArgs,
2377 if ((Opts.getGC() != LangOptions::NonGC) || Opts.ObjCAutoRefCount)
2378 RuntimeVersion = 10;
2381 if (Opts.getGC() != LangOptions::NonGC) {
2393 IvarAssignFn.init(&CGM,
"objc_assign_ivar", IdTy, IdTy, IdTy, PtrDiffTy);
2395 StrongCastAssignFn.init(&CGM,
"objc_assign_strongCast", IdTy, IdTy,
2398 GlobalAssignFn.init(&CGM,
"objc_assign_global", IdTy, IdTy, PtrToIdTy);
2400 WeakAssignFn.init(&CGM,
"objc_assign_weak", IdTy, IdTy, PtrToIdTy);
2402 WeakReadFn.init(&CGM,
"objc_read_weak", IdTy, PtrToIdTy);
2404 MemMoveFn.init(&CGM,
"objc_memmove_collectable", PtrTy, PtrTy, PtrTy,
2410 const std::string &Name,
bool isWeak) {
2411 llvm::Constant *ClassName = MakeConstantString(Name);
2423 llvm::FunctionType::get(IdTy, PtrToInt8Ty,
true),
"objc_lookup_class");
2433 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value))
2438llvm::Value *CGObjCGNU::EmitNSAutoreleasePoolClassRef(
CodeGenFunction &CGF) {
2439 auto *
Value = GetClassNamed(CGF,
"NSAutoreleasePool",
false);
2440 if (CGM.
getTriple().isOSBinFormatCOFF()) {
2441 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value)) {
2447 for (
const auto *Result : DC->
lookup(&II))
2448 if ((VD = dyn_cast<VarDecl>(Result)))
2458 const std::string &TypeEncoding) {
2460 llvm::GlobalAlias *SelValue =
nullptr;
2463 e = Types.end() ; i!=e ; i++) {
2464 if (i->first == TypeEncoding) {
2465 SelValue = i->second;
2470 SelValue = llvm::GlobalAlias::create(SelectorElemTy, 0,
2471 llvm::GlobalValue::PrivateLinkage,
2474 Types.emplace_back(TypeEncoding, SelValue);
2481 llvm::Value *SelValue = GetSelector(CGF, Sel);
2492 return GetTypedSelector(CGF, Sel, std::string());
2498 return GetTypedSelector(CGF, Method->
getSelector(), SelTypes);
2501llvm::Constant *CGObjCGNU::GetEHType(
QualType T) {
2508 return MakeConstantString(
"@id");
2516 assert(OPT &&
"Invalid @catch type.");
2518 assert(IDecl &&
"Invalid @catch type.");
2522llvm::Constant *CGObjCGNUstep::GetEHType(
QualType T) {
2523 if (usesSEHExceptions)
2526 if (!CGM.
getLangOpts().CPlusPlus && !usesCxxExceptions)
2527 return CGObjCGNU::GetEHType(T);
2535 llvm::Constant *IDEHType =
2536 CGM.
getModule().getGlobalVariable(
"__objc_id_type_info");
2539 new llvm::GlobalVariable(CGM.
getModule(), PtrToInt8Ty,
2541 llvm::GlobalValue::ExternalLinkage,
2542 nullptr,
"__objc_id_type_info");
2548 assert(PT &&
"Invalid @catch type.");
2550 assert(IT &&
"Invalid @catch type.");
2551 std::string className =
2554 std::string typeinfoName =
"__objc_eh_typeinfo_" + className;
2557 if (llvm::Constant *typeinfo = TheModule.getGlobalVariable(typeinfoName))
2565 const char *vtableName =
"_ZTVN7gnustep7libobjc22__objc_class_type_infoE";
2566 auto *Vtable = TheModule.getGlobalVariable(vtableName);
2568 Vtable =
new llvm::GlobalVariable(TheModule, PtrToInt8Ty,
true,
2569 llvm::GlobalValue::ExternalLinkage,
2570 nullptr, vtableName);
2572 llvm::Constant *Two = llvm::ConstantInt::get(IntTy, 2);
2574 llvm::ConstantExpr::getGetElementPtr(Vtable->getValueType(), Vtable, Two);
2576 llvm::Constant *typeName =
2577 ExportUniqueString(className,
"__objc_eh_typename_");
2580 auto fields = builder.beginStruct();
2581 fields.add(BVtable);
2582 fields.add(typeName);
2583 llvm::Constant *TI =
2584 fields.finishAndCreateGlobal(
"__objc_eh_typeinfo_" + className,
2587 llvm::GlobalValue::LinkOnceODRLinkage);
2594 std::string Str = SL->
getString().str();
2598 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
2599 if (old != ObjCStrings.end())
2604 if (StringClass.empty()) StringClass =
"NSConstantString";
2606 std::string Sym =
"_OBJC_CLASS_";
2609 llvm::Constant *
isa = TheModule.getNamedGlobal(Sym);
2612 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
2613 llvm::GlobalValue::ExternalWeakLinkage,
2617 auto Fields = Builder.beginStruct();
2619 Fields.add(MakeConstantString(Str));
2620 Fields.addInt(IntTy, Str.size());
2622 ObjCStrings[Str] = ObjCStr;
2623 ConstantStrings.push_back(ObjCStr);
2636 bool isCategoryImpl,
2637 llvm::Value *Receiver,
2638 bool IsClassMessage,
2642 if (CGM.
getLangOpts().getGC() == LangOptions::GCOnly) {
2643 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2647 if (Sel == ReleaseSel) {
2652 llvm::Value *cmd = GetSelector(CGF, Sel);
2655 ActualArgs.
add(
RValue::get(EnforceType(Builder, Receiver, IdTy)), ASTIdTy);
2659 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2661 llvm::Value *ReceiverClass =
nullptr;
2664 ReceiverClass = GetClassNamed(CGF,
2665 Class->getSuperClass()->getNameAsString(),
false);
2666 if (IsClassMessage) {
2668 ReceiverClass = Builder.CreateBitCast(ReceiverClass,
2669 llvm::PointerType::getUnqual(IdTy));
2671 Builder.CreateAlignedLoad(IdTy, ReceiverClass, CGF.
getPointerAlign());
2673 ReceiverClass = EnforceType(Builder, ReceiverClass, IdTy);
2675 if (isCategoryImpl) {
2676 llvm::FunctionCallee classLookupFunction =
nullptr;
2677 if (IsClassMessage) {
2679 IdTy, PtrTy,
true),
"objc_get_meta_class");
2682 IdTy, PtrTy,
true),
"objc_get_class");
2684 ReceiverClass = Builder.CreateCall(classLookupFunction,
2685 MakeConstantString(
Class->getNameAsString()));
2692 if (IsClassMessage) {
2693 if (!MetaClassPtrAlias) {
2694 MetaClassPtrAlias = llvm::GlobalAlias::create(
2695 IdElemTy, 0, llvm::GlobalValue::InternalLinkage,
2696 ".objc_metaclass_ref" +
Class->getNameAsString(), &TheModule);
2698 ReceiverClass = MetaClassPtrAlias;
2700 if (!ClassPtrAlias) {
2701 ClassPtrAlias = llvm::GlobalAlias::create(
2702 IdElemTy, 0, llvm::GlobalValue::InternalLinkage,
2703 ".objc_class_ref" +
Class->getNameAsString(), &TheModule);
2705 ReceiverClass = ClassPtrAlias;
2709 llvm::Type *CastTy = llvm::StructType::get(IdTy, IdTy);
2710 ReceiverClass = Builder.CreateBitCast(ReceiverClass,
2711 llvm::PointerType::getUnqual(CastTy));
2713 ReceiverClass = Builder.CreateStructGEP(CastTy, ReceiverClass, 1);
2716 Builder.CreateAlignedLoad(IdTy, ReceiverClass, CGF.
getPointerAlign());
2719 llvm::StructType *ObjCSuperTy =
2720 llvm::StructType::get(Receiver->getType(), IdTy);
2725 Builder.CreateStore(Receiver, Builder.CreateStructGEP(ObjCSuper, 0));
2726 Builder.CreateStore(ReceiverClass, Builder.CreateStructGEP(ObjCSuper, 1));
2729 llvm::Value *imp = LookupIMPSuper(CGF, ObjCSuper, cmd, MSI);
2730 imp = EnforceType(Builder, imp, MSI.MessengerType);
2732 llvm::Metadata *impMD[] = {
2733 llvm::MDString::get(VMContext, Sel.
getAsString()),
2734 llvm::MDString::get(VMContext,
Class->getSuperClass()->getNameAsString()),
2735 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2736 llvm::Type::getInt1Ty(VMContext), IsClassMessage))};
2737 llvm::MDNode *
node = llvm::MDNode::get(VMContext, impMD);
2741 llvm::CallBase *call;
2742 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2743 call->setMetadata(msgSendMDKind, node);
2753 llvm::Value *Receiver,
2760 if (CGM.
getLangOpts().getGC() == LangOptions::GCOnly) {
2761 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2765 if (Sel == ReleaseSel) {
2776 cmd = GetSelector(CGF, Method);
2778 cmd = GetSelector(CGF, Sel);
2779 cmd = EnforceType(Builder, cmd, SelectorTy);
2782 Receiver = EnforceType(Builder, Receiver, IdTy);
2784 llvm::Metadata *impMD[] = {
2785 llvm::MDString::get(VMContext, Sel.
getAsString()),
2786 llvm::MDString::get(VMContext, Class ?
Class->getNameAsString() :
""),
2787 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2788 llvm::Type::getInt1Ty(VMContext), Class !=
nullptr))};
2789 llvm::MDNode *
node = llvm::MDNode::get(VMContext, impMD);
2797 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2818 bool hasParamDestroyedInCallee =
false;
2819 bool requiresExplicitZeroResult =
false;
2820 bool requiresNilReceiverCheck = [&] {
2822 if (!canMessageReceiverBeNull(CGF, Method,
false,
2828 hasParamDestroyedInCallee =
true;
2849 requiresExplicitZeroResult = !isDirect;
2853 return hasParamDestroyedInCallee || requiresExplicitZeroResult;
2859 bool requiresExplicitAggZeroing =
2863 llvm::BasicBlock *continueBB =
nullptr;
2865 llvm::BasicBlock *nilPathBB =
nullptr;
2867 llvm::BasicBlock *nilCleanupBB =
nullptr;
2870 if (requiresNilReceiverCheck) {
2877 if (requiresExplicitAggZeroing || hasParamDestroyedInCallee) {
2880 nilPathBB = Builder.GetInsertBlock();
2883 llvm::Value *isNil = Builder.CreateICmpEQ(Receiver,
2884 llvm::Constant::getNullValue(Receiver->getType()));
2885 Builder.CreateCondBr(isNil, nilCleanupBB ? nilCleanupBB : continueBB,
2902 imp = LookupIMP(CGF, Receiver, cmd, node, MSI);
2909 "objc_msgSend_fpret")
2916 "objc_msgSend_stret")
2920 llvm::FunctionType::get(IdTy, IdTy,
true),
"objc_msgSend")
2928 imp = EnforceType(Builder, imp, MSI.MessengerType);
2930 llvm::CallBase *call;
2932 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2934 call->setMetadata(msgSendMDKind, node);
2936 if (requiresNilReceiverCheck) {
2937 llvm::BasicBlock *nonNilPathBB = CGF.
Builder.GetInsertBlock();
2938 CGF.
Builder.CreateBr(continueBB);
2944 if (hasParamDestroyedInCallee) {
2945 destroyCalleeDestroyedArguments(CGF, Method, CallArgs);
2948 if (requiresExplicitAggZeroing) {
2954 nilPathBB = CGF.
Builder.GetInsertBlock();
2955 CGF.
Builder.CreateBr(continueBB);
2963 llvm::PHINode *phi = Builder.CreatePHI(
v->getType(), 2);
2964 phi->addIncoming(
v, nonNilPathBB);
2972 llvm::PHINode *phi = Builder.CreatePHI(
v.first->getType(), 2);
2973 phi->addIncoming(
v.first, nonNilPathBB);
2974 phi->addIncoming(llvm::Constant::getNullValue(
v.first->getType()),
2976 llvm::PHINode *phi2 = Builder.CreatePHI(
v.second->getType(), 2);
2977 phi2->addIncoming(
v.second, nonNilPathBB);
2978 phi2->addIncoming(llvm::Constant::getNullValue(
v.second->getType()),
2988llvm::Constant *CGObjCGNU::
2989GenerateMethodList(StringRef ClassName,
2990 StringRef CategoryName,
2992 bool isClassMethodList) {
2993 if (Methods.empty())
2998 auto MethodList = Builder.beginStruct();
2999 MethodList.addNullPointer(CGM.
Int8PtrTy);
3000 MethodList.addInt(Int32Ty, Methods.size());
3003 llvm::StructType *ObjCMethodTy =
3012 llvm::DataLayout td(&TheModule);
3013 MethodList.addInt(SizeTy, td.getTypeSizeInBits(ObjCMethodTy) /
3029 auto MethodArray = MethodList.beginArray();
3031 for (
const auto *OMD : Methods) {
3032 llvm::Constant *FnPtr =
3033 TheModule.getFunction(getSymbolNameForMethod(OMD));
3034 assert(FnPtr &&
"Can't generate metadata for method that doesn't exist");
3035 auto Method = MethodArray.beginStruct(ObjCMethodTy);
3046 Method.finishAndAddTo(MethodArray);
3048 MethodArray.finishAndAddTo(MethodList);
3051 return MethodList.finishAndCreateGlobal(
".objc_method_list",
3056llvm::Constant *CGObjCGNU::
3062 if (IvarNames.empty())
3068 auto IvarList = Builder.beginStruct();
3069 IvarList.addInt(IntTy, (
int)IvarNames.size());
3072 llvm::StructType *ObjCIvarTy =
3073 llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, IntTy);
3076 auto Ivars = IvarList.beginArray(ObjCIvarTy);
3077 for (
unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {
3078 auto Ivar = Ivars.beginStruct(ObjCIvarTy);
3079 Ivar.
add(IvarNames[i]);
3080 Ivar.
add(IvarTypes[i]);
3081 Ivar.
add(IvarOffsets[i]);
3082 Ivar.finishAndAddTo(Ivars);
3084 Ivars.finishAndAddTo(IvarList);
3087 return IvarList.finishAndCreateGlobal(
".objc_ivar_list",
3092llvm::Constant *CGObjCGNU::GenerateClassStructure(
3093 llvm::Constant *MetaClass,
3094 llvm::Constant *SuperClass,
3097 llvm::Constant *Version,
3098 llvm::Constant *InstanceSize,
3099 llvm::Constant *IVars,
3100 llvm::Constant *Methods,
3101 llvm::Constant *Protocols,
3102 llvm::Constant *IvarOffsets,
3103 llvm::Constant *Properties,
3104 llvm::Constant *StrongIvarBitmap,
3105 llvm::Constant *WeakIvarBitmap,
3114 llvm::StructType *ClassTy = llvm::StructType::get(
3131 IvarOffsets->getType(),
3132 Properties->getType(),
3138 auto Elements = Builder.beginStruct(ClassTy);
3143 Elements.add(MetaClass);
3145 Elements.add(SuperClass);
3147 Elements.add(MakeConstantString(Name,
".class_name"));
3149 Elements.addInt(LongTy, 0);
3151 Elements.addInt(LongTy, info);
3154 llvm::DataLayout td(&TheModule);
3155 Elements.addInt(LongTy,
3156 td.getTypeSizeInBits(ClassTy) /
3159 Elements.add(InstanceSize);
3161 Elements.add(IVars);
3163 Elements.add(Methods);
3166 Elements.add(NULLPtr);
3168 Elements.add(NULLPtr);
3170 Elements.add(NULLPtr);
3172 Elements.add(Protocols);
3174 Elements.add(NULLPtr);
3176 Elements.addInt(LongTy, ClassABIVersion);
3178 Elements.add(IvarOffsets);
3180 Elements.add(Properties);
3182 Elements.add(StrongIvarBitmap);
3184 Elements.add(WeakIvarBitmap);
3189 std::string ClassSym((isMeta ?
"_OBJC_METACLASS_":
"_OBJC_CLASS_") +
3191 llvm::GlobalVariable *ClassRef = TheModule.getNamedGlobal(ClassSym);
3192 llvm::Constant *
Class =
3193 Elements.finishAndCreateGlobal(ClassSym, CGM.
getPointerAlign(),
false,
3194 llvm::GlobalValue::ExternalLinkage);
3196 ClassRef->replaceAllUsesWith(Class);
3197 ClassRef->removeFromParent();
3198 Class->setName(ClassSym);
3203llvm::Constant *CGObjCGNU::
3206 llvm::StructType *ObjCMethodDescTy =
3207 llvm::StructType::get(CGM.
getLLVMContext(), { PtrToInt8Ty, PtrToInt8Ty });
3210 auto MethodList = Builder.beginStruct();
3211 MethodList.addInt(IntTy, Methods.size());
3212 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
3213 for (
auto *M : Methods) {
3214 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
3215 Method.
add(MakeConstantString(M->getSelector().getAsString()));
3217 Method.finishAndAddTo(MethodArray);
3219 MethodArray.finishAndAddTo(MethodList);
3220 return MethodList.finishAndCreateGlobal(
".objc_method_list",
3229 auto ProtocolList = Builder.beginStruct();
3230 ProtocolList.add(NULLPtr);
3231 ProtocolList.addInt(LongTy, Protocols.size());
3233 auto Elements = ProtocolList.beginArray(PtrToInt8Ty);
3234 for (
const std::string *iter = Protocols.begin(), *endIter = Protocols.end();
3235 iter != endIter ; iter++) {
3236 llvm::Constant *protocol =
nullptr;
3237 llvm::StringMap<llvm::Constant*>::iterator value =
3238 ExistingProtocols.find(*iter);
3239 if (value == ExistingProtocols.end()) {
3240 protocol = GenerateEmptyProtocol(*iter);
3242 protocol = value->getValue();
3244 Elements.add(protocol);
3246 Elements.finishAndAddTo(ProtocolList);
3247 return ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
3253 auto protocol = GenerateProtocolRef(PD);
3256 return CGF.
Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(T));
3259llvm::Constant *CGObjCGNU::GenerateProtocolRef(
const ObjCProtocolDecl *PD) {
3262 GenerateProtocol(PD);
3263 assert(protocol &&
"Unknown protocol");
3268CGObjCGNU::GenerateEmptyProtocol(StringRef ProtocolName) {
3269 llvm::Constant *ProtocolList = GenerateProtocolList({});
3270 llvm::Constant *MethodList = GenerateProtocolMethodList({});
3274 auto Elements = Builder.beginStruct();
3278 Elements.add(llvm::ConstantExpr::getIntToPtr(
3279 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3281 Elements.add(MakeConstantString(ProtocolName,
".objc_protocol_name"));
3282 Elements.add(ProtocolList);
3283 Elements.add(MethodList);
3284 Elements.add(MethodList);
3285 Elements.add(MethodList);
3286 Elements.add(MethodList);
3287 Elements.add(NULLPtr);
3288 Elements.add(NULLPtr);
3289 return Elements.finishAndCreateGlobal(SymbolForProtocol(ProtocolName),
3305 Protocols.push_back(PI->getNameAsString());
3309 if (I->isOptional())
3310 OptionalInstanceMethods.push_back(I);
3312 InstanceMethods.push_back(I);
3317 if (I->isOptional())
3318 OptionalClassMethods.push_back(I);
3320 ClassMethods.push_back(I);
3322 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
3323 llvm::Constant *InstanceMethodList =
3324 GenerateProtocolMethodList(InstanceMethods);
3325 llvm::Constant *ClassMethodList =
3326 GenerateProtocolMethodList(ClassMethods);
3327 llvm::Constant *OptionalInstanceMethodList =
3328 GenerateProtocolMethodList(OptionalInstanceMethods);
3329 llvm::Constant *OptionalClassMethodList =
3330 GenerateProtocolMethodList(OptionalClassMethods);
3338 llvm::Constant *PropertyList =
3339 GeneratePropertyList(
nullptr, PD,
false,
false);
3340 llvm::Constant *OptionalPropertyList =
3341 GeneratePropertyList(
nullptr, PD,
false,
true);
3348 auto Elements = Builder.beginStruct();
3350 llvm::ConstantExpr::getIntToPtr(
3351 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3352 Elements.add(MakeConstantString(ProtocolName));
3353 Elements.add(ProtocolList);
3354 Elements.add(InstanceMethodList);
3355 Elements.add(ClassMethodList);
3356 Elements.add(OptionalInstanceMethodList);
3357 Elements.add(OptionalClassMethodList);
3358 Elements.add(PropertyList);
3359 Elements.add(OptionalPropertyList);
3360 ExistingProtocols[ProtocolName] =
3361 Elements.finishAndCreateGlobal(
".objc_protocol", CGM.
getPointerAlign());
3363void CGObjCGNU::GenerateProtocolHolderCategory() {
3367 auto Elements = Builder.beginStruct();
3369 const std::string ClassName =
"__ObjC_Protocol_Holder_Ugly_Hack";
3370 const std::string CategoryName =
"AnotherHack";
3371 Elements.add(MakeConstantString(CategoryName));
3372 Elements.add(MakeConstantString(ClassName));
3374 Elements.add(GenerateMethodList(ClassName, CategoryName, {},
false));
3376 Elements.add(GenerateMethodList(ClassName, CategoryName, {},
true));
3380 auto ProtocolList = ProtocolListBuilder.beginStruct();
3381 ProtocolList.add(NULLPtr);
3382 ProtocolList.addInt(LongTy, ExistingProtocols.size());
3383 auto ProtocolElements = ProtocolList.beginArray(PtrTy);
3384 for (
auto iter = ExistingProtocols.begin(), endIter = ExistingProtocols.end();
3385 iter != endIter ; iter++) {
3386 ProtocolElements.add(iter->getValue());
3388 ProtocolElements.finishAndAddTo(ProtocolList);
3389 Elements.add(ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
3391 Categories.push_back(
3407 int bitCount = bits.size();
3409 if (bitCount < ptrBits) {
3411 for (
int i=0 ; i<bitCount ; ++i) {
3412 if (bits[i]) val |= 1ULL<<(i+1);
3414 return llvm::ConstantInt::get(IntPtrTy, val);
3418 while (
v < bitCount) {
3420 for (
int i=0 ; (i<32) && (
v<bitCount) ; ++i) {
3421 if (bits[
v]) word |= 1<<i;
3424 values.push_back(llvm::ConstantInt::get(Int32Ty, word));
3428 auto fields = builder.beginStruct();
3429 fields.addInt(Int32Ty, values.size());
3430 auto array = fields.beginArray();
3431 for (
auto *
v : values) array.add(
v);
3432 array.finishAndAddTo(fields);
3434 llvm::Constant *GS =
3436 llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy);
3440llvm::Constant *CGObjCGNU::GenerateCategoryProtocolList(
const
3443 const auto RuntimeProtos =
3444 GetRuntimeProtocolList(RefPro.begin(), RefPro.end());
3446 for (
const auto *PD : RuntimeProtos)
3448 return GenerateProtocolList(Protocols);
3453 std::string ClassName =
Class->getNameAsString();
3460 auto Elements = Builder.beginStruct();
3461 Elements.add(MakeConstantString(CategoryName));
3462 Elements.add(MakeConstantString(ClassName));
3465 InstanceMethods.insert(InstanceMethods.begin(), OCD->
instmeth_begin(),
3468 GenerateMethodList(ClassName, CategoryName, InstanceMethods,
false));
3475 Elements.add(GenerateMethodList(ClassName, CategoryName, ClassMethods,
true));
3478 Elements.add(GenerateCategoryProtocolList(CatDecl));
3484 Elements.add(GeneratePropertyList(OCD,
Category,
false));
3486 Elements.add(GeneratePropertyList(OCD,
Category,
true));
3488 Elements.addNullPointer(PtrTy);
3489 Elements.addNullPointer(PtrTy);
3493 Categories.push_back(Elements.finishAndCreateGlobal(
3494 std::string(
".objc_category_") + ClassName + CategoryName,
3498llvm::Constant *CGObjCGNU::GeneratePropertyList(
const Decl *Container,
3500 bool isClassProperty,
3501 bool protocolOptionalProperties) {
3505 bool isProtocol = isa<ObjCProtocolDecl>(OCD);
3508 std::function<void(
const ObjCProtocolDecl *Proto)> collectProtocolProperties
3510 for (
const auto *
P : Proto->protocols())
3511 collectProtocolProperties(
P);
3512 for (
const auto *PD : Proto->properties()) {
3513 if (isClassProperty != PD->isClassProperty())
3521 Properties.push_back(PD);
3527 for (
auto *PD : ClassExt->properties()) {
3528 if (isClassProperty != PD->isClassProperty())
3531 Properties.push_back(PD);
3535 if (isClassProperty != PD->isClassProperty())
3539 if (isProtocol && (protocolOptionalProperties != PD->isOptional()))
3546 Properties.push_back(PD);
3551 collectProtocolProperties(
P);
3553 for (
const auto *
P : CD->protocols())
3554 collectProtocolProperties(
P);
3556 auto numProperties = Properties.size();
3558 if (numProperties == 0)
3562 auto propertyList = builder.beginStruct();
3563 auto properties = PushPropertyListHeader(propertyList, numProperties);
3567 for (
auto *property : Properties) {
3568 bool isSynthesized =
false;
3569 bool isDynamic =
false;
3573 isSynthesized = (propertyImpl->getPropertyImplementation() ==
3575 isDynamic = (propertyImpl->getPropertyImplementation() ==
3579 PushProperty(properties, property, Container, isSynthesized, isDynamic);
3581 properties.finishAndAddTo(propertyList);
3583 return propertyList.finishAndCreateGlobal(
".objc_property_list",
3601 std::string SuperClassName;
3602 if (SuperClassDecl) {
3604 EmitClassRef(SuperClassName);
3614 std::string classSymbolName =
"__objc_class_name_" + ClassName;
3615 if (
auto *symbol = TheModule.getGlobalVariable(classSymbolName)) {
3616 symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0));
3618 new llvm::GlobalVariable(TheModule, LongTy,
false,
3619 llvm::GlobalValue::ExternalLinkage,
3620 llvm::ConstantInt::get(LongTy, 0),
3636 auto IvarOffsetValues = IvarOffsetBuilder.beginArray(PtrToIntTy);
3640 int superInstanceSize = !SuperClassDecl ? 0 :
3645 instanceSize = 0 - (instanceSize - superInstanceSize);
3651 IvarNames.push_back(MakeConstantString(IVD->getNameAsString()));
3653 std::string TypeStr;
3655 IvarTypes.push_back(MakeConstantString(TypeStr));
3656 IvarAligns.push_back(llvm::ConstantInt::get(IntTy,
3659 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
3662 Offset = BaseOffset - superInstanceSize;
3664 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
3666 std::string OffsetName =
"__objc_ivar_offset_value_" + ClassName +
"." +
3667 IVD->getNameAsString();
3669 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
3671 OffsetVar->setInitializer(OffsetValue);
3675 OffsetVar->setLinkage(llvm::GlobalValue::ExternalLinkage);
3677 OffsetVar =
new llvm::GlobalVariable(TheModule, Int32Ty,
3678 false, llvm::GlobalValue::ExternalLinkage,
3679 OffsetValue, OffsetName);
3680 IvarOffsets.push_back(OffsetValue);
3681 IvarOffsetValues.add(OffsetVar);
3683 IvarOwnership.push_back(lt);
3686 StrongIvars.push_back(
true);
3687 WeakIvars.push_back(
false);
3690 StrongIvars.push_back(
false);
3691 WeakIvars.push_back(
true);
3694 StrongIvars.push_back(
false);
3695 WeakIvars.push_back(
false);
3698 llvm::Constant *StrongIvarBitmap = MakeBitField(StrongIvars);
3699 llvm::Constant *WeakIvarBitmap = MakeBitField(WeakIvars);
3700 llvm::GlobalVariable *IvarOffsetArray =
3701 IvarOffsetValues.finishAndCreateGlobal(
".ivar.offsets",
3706 InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
3713 llvm::Constant *Properties = GeneratePropertyList(OID, ClassDecl);
3716 auto RefProtocols = ClassDecl->
protocols();
3717 auto RuntimeProtocols =
3718 GetRuntimeProtocolList(RefProtocols.begin(), RefProtocols.end());
3720 for (
const auto *I : RuntimeProtocols)
3721 Protocols.push_back(I->getNameAsString());
3724 llvm::Constant *SuperClass;
3725 if (!SuperClassName.empty()) {
3726 SuperClass = MakeConstantString(SuperClassName,
".super_class_name");
3728 SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty);
3733 llvm::Constant *MethodList = GenerateMethodList(ClassName,
"",
3734 InstanceMethods,
false);
3735 llvm::Constant *ClassMethodList = GenerateMethodList(ClassName,
"",
3736 ClassMethods,
true);
3737 llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
3738 IvarOffsets, IvarAligns, IvarOwnership);
3749 llvm::Type *IndexTy = Int32Ty;
3750 llvm::Constant *offsetPointerIndexes[] = {Zeros[0],
3751 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 2 : 1),
nullptr,
3752 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 3 : 2) };
3754 unsigned ivarIndex = 0;
3757 const std::string Name = GetIVarOffsetVariableName(ClassDecl, IVD);
3758 offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, ivarIndex);
3760 llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr(
3761 cast<llvm::GlobalVariable>(IvarList)->getValueType(), IvarList,
3762 offsetPointerIndexes);
3764 llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name);
3766 offset->setInitializer(offsetValue);
3770 offset->setLinkage(llvm::GlobalValue::ExternalLinkage);
3773 new llvm::GlobalVariable(TheModule, offsetValue->getType(),
3774 false, llvm::GlobalValue::ExternalLinkage, offsetValue, Name);
3777 llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0);
3780 llvm::Constant *MetaClassStruct = GenerateClassStructure(
3781 NULLPtr, NULLPtr, 0x12L, ClassName.c_str(),
nullptr, Zeros[0],
3782 NULLPtr, ClassMethodList, NULLPtr, NULLPtr,
3783 GeneratePropertyList(OID, ClassDecl,
true), ZeroPtr, ZeroPtr,
true);
3788 llvm::Constant *ClassStruct = GenerateClassStructure(
3789 MetaClassStruct, SuperClass, 0x11L, ClassName.c_str(),
nullptr,
3790 llvm::ConstantInt::get(LongTy, instanceSize), IvarList, MethodList,
3791 GenerateProtocolList(Protocols), IvarOffsetArray, Properties,
3792 StrongIvarBitmap, WeakIvarBitmap);
3797 if (ClassPtrAlias) {
3798 ClassPtrAlias->replaceAllUsesWith(ClassStruct);
3799 ClassPtrAlias->eraseFromParent();
3800 ClassPtrAlias =
nullptr;
3802 if (MetaClassPtrAlias) {
3803 MetaClassPtrAlias->replaceAllUsesWith(MetaClassStruct);
3804 MetaClassPtrAlias->eraseFromParent();
3805 MetaClassPtrAlias =
nullptr;
3809 Classes.push_back(ClassStruct);
3812llvm::Function *CGObjCGNU::ModuleInitFunction() {
3814 if (Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
3819 GenerateProtocolHolderCategory();
3821 llvm::StructType *selStructTy = dyn_cast<llvm::StructType>(SelectorElemTy);
3824 { PtrToInt8Ty, PtrToInt8Ty });
3828 llvm::Constant *statics = NULLPtr;
3829 if (!ConstantStrings.empty()) {
3830 llvm::GlobalVariable *fileStatics = [&] {
3832 auto staticsStruct = builder.beginStruct();
3835 if (stringClass.empty()) stringClass =
"NXConstantString";
3836 staticsStruct.add(MakeConstantString(stringClass,
3837 ".objc_static_class_name"));
3839 auto array = staticsStruct.beginArray();
3840 array.addAll(ConstantStrings);
3842 array.finishAndAddTo(staticsStruct);
3844 return staticsStruct.finishAndCreateGlobal(
".objc_statics",
3849 auto allStaticsArray = builder.beginArray(fileStatics->getType());
3850 allStaticsArray.add(fileStatics);
3851 allStaticsArray.addNullPointer(fileStatics->getType());
3853 statics = allStaticsArray.finishAndCreateGlobal(
".objc_statics_ptr",
3860 unsigned selectorCount;
3863 llvm::GlobalVariable *selectorList = [&] {
3865 auto selectors = builder.beginArray(selStructTy);
3867 std::vector<Selector> allSelectors;
3868 for (
auto &entry : table)
3869 allSelectors.push_back(entry.first);
3870 llvm::sort(allSelectors);
3872 for (
auto &untypedSel : allSelectors) {
3873 std::string selNameStr = untypedSel.getAsString();
3874 llvm::Constant *selName = ExportUniqueString(selNameStr,
".objc_sel_name");
3876 for (TypedSelector &sel : table[untypedSel]) {
3877 llvm::Constant *selectorTypeEncoding = NULLPtr;
3878 if (!sel.first.empty())
3879 selectorTypeEncoding =
3880 MakeConstantString(sel.first,
".objc_sel_types");
3882 auto selStruct = selectors.beginStruct(selStructTy);
3883 selStruct.add(selName);
3884 selStruct.add(selectorTypeEncoding);
3885 selStruct.finishAndAddTo(selectors);
3888 selectorAliases.push_back(sel.second);
3893 selectorCount = selectors.size();
3899 auto selStruct = selectors.beginStruct(selStructTy);
3900 selStruct.add(NULLPtr);
3901 selStruct.add(NULLPtr);
3902 selStruct.finishAndAddTo(selectors);
3904 return selectors.finishAndCreateGlobal(
".objc_selector_list",
3909 for (
unsigned i = 0; i < selectorCount; ++i) {
3910 llvm::Constant *idxs[] = {
3912 llvm::ConstantInt::get(Int32Ty, i)
3915 llvm::Constant *selPtr = llvm::ConstantExpr::getGetElementPtr(
3916 selectorList->getValueType(), selectorList, idxs);
3917 selectorAliases[i]->replaceAllUsesWith(selPtr);
3918 selectorAliases[i]->eraseFromParent();
3921 llvm::GlobalVariable *symtab = [&] {
3923 auto symtab = builder.beginStruct();
3926 symtab.addInt(LongTy, selectorCount);
3928 symtab.add(selectorList);
3931 symtab.addInt(CGM.
Int16Ty, Classes.size());
3933 symtab.addInt(CGM.
Int16Ty, Categories.size());
3936 auto classList = symtab.beginArray(PtrToInt8Ty);
3937 classList.addAll(Classes);
3938 classList.addAll(Categories);
3940 classList.add(statics);
3941 classList.add(NULLPtr);
3942 classList.finishAndAddTo(symtab);
3950 llvm::Constant *module = [&] {
3951 llvm::Type *moduleEltTys[] = {
3952 LongTy, LongTy, PtrToInt8Ty, symtab->getType(), IntTy
3954 llvm::StructType *moduleTy = llvm::StructType::get(
3956 ArrayRef(moduleEltTys).drop_back(
unsigned(RuntimeVersion < 10)));
3959 auto module = builder.beginStruct(moduleTy);
3961 module.addInt(LongTy, RuntimeVersion);
3963 module.addInt(LongTy, CGM.
getDataLayout().getTypeStoreSize(moduleTy));
3970 module.add(MakeConstantString(path,
".objc_source_file_name"));
3973 if (RuntimeVersion >= 10) {
3975 case LangOptions::GCOnly:
3976 module.addInt(IntTy, 2);
3978 case LangOptions::NonGC:
3980 module.addInt(IntTy, 1);
3982 module.addInt(IntTy, 0);
3984 case LangOptions::HybridGC:
3985 module.addInt(IntTy, 1);
3995 llvm::Function * LoadFunction = llvm::Function::Create(
3996 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
3997 llvm::GlobalValue::InternalLinkage,
".objc_load_function",
3999 llvm::BasicBlock *EntryBB =
4000 llvm::BasicBlock::Create(VMContext,
"entry", LoadFunction);
4002 Builder.SetInsertPoint(EntryBB);
4004 llvm::FunctionType *FT =
4005 llvm::FunctionType::get(Builder.getVoidTy(), module->getType(),
true);
4006 llvm::FunctionCallee Register =
4008 Builder.CreateCall(Register, module);
4010 if (!ClassAliases.empty()) {
4011 llvm::Type *ArgTypes[2] = {PtrTy, PtrToInt8Ty};
4012 llvm::FunctionType *RegisterAliasTy =
4013 llvm::FunctionType::get(Builder.getVoidTy(),
4015 llvm::Function *RegisterAlias = llvm::Function::Create(
4017 llvm::GlobalValue::ExternalWeakLinkage,
"class_registerAlias_np",
4019 llvm::BasicBlock *AliasBB =
4020 llvm::BasicBlock::Create(VMContext,
"alias", LoadFunction);
4021 llvm::BasicBlock *NoAliasBB =
4022 llvm::BasicBlock::Create(VMContext,
"no_alias", LoadFunction);
4025 llvm::Value *HasRegisterAlias = Builder.CreateICmpNE(RegisterAlias,
4026 llvm::Constant::getNullValue(RegisterAlias->getType()));
4027 Builder.CreateCondBr(HasRegisterAlias, AliasBB, NoAliasBB);
4030 Builder.SetInsertPoint(AliasBB);
4032 for (std::vector<ClassAliasPair>::iterator iter = ClassAliases.begin();
4033 iter != ClassAliases.end(); ++iter) {
4034 llvm::Constant *TheClass =
4035 TheModule.getGlobalVariable(
"_OBJC_CLASS_" + iter->first,
true);
4037 Builder.CreateCall(RegisterAlias,
4038 {TheClass, MakeConstantString(iter->second)});
4042 Builder.CreateBr(NoAliasBB);
4045 Builder.SetInsertPoint(NoAliasBB);
4047 Builder.CreateRetVoid();
4049 return LoadFunction;
4052llvm::Function *CGObjCGNU::GenerateMethod(
const ObjCMethodDecl *OMD,
4055 llvm::FunctionType *MethodTy =
4056 Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
4059 std::string FunctionName =
4060 getSymbolNameForMethod(OMD, !isDirect);
4063 return llvm::Function::Create(MethodTy,
4064 llvm::GlobalVariable::InternalLinkage,
4065 FunctionName, &TheModule);
4068 auto I = DirectMethodDefinitions.find(COMD);
4069 llvm::Function *OldFn =
nullptr, *Fn =
nullptr;
4071 if (I == DirectMethodDefinitions.end()) {
4073 llvm::Function::Create(MethodTy, llvm::GlobalVariable::ExternalLinkage,
4074 FunctionName, &TheModule);
4075 DirectMethodDefinitions.insert(std::make_pair(COMD, F));
4092 Fn = llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,
"",
4094 Fn->takeName(OldFn);
4095 OldFn->replaceAllUsesWith(Fn);
4096 OldFn->eraseFromParent();
4110llvm::FunctionCallee CGObjCGNU::GetPropertyGetFunction() {
4111 return GetPropertyFn;
4114llvm::FunctionCallee CGObjCGNU::GetPropertySetFunction() {
4115 return SetPropertyFn;
4118llvm::FunctionCallee CGObjCGNU::GetOptimizedPropertySetFunction(
bool atomic,
4123llvm::FunctionCallee CGObjCGNU::GetGetStructFunction() {
4124 return GetStructPropertyFn;
4127llvm::FunctionCallee CGObjCGNU::GetSetStructFunction() {
4128 return SetStructPropertyFn;
4131llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectGetFunction() {
4135llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectSetFunction() {
4139llvm::FunctionCallee CGObjCGNU::EnumerationMutationFunction() {
4140 return EnumerationMutationFn;
4145 EmitAtSynchronizedStmt(CGF, S, SyncEnterFn, SyncExitFn);
4162 EmitTryCatchStmt(CGF, S, EnterCatchFn, ExitCatchFn, ExceptionReThrowFn);
4167 bool ClearInsertionPoint) {
4168 llvm::Value *ExceptionAsObject;
4169 bool isRethrow =
false;
4171 if (
const Expr *ThrowExpr = S.getThrowExpr()) {
4173 ExceptionAsObject = Exception;
4176 "Unexpected rethrow outside @catch block.");
4180 if (isRethrow && (usesSEHExceptions || usesCxxExceptions)) {
4189 Throw->setDoesNotReturn();
4191 ExceptionAsObject = CGF.
Builder.CreateBitCast(ExceptionAsObject, IdTy);
4192 llvm::CallBase *Throw =
4194 Throw->setDoesNotReturn();
4196 CGF.
Builder.CreateUnreachable();
4197 if (ClearInsertionPoint)
4198 CGF.
Builder.ClearInsertionPoint();
4204 return B.CreateCall(WeakReadFn,
4205 EnforceType(B, AddrWeakObj.
getPointer(), PtrToIdTy));
4209 llvm::Value *src,
Address dst) {
4211 src = EnforceType(B, src, IdTy);
4212 llvm::Value *dstVal = EnforceType(B, dst.
getPointer(), PtrToIdTy);
4213 B.CreateCall(WeakAssignFn, {src, dstVal});
4217 llvm::Value *src,
Address dst,
4220 src = EnforceType(B, src, IdTy);
4221 llvm::Value *dstVal = EnforceType(B, dst.
getPointer(), PtrToIdTy);
4223 assert(!threadlocal &&
"EmitObjCGlobalAssign - Threal Local API NYI");
4224 B.CreateCall(GlobalAssignFn, {src, dstVal});
4228 llvm::Value *src,
Address dst,
4229 llvm::Value *ivarOffset) {
4231 src = EnforceType(B, src, IdTy);
4232 llvm::Value *dstVal = EnforceType(B, dst.
getPointer(), IdTy);
4233 B.CreateCall(IvarAssignFn, {src, dstVal, ivarOffset});
4237 llvm::Value *src,
Address dst) {
4239 src = EnforceType(B, src, IdTy);
4240 llvm::Value *dstVal = EnforceType(B, dst.
getPointer(), PtrToIdTy);
4241 B.CreateCall(StrongCastAssignFn, {src, dstVal});
4247 llvm::Value *Size) {
4249 llvm::Value *DestPtrVal = EnforceType(B, DestPtr.
getPointer(), PtrTy);
4250 llvm::Value *SrcPtrVal = EnforceType(B, SrcPtr.
getPointer(), PtrTy);
4252 B.CreateCall(MemMoveFn, {DestPtrVal, SrcPtrVal,
Size});
4255llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
4258 const std::string Name = GetIVarOffsetVariableName(ID, Ivar);
4262 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
4263 if (!IvarOffsetPointer)
4264 IvarOffsetPointer =
new llvm::GlobalVariable(
4265 TheModule, llvm::PointerType::getUnqual(VMContext),
false,
4266 llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
4267 return IvarOffsetPointer;
4272 llvm::Value *BaseValue,
4274 unsigned CVRQualifiers) {
4277 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
4278 EmitIvarOffset(CGF, ID, Ivar));
4306 if (RuntimeVersion < 10 ||
4308 return CGF.
Builder.CreateZExtOrBitCast(
4312 llvm::PointerType::getUnqual(VMContext),
4313 ObjCIvarOffsetVariable(
Interface, Ivar),
4317 std::string
name =
"__objc_ivar_offset_value_" +
4320 llvm::Value *Offset = TheModule.getGlobalVariable(name);
4322 auto GV =
new llvm::GlobalVariable(TheModule, IntTy,
4323 false, llvm::GlobalValue::LinkOnceAnyLinkage,
4324 llvm::Constant::getNullValue(IntTy), name);
4329 if (Offset->getType() != PtrDiffTy)
4330 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
4334 return llvm::ConstantInt::get(PtrDiffTy, Offset,
true);
4340 switch (Runtime.getKind()) {
4342 if (Runtime.getVersion() >= VersionTuple(2, 0))
4343 return new CGObjCGNUstep2(CGM);
4344 return new CGObjCGNUstep(CGM);
4347 return new CGObjCGCC(CGM);
4350 return new CGObjCObjFW(CGM);
4356 llvm_unreachable(
"these runtimes are not GNU runtimes");
4358 llvm_unreachable(
"bad runtime");
Defines the clang::ASTContext interface.
static const ObjCInterfaceDecl * FindIvarInterface(ASTContext &Context, const ObjCInterfaceDecl *OID, const ObjCIvarDecl *OIVD)
static bool isNamed(const NamedDecl *ND, const char(&Str)[Len])
Defines the clang::FileManager interface and associated types.
Defines the SourceManager interface.
Defines the Objective-C statement AST node classes.
__device__ __2f16 float __ockl_bool s
__device__ __2f16 float c
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
TranslationUnitDecl * getTranslationUnitDecl() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
void getObjCEncodingForType(QualType T, std::string &S, const FieldDecl *Field=nullptr, QualType *NotEncodedT=nullptr) const
Emit the Objective-CC type encoding for the given type T into S.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
std::string getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, bool Extended=false) const
Emit the encoded type for the method declaration Decl into S.
std::string getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD, const Decl *Container) const
getObjCEncodingForPropertyDecl - Return the encoded type for this method declaration.
const ASTRecordLayout & getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const
Get or compute information about the layout of the specified Objective-C implementation.
const ASTRecordLayout & getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const
Get or compute information about the layout of the specified Objective-C interface.
QualType getObjCProtoType() const
Retrieve the type of the Objective-C Protocol class.
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
ObjCPropertyImplDecl * getObjCPropertyImplDeclForPropertyDecl(const ObjCPropertyDecl *PD, const Decl *Container) const
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
QualType getObjCIdType() const
Represents the Objective-CC id type.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
void getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT, QualType T, std::string &S, bool Extended) const
getObjCEncodingForMethodParameter - Return the encoded type for a single method parameter or return t...
const TargetInfo & getTargetInfo() const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
CharUnits getSize() const
getSize - Get the record size in characters.
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
CharUnits - This is an opaque type for sizes expressed in character units.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
llvm::Value * getPointer() const
CGBlockInfo - Information to generate a block literal.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
virtual llvm::Constant * getAddrOfRTTIDescriptor(QualType Ty)=0
virtual CatchTypeInfo getCatchAllTypeInfo()
Abstract information about a function or function prototype.
All available information about a concrete callee.
Implements runtime-specific code generation functions.
virtual llvm::Constant * GetEHType(QualType T)=0
Get the type constant to catch for the given ObjC pointer type.
virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest, llvm::Value *ivarOffset)=0
virtual llvm::FunctionCallee GetCppAtomicObjectGetFunction()=0
API for atomic copying of qualified aggregates with non-trivial copy assignment (c++) in getter.
virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest)=0
virtual llvm::Constant * BuildByrefLayout(CodeGen::CodeGenModule &CGM, QualType T)=0
Returns an i8* which points to the byref layout information.
virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, Address DestPtr, Address SrcPtr, llvm::Value *Size)=0
virtual llvm::FunctionCallee GetPropertySetFunction()=0
Return the runtime function for setting properties.
virtual llvm::FunctionCallee GetCppAtomicObjectSetFunction()=0
API for atomic copying of qualified aggregates with non-trivial copy assignment (c++) in setter.
virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtTryStmt &S)=0
virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, ReturnValueSlot ReturnSlot, QualType ResultType, Selector Sel, llvm::Value *Receiver, const CallArgList &CallArgs, const ObjCInterfaceDecl *Class=nullptr, const ObjCMethodDecl *Method=nullptr)=0
Generate an Objective-C message send operation.
virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy, llvm::Value *BaseValue, const ObjCIvarDecl *Ivar, unsigned CVRQualifiers)=0
virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD)=0
Register an class alias.
virtual void GenerateCategory(const ObjCCategoryImplDecl *OCD)=0
Generate a category.
virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S, bool ClearInsertionPoint=true)=0
virtual llvm::Value * EmitIvarOffset(CodeGen::CodeGenFunction &CGF, const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar)=0
virtual llvm::Function * GenerateMethod(const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD)=0
Generate a function preamble for a method with the specified types.
virtual llvm::Value * GenerateProtocolRef(CodeGenFunction &CGF, const ObjCProtocolDecl *OPD)=0
Emit the code to return the named protocol as an object, as in a @protocol expression.
virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, Address AddrWeakObj)=0
virtual llvm::Function * ModuleInitFunction()=0
Generate the function required to register all Objective-C components in this compilation unit with t...
virtual CodeGen::RValue GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, ReturnValueSlot ReturnSlot, QualType ResultType, Selector Sel, const ObjCInterfaceDecl *Class, bool isCategoryImpl, llvm::Value *Self, bool IsClassMessage, const CallArgList &CallArgs, const ObjCMethodDecl *Method=nullptr)=0
Generate an Objective-C message send operation to the super class initiated in a method for Class and...
virtual void GenerateClass(const ObjCImplementationDecl *OID)=0
Generate a class structure for this class.
virtual llvm::FunctionCallee EnumerationMutationFunction()=0
EnumerationMutationFunction - Return the function that's called by the compiler when a mutation is de...
virtual llvm::Constant * BuildGCBlockLayout(CodeGen::CodeGenModule &CGM, const CodeGen::CGBlockInfo &blockInfo)=0
virtual llvm::FunctionCallee GetGetStructFunction()=0
virtual llvm::Constant * GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0
GetOrEmitProtocol - Get the protocol object for the given declaration, emitting it if necessary.
virtual ConstantAddress GenerateConstantString(const StringLiteral *)=0
Generate a constant string object.
virtual llvm::Value * GetClass(CodeGenFunction &CGF, const ObjCInterfaceDecl *OID)=0
GetClass - Return a reference to the class for the given interface decl.
virtual void GenerateProtocol(const ObjCProtocolDecl *OPD)=0
Generate the named protocol.
virtual llvm::Constant * BuildRCBlockLayout(CodeGen::CodeGenModule &CGM, const CodeGen::CGBlockInfo &blockInfo)=0
virtual llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic, bool copy)=0
Return the runtime function for optimized setting properties.
virtual llvm::Value * GetSelector(CodeGenFunction &CGF, Selector Sel)=0
Get a selector for the specified name and type values.
virtual void GenerateDirectMethodPrologue(CodeGenFunction &CGF, llvm::Function *Fn, const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD)=0
Generates prologue for direct Objective-C Methods.
virtual Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel)=0
Get the address of a selector for the specified name and type values.
virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest)=0
virtual llvm::Value * EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF)
virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest, bool threadlocal=false)=0
virtual llvm::FunctionCallee GetPropertyGetFunction()=0
Return the runtime function for getting properties.
virtual llvm::FunctionCallee GetSetStructFunction()=0
virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S)=0
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
void addFrom(const CallArgList &other)
Add all the arguments from another CallArgList to this one.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
SmallVector< llvm::Value *, 8 > ObjCEHValueStack
ObjCEHValueStack - Stack of Objective-C exception values, used for rethrows.
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **callOrInvoke, bool IsMustTail, SourceLocation Loc)
EmitCall - Generate a call of the given function, expecting the given result type,...
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
JumpDest ReturnBlock
ReturnBlock - Unified return block.
llvm::Value * EmitObjCThrowOperand(const Expr *expr)
llvm::Value * LoadObjCSelf()
LoadObjCSelf - Load the value of self.
void EmitVarDecl(const VarDecl &D)
EmitVarDecl - Emit a local variable declaration.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
static bool hasAggregateEvaluationKind(QualType T)
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
This class organizes the cross-function state that is used while generating LLVM code.
void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const
Set visibility, dllimport/dllexport and dso_local.
llvm::Module & getModule() const
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
void addCompilerUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.compiler.used metadata.
bool ReturnTypeUsesFPRet(QualType ResultType)
Return true iff the given type uses 'fpret' when used as a return type.
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
void addUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.used metadata.
const llvm::DataLayout & getDataLayout() const
CGCXXABI & getCXXABI() const
const llvm::Triple & getTriple() const
ASTContext & getContext() const
bool ReturnTypeUsesSRet(const CGFunctionInfo &FI)
Return true iff the given type uses 'sret' when used as a return type.
const CodeGenOptions & getCodeGenOpts() const
llvm::LLVMContext & getLLVMContext()
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
ConstantAddress GetAddrOfConstantCString(const std::string &Str, const char *GlobalName=nullptr)
Returns a pointer to a character array containing the literal and a terminating '\0' character.
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
bool isZeroInitializable(QualType T)
IsZeroInitializable - Return whether a type can be zero-initialized (in the C++ sense) with an LLVM z...
llvm::Type * ConvertTypeForMem(QualType T, bool ForBitField=false)
ConvertTypeForMem - Convert type T into a llvm::Type.
A specialization of Address that requires the address to be an LLVM Constant.
ArrayBuilder beginArray(llvm::Type *eltTy=nullptr)
llvm::GlobalVariable * finishAndCreateGlobal(As &&...args)
Given that this builder was created by beginning an array or struct directly on a ConstantInitBuilder...
StructBuilder beginStruct(llvm::StructType *ty=nullptr)
void finishAndAddTo(AggregateBuilderBase &parent)
Given that this builder was created by beginning an array or struct component on the given parent bui...
A helper class of ConstantInitBuilder, used for building constant array initializers.
The standard implementation of ConstantInitBuilder used in Clang.
A helper class of ConstantInitBuilder, used for building constant struct initializers.
LValue - This represents an lvalue references.
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
Decl - This represents one declaration (or definition), e.g.
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
StringRef getName() const
This represents one expression.
StringRef getName() const
The name of this FileEntry.
DirectoryEntryRef getDir() const
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
std::string ObjCConstantStringClass
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Visibility getVisibility() const
Determines the visibility of this entity.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
Represents Objective-C's @synchronized statement.
Represents Objective-C's @throw statement.
Represents Objective-C's @try ... @catch ... @finally statement.
ObjCCategoryDecl - Represents a category declaration.
const ObjCProtocolList & getReferencedProtocols() const
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
ObjCCategoryDecl * getCategoryDecl() const
ObjCCompatibleAliasDecl - Represents alias of a class.
const ObjCInterfaceDecl * getClassInterface() const
ObjCContainerDecl - Represents a container for method declarations.
classmeth_iterator classmeth_end() const
classmeth_iterator classmeth_begin() const
instmeth_range instance_methods() const
instmeth_iterator instmeth_end() const
instmeth_iterator instmeth_begin() const
prop_range properties() const
classmeth_range class_methods() const
propimpl_range property_impls() const
const ObjCInterfaceDecl * getClassInterface() const
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Represents an ObjC class declaration.
all_protocol_range all_referenced_protocols() const
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
protocol_range protocols() const
protocol_iterator protocol_end() const
protocol_iterator protocol_begin() const
ObjCInterfaceDecl * getSuperClass() const
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
known_extensions_range known_extensions() const
Interfaces are the core concept in Objective-C for object oriented design.
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
ObjCIvarDecl - Represents an ObjC instance variable.
ObjCInterfaceDecl * getContainingInterface()
Return the class interface that this ivar is logically contained in; this is either the interface whe...
ObjCIvarDecl * getNextIvar()
ObjCMethodDecl - Represents an instance or class method declaration.
ImplicitParamDecl * getSelfDecl() const
bool hasParamDestroyedInCallee() const
True if the method has a parameter that's destroyed in the callee.
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
ObjCMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Selector getSelector() const
ImplicitParamDecl * getCmdDecl() const
QualType getReturnType() const
bool isClassMethod() const
ObjCInterfaceDecl * getClassInterface()
Represents a pointer to an Objective C object.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
const ObjCInterfaceType * getInterfaceType() const
If this pointer points to an Objective C @interface type, gets the type for that interface.
Represents a class type in Objective C.
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface.
Represents one property declaration in an Objective-C interface.
ObjCMethodDecl * getGetterMethodDecl() const
ObjCMethodDecl * getSetterMethodDecl() const
Represents an Objective-C protocol declaration.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
bool isNonRuntimeProtocol() const
This is true iff the protocol is tagged with the objc_non_runtime_protocol attribute.
protocol_iterator protocol_begin() const
protocol_range protocols() const
protocol_iterator protocol_end() const
The basic abstraction for the target Objective-C runtime.
const VersionTuple & getVersion() const
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
Kind
The basic Objective-C runtimes that we know about.
@ MacOSX
'macosx' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the non-fragile AB...
@ FragileMacOSX
'macosx-fragile' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the fragil...
@ GNUstep
'gnustep' is the modern non-fragile GNUstep runtime.
@ ObjFW
'objfw' is the Objective-C runtime included in ObjFW
@ iOS
'ios' is the Apple-provided NeXT-derived runtime on iOS or the iOS simulator; it is always non-fragil...
@ GCC
'gcc' is the Objective-C runtime shipped with GCC, implementing a fragile Objective-C ABI
@ WatchOS
'watchos' is a variant of iOS for Apple's watchOS.
A (possibly-)qualified type.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
This table allows us to fully hide how we implement multi-keyword caching.
Smart pointer class that efficiently represents Objective-C method names.
std::string getAsString() const
Derive the full selector name (e.g.
This class handles loading and caching of source files into memory.
StringLiteral - This represents a string literal expression, e.g.
bool containsNonAscii() const
unsigned getLength() const
uint32_t getCodeUnit(size_t i) const
StringRef getString() const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
The top declaration context.
static DeclContext * castToDeclContext(const TranslationUnitDecl *D)
const T * castAs() const
Member-template castAs<specific type>.
bool isObjCQualifiedIdType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isObjCIdType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
Represents a variable declaration or definition.
CGObjCRuntime * CreateGNUObjCRuntime(CodeGenModule &CGM)
Creates an instance of an Objective-C runtime class.
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
bool Zero(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
@ 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