30#include "llvm/ADT/SmallVector.h"
31#include "llvm/ADT/StringMap.h"
32#include "llvm/IR/DataLayout.h"
33#include "llvm/IR/Intrinsics.h"
34#include "llvm/IR/LLVMContext.h"
35#include "llvm/IR/Module.h"
36#include "llvm/Support/Compiler.h"
37#include "llvm/Support/ConvertUTF.h"
41using namespace CodeGen;
48class LazyRuntimeFunction {
50 llvm::FunctionType *FTy =
nullptr;
51 const char *FunctionName =
nullptr;
52 llvm::FunctionCallee
Function =
nullptr;
55 LazyRuntimeFunction() =
default;
59 template <
typename... Tys>
60 void init(
CodeGenModule *Mod,
const char *name, llvm::Type *RetTy,
67 FTy = llvm::FunctionType::get(RetTy, ArgTys,
false);
70 FTy = llvm::FunctionType::get(RetTy, std::nullopt,
false);
74 llvm::FunctionType *getType() {
return FTy; }
78 operator llvm::FunctionCallee() {
95 llvm::Module &TheModule;
98 llvm::StructType *ObjCSuperTy;
101 llvm::PointerType *PtrToObjCSuperTy;
105 llvm::PointerType *SelectorTy;
107 llvm::Type *SelectorElemTy;
110 llvm::IntegerType *Int8Ty;
113 llvm::PointerType *PtrToInt8Ty;
115 llvm::StructType *ProtocolTy;
117 llvm::PointerType *ProtocolPtrTy;
123 llvm::PointerType *IMPTy;
128 llvm::PointerType *IdTy;
130 llvm::Type *IdElemTy;
133 llvm::PointerType *PtrToIdTy;
138 llvm::IntegerType *IntTy;
142 llvm::PointerType *PtrTy;
146 llvm::IntegerType *LongTy;
148 llvm::IntegerType *SizeTy;
150 llvm::IntegerType *IntPtrTy;
152 llvm::IntegerType *PtrDiffTy;
155 llvm::PointerType *PtrToIntTy;
159 llvm::IntegerType *Int32Ty;
161 llvm::IntegerType *Int64Ty;
163 llvm::StructType *PropertyMetadataTy;
167 unsigned msgSendMDKind;
170 bool usesSEHExceptions;
175 return (R.
getKind() == kind) &&
176 (R.
getVersion() >= VersionTuple(major, minor));
179 std::string ManglePublicSymbol(StringRef Name) {
180 return (StringRef(CGM.
getTriple().isOSBinFormatCOFF() ?
"$_" :
"._") + Name).str();
183 std::string SymbolForProtocol(Twine Name) {
184 return (ManglePublicSymbol(
"OBJC_PROTOCOL_") + Name).str();
187 std::string SymbolForProtocolRef(StringRef Name) {
188 return (ManglePublicSymbol(
"OBJC_REF_PROTOCOL_") + Name).str();
195 llvm::Constant *MakeConstantString(StringRef Str,
const char *Name =
"") {
198 return llvm::ConstantExpr::getGetElementPtr(Array.getElementType(),
199 Array.getPointer(), Zeros);
206 llvm::Constant *ExportUniqueString(
const std::string &Str,
207 const std::string &prefix,
208 bool Private=
false) {
209 std::string
name = prefix + Str;
210 auto *ConstStr = TheModule.getGlobalVariable(name);
212 llvm::Constant *value = llvm::ConstantDataArray::getString(VMContext,Str);
213 auto *GV =
new llvm::GlobalVariable(TheModule, value->getType(),
true,
214 llvm::GlobalValue::LinkOnceODRLinkage, value, name);
215 GV->setComdat(TheModule.getOrInsertComdat(name));
217 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
220 return llvm::ConstantExpr::getGetElementPtr(ConstStr->getValueType(),
226 const Decl *Container) {
229 std::string NameAndAttributes;
230 std::string TypeStr =
232 NameAndAttributes +=
'\0';
233 NameAndAttributes += TypeStr.length() + 3;
234 NameAndAttributes += TypeStr;
235 NameAndAttributes +=
'\0';
237 return MakeConstantString(NameAndAttributes);
246 int attrs =
property->getPropertyAttributes();
249 attrs &= ~ObjCPropertyAttribute::kind_copy;
250 attrs &= ~ObjCPropertyAttribute::kind_retain;
251 attrs &= ~ObjCPropertyAttribute::kind_weak;
252 attrs &= ~ObjCPropertyAttribute::kind_strong;
255 Fields.addInt(Int8Ty, attrs & 0xff);
261 attrs |= isSynthesized ? (1<<0) : 0;
262 attrs |= isDynamic ? (1<<1) : 0;
265 Fields.addInt(Int8Ty, attrs & 0xff);
267 Fields.addInt(Int8Ty, 0);
268 Fields.addInt(Int8Ty, 0);
271 virtual llvm::Constant *GenerateCategoryProtocolList(
const
276 Fields.addInt(IntTy, count);
279 llvm::DataLayout td(&TheModule);
280 Fields.addInt(IntTy, td.getTypeSizeInBits(PropertyMetadataTy) /
291 bool isSynthesized=
true,
bool
293 auto Fields = PropertiesArray.
beginStruct(PropertyMetadataTy);
295 Fields.add(MakePropertyEncodingString(property, OCD));
296 PushPropertyAttributes(Fields, property, isSynthesized, isDynamic);
300 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
301 Fields.add(MakeConstantString(accessor->getSelector().getAsString()));
302 Fields.add(TypeEncoding);
316 llvm::Value *EnforceType(
CGBuilderTy &B, llvm::Value *
V, llvm::Type *Ty) {
317 if (
V->getType() == Ty)
319 return B.CreateBitCast(
V, Ty);
323 llvm::Constant *Zeros[2];
325 llvm::Constant *NULLPtr;
327 llvm::LLVMContext &VMContext;
335 llvm::GlobalAlias *ClassPtrAlias;
340 llvm::GlobalAlias *MetaClassPtrAlias;
342 std::vector<llvm::Constant*> Classes;
344 std::vector<llvm::Constant*> Categories;
347 std::vector<llvm::Constant*> ConstantStrings;
351 llvm::StringMap<llvm::Constant*> ObjCStrings;
353 llvm::StringMap<llvm::Constant*> ExistingProtocols;
359 typedef std::pair<std::string, llvm::GlobalAlias*> TypedSelector;
363 typedef llvm::DenseMap<Selector, SmallVector<TypedSelector, 2> >
371 Selector RetainSel, ReleaseSel, AutoreleaseSel;
375 LazyRuntimeFunction IvarAssignFn, StrongCastAssignFn, MemMoveFn, WeakReadFn,
376 WeakAssignFn, GlobalAssignFn;
378 typedef std::pair<std::string, std::string> ClassAliasPair;
380 std::vector<ClassAliasPair> ClassAliases;
384 LazyRuntimeFunction ExceptionThrowFn;
387 LazyRuntimeFunction ExceptionReThrowFn;
390 LazyRuntimeFunction EnterCatchFn;
393 LazyRuntimeFunction ExitCatchFn;
395 LazyRuntimeFunction SyncEnterFn;
397 LazyRuntimeFunction SyncExitFn;
402 LazyRuntimeFunction EnumerationMutationFn;
405 LazyRuntimeFunction GetPropertyFn;
408 LazyRuntimeFunction SetPropertyFn;
410 LazyRuntimeFunction GetStructPropertyFn;
412 LazyRuntimeFunction SetStructPropertyFn;
424 const int ProtocolVersion;
427 const int ClassABIVersion;
443 llvm::Constant *GenerateMethodList(StringRef ClassName,
444 StringRef CategoryName,
446 bool isClassMethodList);
451 virtual llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName);
455 llvm::Constant *GeneratePropertyList(
const Decl *Container,
457 bool isClassProperty=
false,
458 bool protocolOptionalProperties=
false);
468 void GenerateProtocolHolderCategory();
471 llvm::Constant *GenerateClassStructure(
472 llvm::Constant *MetaClass,
473 llvm::Constant *SuperClass,
476 llvm::Constant *Version,
477 llvm::Constant *InstanceSize,
478 llvm::Constant *IVars,
479 llvm::Constant *Methods,
480 llvm::Constant *Protocols,
481 llvm::Constant *IvarOffsets,
482 llvm::Constant *Properties,
483 llvm::Constant *StrongIvarBitmap,
484 llvm::Constant *WeakIvarBitmap,
489 virtual llvm::Constant *GenerateProtocolMethodList(
493 void EmitProtocolMethodList(T &&Methods, llvm::Constant *&
Required,
497 for (
const auto *I : Methods)
499 OptionalMethods.push_back(I);
501 RequiredMethods.push_back(I);
502 Required = GenerateProtocolMethodList(RequiredMethods);
503 Optional = GenerateProtocolMethodList(OptionalMethods);
509 const std::string &TypeEncoding);
516 const std::string Name =
"__objc_ivar_offset_" +
ID->getNameAsString()
525 void EmitClassRef(
const std::string &className);
529 const std::string &Name,
bool isWeak);
535 llvm::Value *&Receiver,
538 MessageSendInfo &MSI) = 0;
546 MessageSendInfo &MSI) = 0;
563 unsigned protocolClassVersion,
unsigned classABI=1);
570 llvm::Value *Receiver,
const CallArgList &CallArgs,
577 bool isCategoryImpl, llvm::Value *Receiver,
586 virtual llvm::Constant *GetConstantSelector(
Selector Sel,
587 const std::string &TypeEncoding) {
588 llvm_unreachable(
"Runtime unable to generate constant selector");
631 bool ClearInsertionPoint=
true)
override;
635 llvm::Value *src,
Address dst)
override;
637 llvm::Value *src,
Address dest,
638 bool threadlocal=
false)
override;
640 Address dest, llvm::Value *ivarOffset)
override;
642 llvm::Value *src,
Address dest)
override;
645 llvm::Value *Size)
override;
648 unsigned CVRQualifiers)
override;
675class CGObjCGCC :
public CGObjCGNU {
678 LazyRuntimeFunction MsgLookupFn;
682 LazyRuntimeFunction MsgLookupSuperFn;
686 llvm::Value *cmd, llvm::MDNode *node,
687 MessageSendInfo &MSI)
override {
689 llvm::Value *args[] = {
690 EnforceType(Builder, Receiver, IdTy),
691 EnforceType(Builder, cmd, SelectorTy) };
693 imp->setMetadata(msgSendMDKind, node);
698 llvm::Value *cmd, MessageSendInfo &MSI)
override {
700 llvm::Value *lookupArgs[] = {
701 EnforceType(Builder, ObjCSuper.
getPointer(), PtrToObjCSuperTy), cmd};
708 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
710 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
711 PtrToObjCSuperTy, SelectorTy);
716class CGObjCGNUstep :
public CGObjCGNU {
719 LazyRuntimeFunction SlotLookupFn;
724 LazyRuntimeFunction SlotLookupSuperFn;
726 LazyRuntimeFunction SetPropertyAtomic;
728 LazyRuntimeFunction SetPropertyAtomicCopy;
730 LazyRuntimeFunction SetPropertyNonAtomic;
732 LazyRuntimeFunction SetPropertyNonAtomicCopy;
735 LazyRuntimeFunction CxxAtomicObjectGetFn;
738 LazyRuntimeFunction CxxAtomicObjectSetFn;
743 llvm::Type *SlotStructTy;
746 llvm::Constant *GetEHType(
QualType T)
override;
750 llvm::Value *cmd, llvm::MDNode *node,
751 MessageSendInfo &MSI)
override {
753 llvm::FunctionCallee LookupFn = SlotLookupFn;
758 Builder.CreateStore(Receiver, ReceiverPtr);
765 self = llvm::ConstantPointerNull::get(IdTy);
769 if (
auto *LookupFn2 = dyn_cast<llvm::Function>(LookupFn.getCallee()))
770 LookupFn2->addParamAttr(0, llvm::Attribute::NoCapture);
772 llvm::Value *args[] = {
773 EnforceType(Builder, ReceiverPtr.
getPointer(), PtrToIdTy),
774 EnforceType(Builder, cmd, SelectorTy),
775 EnforceType(Builder, self, IdTy) };
777 slot->setOnlyReadsMemory();
778 slot->setMetadata(msgSendMDKind, node);
781 llvm::Value *imp = Builder.CreateAlignedLoad(
782 IMPTy, Builder.CreateStructGEP(SlotStructTy, slot, 4),
787 Receiver = Builder.CreateLoad(ReceiverPtr,
true);
793 MessageSendInfo &MSI)
override {
795 llvm::Value *lookupArgs[] = {ObjCSuper.
getPointer(), cmd};
797 llvm::CallInst *slot =
799 slot->setOnlyReadsMemory();
801 return Builder.CreateAlignedLoad(
802 IMPTy, Builder.CreateStructGEP(SlotStructTy, slot, 4),
807 CGObjCGNUstep(
CodeGenModule &Mod) : CGObjCGNUstep(Mod, 9, 3, 1) {}
808 CGObjCGNUstep(
CodeGenModule &Mod,
unsigned ABI,
unsigned ProtocolABI,
810 CGObjCGNU(Mod, ABI, ProtocolABI, ClassABI) {
813 SlotStructTy = llvm::StructType::get(PtrTy, PtrTy, PtrTy, IntTy, IMPTy);
814 SlotTy = llvm::PointerType::getUnqual(SlotStructTy);
816 SlotLookupFn.init(&CGM,
"objc_msg_lookup_sender", SlotTy, PtrToIdTy,
819 SlotLookupSuperFn.init(&CGM,
"objc_slot_lookup_super", SlotTy,
820 PtrToObjCSuperTy, SelectorTy);
822 if (usesSEHExceptions) {
823 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
825 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy);
827 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
829 EnterCatchFn.init(&CGM,
"__cxa_begin_catch", PtrTy, PtrTy);
831 ExitCatchFn.init(&CGM,
"__cxa_end_catch", VoidTy);
833 ExceptionReThrowFn.init(&CGM,
"_Unwind_Resume_or_Rethrow", VoidTy,
835 }
else if (R.
getVersion() >= VersionTuple(1, 7)) {
836 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
838 EnterCatchFn.init(&CGM,
"objc_begin_catch", IdTy, PtrTy);
840 ExitCatchFn.init(&CGM,
"objc_end_catch", VoidTy);
842 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy, PtrTy);
844 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
845 SetPropertyAtomic.init(&CGM,
"objc_setProperty_atomic", VoidTy, IdTy,
846 SelectorTy, IdTy, PtrDiffTy);
847 SetPropertyAtomicCopy.init(&CGM,
"objc_setProperty_atomic_copy", VoidTy,
848 IdTy, SelectorTy, IdTy, PtrDiffTy);
849 SetPropertyNonAtomic.init(&CGM,
"objc_setProperty_nonatomic", VoidTy,
850 IdTy, SelectorTy, IdTy, PtrDiffTy);
851 SetPropertyNonAtomicCopy.init(&CGM,
"objc_setProperty_nonatomic_copy",
852 VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy);
855 CxxAtomicObjectSetFn.init(&CGM,
"objc_setCppObjectAtomic", VoidTy, PtrTy,
859 CxxAtomicObjectGetFn.init(&CGM,
"objc_getCppObjectAtomic", VoidTy, PtrTy,
863 llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override {
868 return CxxAtomicObjectGetFn;
871 llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override {
876 return CxxAtomicObjectSetFn;
879 llvm::FunctionCallee GetOptimizedPropertySetFunction(
bool atomic,
880 bool copy)
override {
891 if (copy)
return SetPropertyAtomicCopy;
892 return SetPropertyAtomic;
895 return copy ? SetPropertyNonAtomicCopy : SetPropertyNonAtomic;
902class CGObjCGNUstep2 :
public CGObjCGNUstep {
907 ClassReferenceSection,
910 ProtocolReferenceSection,
912 ConstantStringSection
914 static const char *
const SectionsBaseNames[8];
915 static const char *
const PECOFFSectionsBaseNames[8];
916 template<SectionKind K>
917 std::string sectionName() {
918 if (CGM.
getTriple().isOSBinFormatCOFF()) {
919 std::string
name(PECOFFSectionsBaseNames[K]);
923 return SectionsBaseNames[K];
928 LazyRuntimeFunction MsgLookupSuperFn;
932 bool EmittedProtocol =
false;
937 bool EmittedProtocolRef =
false;
941 bool EmittedClass =
false;
945 typedef std::pair<std::string, std::pair<llvm::GlobalVariable*, int>>
947 std::vector<EarlyInitPair> EarlyInitList;
949 std::string SymbolForClassRef(StringRef Name,
bool isWeak) {
951 return (ManglePublicSymbol(
"OBJC_WEAK_REF_CLASS_") + Name).str();
953 return (ManglePublicSymbol(
"OBJC_REF_CLASS_") + Name).str();
956 std::string SymbolForClass(StringRef Name) {
957 return (ManglePublicSymbol(
"OBJC_CLASS_") + Name).str();
959 void CallRuntimeFunction(
CGBuilderTy &B, StringRef FunctionName,
962 for (
auto *Arg : Args)
963 Types.push_back(Arg->getType());
964 llvm::FunctionType *FT = llvm::FunctionType::get(B.getVoidTy(), Types,
967 B.CreateCall(Fn, Args);
976 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
977 if (old != ObjCStrings.end())
985 (LiteralLength < 9) && !isNonASCII) {
991 for (
unsigned i=0 ; i<LiteralLength ; i++)
992 str |= ((uint64_t)SL->
getCodeUnit(i)) << ((64 - 4 - 3) - (i*7));
994 str |= LiteralLength << 3;
997 auto *ObjCStr = llvm::ConstantExpr::getIntToPtr(
998 llvm::ConstantInt::get(Int64Ty, str), IdTy);
999 ObjCStrings[Str] = ObjCStr;
1005 if (StringClass.empty()) StringClass =
"NSConstantString";
1007 std::string Sym = SymbolForClass(StringClass);
1009 llvm::Constant *
isa = TheModule.getNamedGlobal(Sym);
1012 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
1013 llvm::GlobalValue::ExternalLinkage,
nullptr, Sym);
1014 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1015 cast<llvm::GlobalValue>(isa)->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
1030 auto Fields = Builder.beginStruct();
1031 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
1034 Fields.addNullPointer(PtrTy);
1041 unsigned NumU8CodeUnits = Str.size();
1046 const llvm::UTF8 *FromPtr = (
const llvm::UTF8 *)Str.data();
1047 llvm::UTF16 *ToPtr = &ToBuf[0];
1048 (void)llvm::ConvertUTF8toUTF16(&FromPtr, FromPtr + NumU8CodeUnits,
1049 &ToPtr, ToPtr + NumU8CodeUnits, llvm::strictConversion);
1050 uint32_t StringLength = ToPtr - &ToBuf[0];
1054 Fields.addInt(Int32Ty, 2);
1056 Fields.addInt(Int32Ty, StringLength);
1058 Fields.addInt(Int32Ty, StringLength * 2);
1060 Fields.addInt(Int32Ty, 0);
1063 auto *
C = llvm::ConstantDataArray::get(VMContext, Arr);
1064 auto *Buffer =
new llvm::GlobalVariable(TheModule,
C->getType(),
1065 true, llvm::GlobalValue::PrivateLinkage,
C,
".str");
1066 Buffer->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1070 Fields.addInt(Int32Ty, 0);
1072 Fields.addInt(Int32Ty, Str.size());
1074 Fields.addInt(Int32Ty, Str.size());
1076 Fields.addInt(Int32Ty, 0);
1078 Fields.add(MakeConstantString(Str));
1080 std::string StringName;
1083 StringName =
".objc_str_";
1084 for (
int i=0,e=Str.size() ; i<e ; ++i) {
1085 unsigned char c = Str[i];
1096 llvm::GlobalVariable *ObjCStrGV =
1098 isNamed ? StringRef(StringName) :
".objc_string",
1099 Align,
false,
isNamed ? llvm::GlobalValue::LinkOnceODRLinkage
1100 : llvm::GlobalValue::PrivateLinkage);
1101 ObjCStrGV->setSection(sectionName<ConstantStringSection>());
1103 ObjCStrGV->setComdat(TheModule.getOrInsertComdat(StringName));
1104 ObjCStrGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1106 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1107 std::pair<llvm::GlobalVariable*, int>
v{ObjCStrGV, 0};
1108 EarlyInitList.emplace_back(Sym,
v);
1110 ObjCStrings[Str] = ObjCStrGV;
1111 ConstantStrings.push_back(ObjCStrGV);
1118 bool isSynthesized=
true,
bool
1119 isDynamic=
true)
override {
1128 auto Fields = PropertiesArray.
beginStruct(PropertyMetadataTy);
1131 std::string TypeStr =
1133 Fields.add(MakeConstantString(TypeStr));
1134 std::string typeStr;
1136 Fields.add(MakeConstantString(typeStr));
1140 Fields.add(GetConstantSelector(accessor->getSelector(), TypeStr));
1142 Fields.add(NULLPtr);
1157 llvm::StructType *ObjCMethodDescTy =
1159 { PtrToInt8Ty, PtrToInt8Ty });
1168 auto MethodList = Builder.beginStruct();
1170 MethodList.addInt(IntTy, Methods.size());
1172 llvm::DataLayout td(&TheModule);
1173 MethodList.addInt(IntTy, td.getTypeSizeInBits(ObjCMethodDescTy) /
1176 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
1177 for (
auto *M : Methods) {
1178 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
1179 Method.add(CGObjCGNU::GetConstantSelector(M));
1181 Method.finishAndAddTo(MethodArray);
1183 MethodArray.finishAndAddTo(MethodList);
1184 return MethodList.finishAndCreateGlobal(
".objc_protocol_method_list",
1190 auto RuntimeProtocols = GetRuntimeProtocolList(ReferencedProtocols.begin(),
1191 ReferencedProtocols.end());
1193 for (
const auto *PI : RuntimeProtocols)
1194 Protocols.push_back(GenerateProtocolRef(PI));
1195 return GenerateProtocolList(Protocols);
1199 llvm::Value *cmd, MessageSendInfo &MSI)
override {
1202 llvm::Value *lookupArgs[] = {CGObjCGNU::EnforceType(Builder,
1209 llvm::GlobalVariable *GetClassVar(StringRef Name,
bool isWeak=
false) {
1210 std::string SymbolName = SymbolForClassRef(Name, isWeak);
1211 auto *ClassSymbol = TheModule.getNamedGlobal(SymbolName);
1214 ClassSymbol =
new llvm::GlobalVariable(TheModule,
1215 IdTy,
false, llvm::GlobalValue::ExternalLinkage,
1216 nullptr, SymbolName);
1222 ClassSymbol->setInitializer(
new llvm::GlobalVariable(TheModule,
1223 Int8Ty,
false, llvm::GlobalValue::ExternalWeakLinkage,
1224 nullptr, SymbolForClass(Name)));
1226 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1232 for (
const auto *Result : DC->
lookup(&II))
1233 if ((OID = dyn_cast<ObjCInterfaceDecl>(Result)))
1239 assert(OID &&
"Failed to find ObjCInterfaceDecl");
1241 if (OIDDef !=
nullptr)
1244 auto Storage = llvm::GlobalValue::DefaultStorageClass;
1245 if (OID->
hasAttr<DLLImportAttr>())
1246 Storage = llvm::GlobalValue::DLLImportStorageClass;
1247 else if (OID->
hasAttr<DLLExportAttr>())
1248 Storage = llvm::GlobalValue::DLLExportStorageClass;
1250 cast<llvm::GlobalValue>(ClassSymbol)->setDLLStorageClass(Storage);
1253 assert(ClassSymbol->getName() == SymbolName);
1257 const std::string &Name,
1258 bool isWeak)
override {
1270 switch (Ownership) {
1292 llvm_unreachable(
"Method should not be called!");
1295 llvm::Constant *GenerateEmptyProtocol(StringRef ProtocolName)
override {
1296 std::string Name = SymbolForProtocol(ProtocolName);
1297 auto *GV = TheModule.getGlobalVariable(Name);
1300 GV =
new llvm::GlobalVariable(TheModule, ProtocolTy,
false,
1301 llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
1308 llvm::StringMap<llvm::Constant*> ExistingProtocolRefs;
1313 auto *&Ref = ExistingProtocolRefs[Name];
1315 auto *&
Protocol = ExistingProtocols[Name];
1317 Protocol = GenerateProtocolRef(PD);
1318 std::string RefName = SymbolForProtocolRef(Name);
1319 assert(!TheModule.getGlobalVariable(RefName));
1321 auto GV =
new llvm::GlobalVariable(TheModule, ProtocolPtrTy,
false,
1322 llvm::GlobalValue::LinkOnceODRLinkage,
1324 GV->setComdat(TheModule.getOrInsertComdat(RefName));
1325 GV->setSection(sectionName<ProtocolReferenceSection>());
1329 EmittedProtocolRef =
true;
1335 llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(ProtocolPtrTy,
1337 llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
1340 auto ProtocolBuilder = builder.beginStruct();
1341 ProtocolBuilder.addNullPointer(PtrTy);
1342 ProtocolBuilder.addInt(SizeTy, Protocols.size());
1343 ProtocolBuilder.add(ProtocolArray);
1344 return ProtocolBuilder.finishAndCreateGlobal(
".objc_protocol_list",
1353 auto *&
Protocol = ExistingProtocols[ProtocolName];
1357 EmittedProtocol =
true;
1359 auto SymName = SymbolForProtocol(ProtocolName);
1360 auto *OldGV = TheModule.getGlobalVariable(SymName);
1370 Protocol =
new llvm::GlobalVariable(TheModule, ProtocolTy,
1372 llvm::GlobalValue::ExternalLinkage,
nullptr, SymName);
1377 auto RuntimeProtocols =
1379 for (
const auto *PI : RuntimeProtocols)
1380 Protocols.push_back(GenerateProtocolRef(PI));
1381 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
1384 llvm::Constant *InstanceMethodList, *OptionalInstanceMethodList;
1385 llvm::Constant *ClassMethodList, *OptionalClassMethodList;
1387 OptionalInstanceMethodList);
1388 EmitProtocolMethodList(PD->
class_methods(), ClassMethodList,
1389 OptionalClassMethodList);
1394 auto ProtocolBuilder = builder.beginStruct();
1395 ProtocolBuilder.add(llvm::ConstantExpr::getIntToPtr(
1396 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
1397 ProtocolBuilder.add(MakeConstantString(ProtocolName));
1398 ProtocolBuilder.add(ProtocolList);
1399 ProtocolBuilder.add(InstanceMethodList);
1400 ProtocolBuilder.add(ClassMethodList);
1401 ProtocolBuilder.add(OptionalInstanceMethodList);
1402 ProtocolBuilder.add(OptionalClassMethodList);
1404 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
false,
false));
1406 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
false,
true));
1408 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
true,
false));
1410 ProtocolBuilder.add(GeneratePropertyList(
nullptr, PD,
true,
true));
1412 auto *GV = ProtocolBuilder.finishAndCreateGlobal(SymName,
1414 GV->setSection(sectionName<ProtocolSection>());
1415 GV->setComdat(TheModule.getOrInsertComdat(SymName));
1417 OldGV->replaceAllUsesWith(GV);
1418 OldGV->removeFromParent();
1419 GV->setName(SymName);
1425 const std::string &TypeEncoding)
override {
1426 return GetConstantSelector(Sel, TypeEncoding);
1428 llvm::Constant *GetTypeString(llvm::StringRef TypeEncoding) {
1429 if (TypeEncoding.empty())
1431 std::string MangledTypes = std::string(TypeEncoding);
1432 std::replace(MangledTypes.begin(), MangledTypes.end(),
1434 std::string TypesVarName =
".objc_sel_types_" + MangledTypes;
1435 auto *TypesGlobal = TheModule.getGlobalVariable(TypesVarName);
1437 llvm::Constant *
Init = llvm::ConstantDataArray::getString(VMContext,
1439 auto *GV =
new llvm::GlobalVariable(TheModule,
Init->getType(),
1440 true, llvm::GlobalValue::LinkOnceODRLinkage,
Init, TypesVarName);
1441 GV->setComdat(TheModule.getOrInsertComdat(TypesVarName));
1442 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1445 return llvm::ConstantExpr::getGetElementPtr(TypesGlobal->getValueType(),
1446 TypesGlobal, Zeros);
1448 llvm::Constant *GetConstantSelector(
Selector Sel,
1449 const std::string &TypeEncoding)
override {
1454 std::string MangledTypes = TypeEncoding;
1455 std::replace(MangledTypes.begin(), MangledTypes.end(),
1457 auto SelVarName = (StringRef(
".objc_selector_") + Sel.
getAsString() +
"_" +
1458 MangledTypes).str();
1459 if (
auto *GV = TheModule.getNamedGlobal(SelVarName))
1462 auto SelBuilder = builder.beginStruct();
1463 SelBuilder.add(ExportUniqueString(Sel.
getAsString(),
".objc_sel_name_",
1465 SelBuilder.add(GetTypeString(TypeEncoding));
1466 auto *GV = SelBuilder.finishAndCreateGlobal(SelVarName,
1468 GV->setComdat(TheModule.getOrInsertComdat(SelVarName));
1469 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1470 GV->setSection(sectionName<SelectorSection>());
1473 llvm::StructType *emptyStruct =
nullptr;
1482 std::pair<llvm::Constant*,llvm::Constant*>
1483 GetSectionBounds(StringRef Section) {
1484 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1485 if (emptyStruct ==
nullptr) {
1486 emptyStruct = llvm::StructType::create(VMContext,
".objc_section_sentinel");
1487 emptyStruct->setBody({},
true);
1489 auto ZeroInit = llvm::Constant::getNullValue(emptyStruct);
1490 auto Sym = [&](StringRef Prefix, StringRef SecSuffix) {
1491 auto *Sym =
new llvm::GlobalVariable(TheModule, emptyStruct,
1493 llvm::GlobalValue::LinkOnceODRLinkage, ZeroInit, Prefix +
1495 Sym->setVisibility(llvm::GlobalValue::HiddenVisibility);
1496 Sym->setSection((Section + SecSuffix).str());
1497 Sym->setComdat(TheModule.getOrInsertComdat((Prefix +
1502 return { Sym(
"__start_",
"$a"), Sym(
"__stop",
"$z") };
1504 auto *Start =
new llvm::GlobalVariable(TheModule, PtrTy,
1506 llvm::GlobalValue::ExternalLinkage,
nullptr, StringRef(
"__start_") +
1508 Start->setVisibility(llvm::GlobalValue::HiddenVisibility);
1509 auto *Stop =
new llvm::GlobalVariable(TheModule, PtrTy,
1511 llvm::GlobalValue::ExternalLinkage,
nullptr, StringRef(
"__stop_") +
1513 Stop->setVisibility(llvm::GlobalValue::HiddenVisibility);
1514 return { Start, Stop };
1519 llvm::Function *ModuleInitFunction()
override {
1520 llvm::Function *LoadFunction = llvm::Function::Create(
1521 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
1522 llvm::GlobalValue::LinkOnceODRLinkage,
".objcv2_load_function",
1524 LoadFunction->setVisibility(llvm::GlobalValue::HiddenVisibility);
1525 LoadFunction->setComdat(TheModule.getOrInsertComdat(
".objcv2_load_function"));
1527 llvm::BasicBlock *EntryBB =
1528 llvm::BasicBlock::Create(VMContext,
"entry", LoadFunction);
1530 B.SetInsertPoint(EntryBB);
1532 auto InitStructBuilder = builder.beginStruct();
1533 InitStructBuilder.addInt(Int64Ty, 0);
1534 auto §ionVec = CGM.
getTriple().isOSBinFormatCOFF() ? PECOFFSectionsBaseNames : SectionsBaseNames;
1535 for (
auto *
s : sectionVec) {
1536 auto bounds = GetSectionBounds(
s);
1537 InitStructBuilder.add(bounds.first);
1538 InitStructBuilder.add(bounds.second);
1540 auto *InitStruct = InitStructBuilder.finishAndCreateGlobal(
".objc_init",
1542 InitStruct->setVisibility(llvm::GlobalValue::HiddenVisibility);
1543 InitStruct->setComdat(TheModule.getOrInsertComdat(
".objc_init"));
1545 CallRuntimeFunction(B,
"__objc_load", {InitStruct});;
1552 auto *InitVar =
new llvm::GlobalVariable(TheModule, LoadFunction->getType(),
1553 false, llvm::GlobalValue::LinkOnceAnyLinkage,
1554 LoadFunction,
".objc_ctor");
1557 assert(InitVar->getName() ==
".objc_ctor");
1563 if (CGM.
getTriple().isOSBinFormatCOFF())
1564 InitVar->setSection(
".CRT$XCLz");
1568 InitVar->setSection(
".init_array");
1570 InitVar->setSection(
".ctors");
1572 InitVar->setVisibility(llvm::GlobalValue::HiddenVisibility);
1573 InitVar->setComdat(TheModule.getOrInsertComdat(
".objc_ctor"));
1575 for (
auto *
C : Categories) {
1576 auto *Cat = cast<llvm::GlobalVariable>(
C->stripPointerCasts());
1577 Cat->setSection(sectionName<CategorySection>());
1581 StringRef Section) {
1582 auto nullBuilder = builder.beginStruct();
1583 for (
auto *F :
Init)
1585 auto GV = nullBuilder.finishAndCreateGlobal(Name, CGM.
getPointerAlign(),
1586 false, llvm::GlobalValue::LinkOnceODRLinkage);
1587 GV->setSection(Section);
1588 GV->setComdat(TheModule.getOrInsertComdat(Name));
1589 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
1593 for (
auto clsAlias : ClassAliases)
1594 createNullGlobal(std::string(
".objc_class_alias") +
1595 clsAlias.second, { MakeConstantString(clsAlias.second),
1596 GetClassVar(clsAlias.first) }, sectionName<ClassAliasSection>());
1601 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
1602 createNullGlobal(
".objc_null_selector", {NULLPtr, NULLPtr},
1603 sectionName<SelectorSection>());
1604 if (Categories.empty())
1605 createNullGlobal(
".objc_null_category", {NULLPtr, NULLPtr,
1606 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr},
1607 sectionName<CategorySection>());
1608 if (!EmittedClass) {
1609 createNullGlobal(
".objc_null_cls_init_ref", NULLPtr,
1610 sectionName<ClassSection>());
1611 createNullGlobal(
".objc_null_class_ref", { NULLPtr, NULLPtr },
1612 sectionName<ClassReferenceSection>());
1614 if (!EmittedProtocol)
1615 createNullGlobal(
".objc_null_protocol", {NULLPtr, NULLPtr, NULLPtr,
1616 NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr, NULLPtr,
1617 NULLPtr}, sectionName<ProtocolSection>());
1618 if (!EmittedProtocolRef)
1619 createNullGlobal(
".objc_null_protocol_ref", {NULLPtr},
1620 sectionName<ProtocolReferenceSection>());
1621 if (ClassAliases.empty())
1622 createNullGlobal(
".objc_null_class_alias", { NULLPtr, NULLPtr },
1623 sectionName<ClassAliasSection>());
1624 if (ConstantStrings.empty()) {
1625 auto i32Zero = llvm::ConstantInt::get(Int32Ty, 0);
1626 createNullGlobal(
".objc_null_constant_string", { NULLPtr, i32Zero,
1627 i32Zero, i32Zero, i32Zero, NULLPtr },
1628 sectionName<ConstantStringSection>());
1631 ConstantStrings.clear();
1635 if (EarlyInitList.size() > 0) {
1636 auto *
Init = llvm::Function::Create(llvm::FunctionType::get(CGM.
VoidTy,
1637 {}), llvm::GlobalValue::InternalLinkage,
".objc_early_init",
1639 llvm::IRBuilder<>
b(llvm::BasicBlock::Create(CGM.
getLLVMContext(),
"entry",
1641 for (
const auto &lateInit : EarlyInitList) {
1642 auto *global = TheModule.getGlobalVariable(lateInit.first);
1644 llvm::GlobalVariable *GV = lateInit.second.first;
1645 b.CreateAlignedStore(
1647 b.CreateStructGEP(GV->getValueType(), GV, lateInit.second.second),
1654 auto *InitVar =
new llvm::GlobalVariable(CGM.
getModule(),
Init->getType(),
1655 true, llvm::GlobalValue::InternalLinkage,
1656 Init,
".objc_early_init_ptr");
1657 InitVar->setSection(
".CRT$XCLb");
1666 std::string TypeEncoding;
1669 std::replace(TypeEncoding.begin(), TypeEncoding.end(),
1671 const std::string Name =
"__objc_ivar_offset_" +
ID->getNameAsString()
1679 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
1680 if (!IvarOffsetPointer)
1681 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule, IntTy,
false,
1682 llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
1684 llvm::Value *Offset =
1686 if (Offset->getType() != PtrDiffTy)
1687 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
1692 bool IsCOFF = CGM.
getTriple().isOSBinFormatCOFF();
1698 auto *classNameConstant = MakeConstantString(className);
1701 auto metaclassFields = builder.beginStruct();
1703 metaclassFields.addNullPointer(PtrTy);
1705 metaclassFields.addNullPointer(PtrTy);
1707 metaclassFields.add(classNameConstant);
1709 metaclassFields.addInt(LongTy, 0);
1712 metaclassFields.addInt(LongTy, 1);
1716 metaclassFields.addInt(LongTy, 0);
1718 metaclassFields.addNullPointer(PtrTy);
1723 metaclassFields.addNullPointer(PtrTy);
1728 metaclassFields.add(
1729 GenerateMethodList(className,
"", ClassMethods,
true));
1732 metaclassFields.addNullPointer(PtrTy);
1734 metaclassFields.addNullPointer(PtrTy);
1736 metaclassFields.addNullPointer(PtrTy);
1738 metaclassFields.addNullPointer(PtrTy);
1740 metaclassFields.addNullPointer(PtrTy);
1742 metaclassFields.addNullPointer(PtrTy);
1744 metaclassFields.addNullPointer(PtrTy);
1746 metaclassFields.addInt(LongTy, 0);
1748 metaclassFields.add(GeneratePropertyList(OID, classDecl,
true));
1750 auto *metaclass = metaclassFields.finishAndCreateGlobal(
1751 ManglePublicSymbol(
"OBJC_METACLASS_") + className,
1754 auto classFields = builder.beginStruct();
1756 classFields.add(metaclass);
1761 llvm::Constant *SuperClass =
nullptr;
1762 if (SuperClassDecl) {
1763 auto SuperClassName = SymbolForClass(SuperClassDecl->
getNameAsString());
1764 SuperClass = TheModule.getNamedGlobal(SuperClassName);
1767 SuperClass =
new llvm::GlobalVariable(TheModule, PtrTy,
false,
1768 llvm::GlobalValue::ExternalLinkage,
nullptr, SuperClassName);
1770 auto Storage = llvm::GlobalValue::DefaultStorageClass;
1771 if (SuperClassDecl->
hasAttr<DLLImportAttr>())
1772 Storage = llvm::GlobalValue::DLLImportStorageClass;
1773 else if (SuperClassDecl->
hasAttr<DLLExportAttr>())
1774 Storage = llvm::GlobalValue::DLLExportStorageClass;
1776 cast<llvm::GlobalValue>(SuperClass)->setDLLStorageClass(Storage);
1780 classFields.add(SuperClass);
1782 classFields.addNullPointer(PtrTy);
1784 classFields.addNullPointer(PtrTy);
1786 classFields.add(classNameConstant);
1788 classFields.addInt(LongTy, 0);
1791 classFields.addInt(LongTy, 0);
1793 int superInstanceSize = !SuperClassDecl ? 0 :
1797 classFields.addInt(LongTy,
1799 superInstanceSize));
1802 classFields.addNullPointer(PtrTy);
1807 llvm::DataLayout td(&TheModule);
1810 auto ivarListBuilder =
b.beginStruct();
1812 ivarListBuilder.addInt(IntTy, ivar_count);
1814 llvm::StructType *ObjCIvarTy = llvm::StructType::get(
1820 ivarListBuilder.addInt(SizeTy, td.getTypeSizeInBits(ObjCIvarTy) /
1823 auto ivarArrayBuilder = ivarListBuilder.beginArray();
1826 auto ivarTy = IVD->getType();
1827 auto ivarBuilder = ivarArrayBuilder.beginStruct();
1829 ivarBuilder.add(MakeConstantString(IVD->getNameAsString()));
1831 std::string TypeStr;
1834 ivarBuilder.add(MakeConstantString(TypeStr));
1836 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
1837 uint64_t Offset = BaseOffset - superInstanceSize;
1838 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
1839 std::string OffsetName = GetIVarOffsetVariableName(classDecl, IVD);
1840 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
1842 OffsetVar->setInitializer(OffsetValue);
1844 OffsetVar =
new llvm::GlobalVariable(TheModule, IntTy,
1845 false, llvm::GlobalValue::ExternalLinkage,
1846 OffsetValue, OffsetName);
1847 auto ivarVisibility =
1851 llvm::GlobalValue::HiddenVisibility :
1852 llvm::GlobalValue::DefaultVisibility;
1853 OffsetVar->setVisibility(ivarVisibility);
1854 ivarBuilder.add(OffsetVar);
1856 ivarBuilder.addInt(Int32Ty,
1867 ivarBuilder.addInt(Int32Ty,
1868 (align << 3) | (1<<2) |
1869 FlagsForOwnership(ivarTy.getQualifiers().getObjCLifetime()));
1870 ivarBuilder.finishAndAddTo(ivarArrayBuilder);
1872 ivarArrayBuilder.finishAndAddTo(ivarListBuilder);
1873 auto ivarList = ivarListBuilder.finishAndCreateGlobal(
".objc_ivar_list",
1875 llvm::GlobalValue::PrivateLinkage);
1876 classFields.add(ivarList);
1880 InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
1883 if (propImpl->getPropertyImplementation() ==
1886 if (OMD && OMD->hasBody())
1887 InstanceMethods.push_back(OMD);
1889 addIfExists(propImpl->getGetterMethodDecl());
1890 addIfExists(propImpl->getSetterMethodDecl());
1893 if (InstanceMethods.size() == 0)
1894 classFields.addNullPointer(PtrTy);
1897 GenerateMethodList(className,
"", InstanceMethods,
false));
1900 classFields.addNullPointer(PtrTy);
1902 classFields.addNullPointer(PtrTy);
1904 classFields.addNullPointer(PtrTy);
1906 classFields.addNullPointer(PtrTy);
1908 classFields.addNullPointer(PtrTy);
1910 auto RuntimeProtocols = GetRuntimeProtocolList(classDecl->
protocol_begin(),
1913 for (
const auto *I : RuntimeProtocols)
1914 Protocols.push_back(GenerateProtocolRef(I));
1916 if (Protocols.empty())
1917 classFields.addNullPointer(PtrTy);
1919 classFields.add(GenerateProtocolList(Protocols));
1921 classFields.addNullPointer(PtrTy);
1923 classFields.addInt(LongTy, 0);
1925 classFields.add(GeneratePropertyList(OID, classDecl));
1927 llvm::GlobalVariable *classStruct =
1928 classFields.finishAndCreateGlobal(SymbolForClass(className),
1931 auto *classRefSymbol = GetClassVar(className);
1932 classRefSymbol->setSection(sectionName<ClassReferenceSection>());
1933 classRefSymbol->setInitializer(classStruct);
1938 classStruct->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1939 cast<llvm::GlobalValue>(classRefSymbol)->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1943 std::pair<llvm::GlobalVariable*, int>
v{classStruct, 1};
1944 EarlyInitList.emplace_back(std::string(SuperClass->getName()),
1953 if (ClassPtrAlias) {
1954 ClassPtrAlias->replaceAllUsesWith(classStruct);
1955 ClassPtrAlias->eraseFromParent();
1956 ClassPtrAlias =
nullptr;
1958 if (
auto Placeholder =
1959 TheModule.getNamedGlobal(SymbolForClass(className)))
1960 if (Placeholder != classStruct) {
1961 Placeholder->replaceAllUsesWith(classStruct);
1962 Placeholder->eraseFromParent();
1963 classStruct->setName(SymbolForClass(className));
1965 if (MetaClassPtrAlias) {
1966 MetaClassPtrAlias->replaceAllUsesWith(metaclass);
1967 MetaClassPtrAlias->eraseFromParent();
1968 MetaClassPtrAlias =
nullptr;
1970 assert(classStruct->getName() == SymbolForClass(className));
1972 auto classInitRef =
new llvm::GlobalVariable(TheModule,
1973 classStruct->getType(),
false, llvm::GlobalValue::ExternalLinkage,
1974 classStruct, ManglePublicSymbol(
"OBJC_INIT_CLASS_") + className);
1975 classInitRef->setSection(sectionName<ClassSection>());
1978 EmittedClass =
true;
1981 CGObjCGNUstep2(
CodeGenModule &Mod) : CGObjCGNUstep(Mod, 10, 4, 2) {
1982 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
1983 PtrToObjCSuperTy, SelectorTy);
1992 PropertyMetadataTy =
1994 { PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty });
1999const char *
const CGObjCGNUstep2::SectionsBaseNames[8] =
2006"__objc_protocol_refs",
2007"__objc_class_aliases",
2008"__objc_constant_string"
2011const char *
const CGObjCGNUstep2::PECOFFSectionsBaseNames[8] =
2024class CGObjCObjFW:
public CGObjCGNU {
2028 LazyRuntimeFunction MsgLookupFn;
2031 LazyRuntimeFunction MsgLookupFnSRet;
2035 LazyRuntimeFunction MsgLookupSuperFn, MsgLookupSuperFnSRet;
2038 llvm::Value *cmd, llvm::MDNode *node,
2039 MessageSendInfo &MSI)
override {
2041 llvm::Value *args[] = {
2042 EnforceType(Builder, Receiver, IdTy),
2043 EnforceType(Builder, cmd, SelectorTy) };
2045 llvm::CallBase *imp;
2051 imp->setMetadata(msgSendMDKind, node);
2056 llvm::Value *cmd, MessageSendInfo &MSI)
override {
2058 llvm::Value *lookupArgs[] = {
2059 EnforceType(Builder, ObjCSuper.
getPointer(), PtrToObjCSuperTy), cmd,
2068 llvm::Value *GetClassNamed(
CodeGenFunction &CGF,
const std::string &Name,
2069 bool isWeak)
override {
2071 return CGObjCGNU::GetClassNamed(CGF, Name, isWeak);
2074 std::string SymbolName =
"_OBJC_CLASS_" + Name;
2075 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(SymbolName);
2077 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
2078 llvm::GlobalValue::ExternalLinkage,
2079 nullptr, SymbolName);
2086 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
2087 MsgLookupFnSRet.init(&CGM,
"objc_msg_lookup_stret", IMPTy, IdTy,
2090 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
2091 PtrToObjCSuperTy, SelectorTy);
2092 MsgLookupSuperFnSRet.init(&CGM,
"objc_msg_lookup_super_stret", IMPTy,
2093 PtrToObjCSuperTy, SelectorTy);
2101void CGObjCGNU::EmitClassRef(
const std::string &className) {
2102 std::string symbolRef =
"__objc_class_ref_" + className;
2104 if (TheModule.getGlobalVariable(symbolRef))
2106 std::string symbolName =
"__objc_class_name_" + className;
2107 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
2109 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
2110 llvm::GlobalValue::ExternalLinkage,
2111 nullptr, symbolName);
2113 new llvm::GlobalVariable(TheModule, ClassSymbol->getType(),
true,
2114 llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef);
2117CGObjCGNU::CGObjCGNU(
CodeGenModule &cgm,
unsigned runtimeABIVersion,
2118 unsigned protocolClassVersion,
unsigned classABI)
2120 VMContext(cgm.getLLVMContext()), ClassPtrAlias(nullptr),
2121 MetaClassPtrAlias(nullptr), RuntimeVersion(runtimeABIVersion),
2122 ProtocolVersion(protocolClassVersion), ClassABIVersion(classABI) {
2124 msgSendMDKind = VMContext.getMDKindID(
"GNUObjCMessageSend");
2129 IntTy = cast<llvm::IntegerType>(
2131 LongTy = cast<llvm::IntegerType>(
2133 SizeTy = cast<llvm::IntegerType>(
2135 PtrDiffTy = cast<llvm::IntegerType>(
2139 Int8Ty = llvm::Type::getInt8Ty(VMContext);
2141 PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
2142 ProtocolPtrTy = llvm::PointerType::getUnqual(
2145 Zeros[0] = llvm::ConstantInt::get(LongTy, 0);
2146 Zeros[1] = Zeros[0];
2147 NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty);
2151 SelectorTy = PtrToInt8Ty;
2152 SelectorElemTy = Int8Ty;
2158 PtrToIntTy = llvm::PointerType::getUnqual(IntTy);
2159 PtrTy = PtrToInt8Ty;
2161 Int32Ty = llvm::Type::getInt32Ty(VMContext);
2162 Int64Ty = llvm::Type::getInt64Ty(VMContext);
2165 CGM.
getDataLayout().getPointerSizeInBits() == 32 ? Int32Ty : Int64Ty;
2179 PtrToIdTy = llvm::PointerType::getUnqual(IdTy);
2180 ProtocolTy = llvm::StructType::get(IdTy,
2202 PropertyMetadataTy = llvm::StructType::get(CGM.
getLLVMContext(), {
2203 PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty, PtrToInt8Ty,
2204 PtrToInt8Ty, PtrToInt8Ty });
2206 ObjCSuperTy = llvm::StructType::get(IdTy, IdTy);
2207 PtrToObjCSuperTy = llvm::PointerType::getUnqual(ObjCSuperTy);
2209 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
2212 ExceptionThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy);
2213 ExceptionReThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy);
2215 SyncEnterFn.init(&CGM,
"objc_sync_enter", IntTy, IdTy);
2217 SyncExitFn.init(&CGM,
"objc_sync_exit", IntTy, IdTy);
2220 EnumerationMutationFn.init(&CGM,
"objc_enumerationMutation", VoidTy, IdTy);
2223 GetPropertyFn.init(&CGM,
"objc_getProperty", IdTy, IdTy, SelectorTy,
2226 SetPropertyFn.init(&CGM,
"objc_setProperty", VoidTy, IdTy, SelectorTy,
2227 PtrDiffTy, IdTy, BoolTy, BoolTy);
2229 GetStructPropertyFn.init(&CGM,
"objc_getPropertyStruct", VoidTy, PtrTy, PtrTy,
2230 PtrDiffTy, BoolTy, BoolTy);
2232 SetStructPropertyFn.init(&CGM,
"objc_setPropertyStruct", VoidTy, PtrTy, PtrTy,
2233 PtrDiffTy, BoolTy, BoolTy);
2236 llvm::Type *IMPArgs[] = { IdTy, SelectorTy };
2237 IMPTy = llvm::PointerType::getUnqual(llvm::FunctionType::get(IdTy, IMPArgs,
2242 RuntimeVersion = 10;
2257 IvarAssignFn.init(&CGM,
"objc_assign_ivar", IdTy, IdTy, IdTy, PtrDiffTy);
2259 StrongCastAssignFn.init(&CGM,
"objc_assign_strongCast", IdTy, IdTy,
2262 GlobalAssignFn.init(&CGM,
"objc_assign_global", IdTy, IdTy, PtrToIdTy);
2264 WeakAssignFn.init(&CGM,
"objc_assign_weak", IdTy, IdTy, PtrToIdTy);
2266 WeakReadFn.init(&CGM,
"objc_read_weak", IdTy, PtrToIdTy);
2268 MemMoveFn.init(&CGM,
"objc_memmove_collectable", PtrTy, PtrTy, PtrTy,
2274 const std::string &Name,
bool isWeak) {
2275 llvm::Constant *ClassName = MakeConstantString(Name);
2287 llvm::FunctionType::get(IdTy, PtrToInt8Ty,
true),
"objc_lookup_class");
2297 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value))
2302llvm::Value *CGObjCGNU::EmitNSAutoreleasePoolClassRef(
CodeGenFunction &CGF) {
2303 auto *
Value = GetClassNamed(CGF,
"NSAutoreleasePool",
false);
2304 if (CGM.
getTriple().isOSBinFormatCOFF()) {
2305 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value)) {
2311 for (
const auto *Result : DC->
lookup(&II))
2312 if ((VD = dyn_cast<VarDecl>(Result)))
2322 const std::string &TypeEncoding) {
2324 llvm::GlobalAlias *SelValue =
nullptr;
2327 e = Types.end() ; i!=e ; i++) {
2328 if (i->first == TypeEncoding) {
2329 SelValue = i->second;
2334 SelValue = llvm::GlobalAlias::create(SelectorElemTy, 0,
2335 llvm::GlobalValue::PrivateLinkage,
2338 Types.emplace_back(TypeEncoding, SelValue);
2345 llvm::Value *SelValue = GetSelector(CGF, Sel);
2356 return GetTypedSelector(CGF, Sel, std::string());
2362 return GetTypedSelector(CGF, Method->
getSelector(), SelTypes);
2365llvm::Constant *CGObjCGNU::GetEHType(
QualType T) {
2372 return MakeConstantString(
"@id");
2380 assert(OPT &&
"Invalid @catch type.");
2382 assert(IDecl &&
"Invalid @catch type.");
2386llvm::Constant *CGObjCGNUstep::GetEHType(
QualType T) {
2387 if (usesSEHExceptions)
2391 return CGObjCGNU::GetEHType(T);
2399 llvm::Constant *IDEHType =
2400 CGM.
getModule().getGlobalVariable(
"__objc_id_type_info");
2403 new llvm::GlobalVariable(CGM.
getModule(), PtrToInt8Ty,
2405 llvm::GlobalValue::ExternalLinkage,
2406 nullptr,
"__objc_id_type_info");
2412 assert(PT &&
"Invalid @catch type.");
2414 assert(IT &&
"Invalid @catch type.");
2415 std::string className =
2418 std::string typeinfoName =
"__objc_eh_typeinfo_" + className;
2421 if (llvm::Constant *typeinfo = TheModule.getGlobalVariable(typeinfoName))
2429 const char *vtableName =
"_ZTVN7gnustep7libobjc22__objc_class_type_infoE";
2430 auto *Vtable = TheModule.getGlobalVariable(vtableName);
2432 Vtable =
new llvm::GlobalVariable(TheModule, PtrToInt8Ty,
true,
2433 llvm::GlobalValue::ExternalLinkage,
2434 nullptr, vtableName);
2436 llvm::Constant *Two = llvm::ConstantInt::get(IntTy, 2);
2438 llvm::ConstantExpr::getGetElementPtr(Vtable->getValueType(), Vtable, Two);
2440 llvm::Constant *typeName =
2441 ExportUniqueString(className,
"__objc_eh_typename_");
2444 auto fields = builder.beginStruct();
2445 fields.add(BVtable);
2446 fields.add(typeName);
2447 llvm::Constant *TI =
2448 fields.finishAndCreateGlobal(
"__objc_eh_typeinfo_" + className,
2451 llvm::GlobalValue::LinkOnceODRLinkage);
2458 std::string Str = SL->
getString().str();
2462 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
2463 if (old != ObjCStrings.end())
2468 if (StringClass.empty()) StringClass =
"NSConstantString";
2470 std::string Sym =
"_OBJC_CLASS_";
2473 llvm::Constant *
isa = TheModule.getNamedGlobal(Sym);
2476 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
2477 llvm::GlobalValue::ExternalWeakLinkage,
2481 auto Fields = Builder.beginStruct();
2483 Fields.add(MakeConstantString(Str));
2484 Fields.addInt(IntTy, Str.size());
2486 ObjCStrings[Str] = ObjCStr;
2487 ConstantStrings.push_back(ObjCStr);
2500 bool isCategoryImpl,
2501 llvm::Value *Receiver,
2502 bool IsClassMessage,
2507 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2511 if (Sel == ReleaseSel) {
2516 llvm::Value *cmd = GetSelector(CGF, Sel);
2519 ActualArgs.
add(
RValue::get(EnforceType(Builder, Receiver, IdTy)), ASTIdTy);
2523 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2525 llvm::Value *ReceiverClass =
nullptr;
2528 ReceiverClass = GetClassNamed(CGF,
2529 Class->getSuperClass()->getNameAsString(),
false);
2530 if (IsClassMessage) {
2532 ReceiverClass = Builder.CreateBitCast(ReceiverClass,
2533 llvm::PointerType::getUnqual(IdTy));
2535 Builder.CreateAlignedLoad(IdTy, ReceiverClass, CGF.
getPointerAlign());
2537 ReceiverClass = EnforceType(Builder, ReceiverClass, IdTy);
2539 if (isCategoryImpl) {
2540 llvm::FunctionCallee classLookupFunction =
nullptr;
2541 if (IsClassMessage) {
2543 IdTy, PtrTy,
true),
"objc_get_meta_class");
2546 IdTy, PtrTy,
true),
"objc_get_class");
2548 ReceiverClass = Builder.CreateCall(classLookupFunction,
2549 MakeConstantString(
Class->getNameAsString()));
2556 if (IsClassMessage) {
2557 if (!MetaClassPtrAlias) {
2558 MetaClassPtrAlias = llvm::GlobalAlias::create(
2559 IdElemTy, 0, llvm::GlobalValue::InternalLinkage,
2560 ".objc_metaclass_ref" +
Class->getNameAsString(), &TheModule);
2562 ReceiverClass = MetaClassPtrAlias;
2564 if (!ClassPtrAlias) {
2565 ClassPtrAlias = llvm::GlobalAlias::create(
2566 IdElemTy, 0, llvm::GlobalValue::InternalLinkage,
2567 ".objc_class_ref" +
Class->getNameAsString(), &TheModule);
2569 ReceiverClass = ClassPtrAlias;
2573 llvm::Type *CastTy = llvm::StructType::get(IdTy, IdTy);
2574 ReceiverClass = Builder.CreateBitCast(ReceiverClass,
2575 llvm::PointerType::getUnqual(CastTy));
2577 ReceiverClass = Builder.CreateStructGEP(CastTy, ReceiverClass, 1);
2580 Builder.CreateAlignedLoad(IdTy, ReceiverClass, CGF.
getPointerAlign());
2583 llvm::StructType *ObjCSuperTy =
2584 llvm::StructType::get(Receiver->getType(), IdTy);
2589 Builder.CreateStore(Receiver, Builder.CreateStructGEP(ObjCSuper, 0));
2590 Builder.CreateStore(ReceiverClass, Builder.CreateStructGEP(ObjCSuper, 1));
2593 llvm::Value *imp = LookupIMPSuper(CGF, ObjCSuper, cmd, MSI);
2594 imp = EnforceType(Builder, imp, MSI.MessengerType);
2596 llvm::Metadata *impMD[] = {
2597 llvm::MDString::get(VMContext, Sel.
getAsString()),
2598 llvm::MDString::get(VMContext,
Class->getSuperClass()->getNameAsString()),
2599 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2600 llvm::Type::getInt1Ty(VMContext), IsClassMessage))};
2601 llvm::MDNode *
node = llvm::MDNode::get(VMContext, impMD);
2605 llvm::CallBase *call;
2606 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2607 call->setMetadata(msgSendMDKind, node);
2617 llvm::Value *Receiver,
2625 if (Sel == RetainSel || Sel == AutoreleaseSel) {
2629 if (Sel == ReleaseSel) {
2637 cmd = GetSelector(CGF, Method);
2639 cmd = GetSelector(CGF, Sel);
2640 cmd = EnforceType(Builder, cmd, SelectorTy);
2641 Receiver = EnforceType(Builder, Receiver, IdTy);
2643 llvm::Metadata *impMD[] = {
2644 llvm::MDString::get(VMContext, Sel.
getAsString()),
2645 llvm::MDString::get(VMContext, Class ?
Class->getNameAsString() :
""),
2646 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
2647 llvm::Type::getInt1Ty(VMContext), Class !=
nullptr))};
2648 llvm::MDNode *
node = llvm::MDNode::get(VMContext, impMD);
2655 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2676 bool hasParamDestroyedInCallee =
false;
2677 bool requiresExplicitZeroResult =
false;
2678 bool requiresNilReceiverCheck = [&] {
2680 if (!canMessageReceiverBeNull(CGF, Method,
false,
2686 hasParamDestroyedInCallee =
true;
2706 requiresExplicitZeroResult =
true;
2710 return hasParamDestroyedInCallee || requiresExplicitZeroResult;
2716 bool requiresExplicitAggZeroing =
2720 llvm::BasicBlock *continueBB =
nullptr;
2722 llvm::BasicBlock *nilPathBB =
nullptr;
2724 llvm::BasicBlock *nilCleanupBB =
nullptr;
2727 if (requiresNilReceiverCheck) {
2734 if (requiresExplicitAggZeroing || hasParamDestroyedInCallee) {
2737 nilPathBB = Builder.GetInsertBlock();
2740 llvm::Value *isNil = Builder.CreateICmpEQ(Receiver,
2741 llvm::Constant::getNullValue(Receiver->getType()));
2742 Builder.CreateCondBr(isNil, nilCleanupBB ? nilCleanupBB : continueBB,
2755 imp = LookupIMP(CGF, Receiver, cmd, node, MSI);
2762 "objc_msgSend_fpret")
2769 "objc_msgSend_stret")
2773 llvm::FunctionType::get(IdTy, IdTy,
true),
"objc_msgSend")
2781 imp = EnforceType(Builder, imp, MSI.MessengerType);
2783 llvm::CallBase *call;
2785 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
2786 call->setMetadata(msgSendMDKind, node);
2788 if (requiresNilReceiverCheck) {
2789 llvm::BasicBlock *nonNilPathBB = CGF.
Builder.GetInsertBlock();
2790 CGF.
Builder.CreateBr(continueBB);
2796 if (hasParamDestroyedInCallee) {
2797 destroyCalleeDestroyedArguments(CGF, Method, CallArgs);
2800 if (requiresExplicitAggZeroing) {
2806 nilPathBB = CGF.
Builder.GetInsertBlock();
2807 CGF.
Builder.CreateBr(continueBB);
2815 llvm::PHINode *phi = Builder.CreatePHI(
v->getType(), 2);
2816 phi->addIncoming(
v, nonNilPathBB);
2824 llvm::PHINode *phi = Builder.CreatePHI(
v.first->getType(), 2);
2825 phi->addIncoming(
v.first, nonNilPathBB);
2826 phi->addIncoming(llvm::Constant::getNullValue(
v.first->getType()),
2828 llvm::PHINode *phi2 = Builder.CreatePHI(
v.second->getType(), 2);
2829 phi2->addIncoming(
v.second, nonNilPathBB);
2830 phi2->addIncoming(llvm::Constant::getNullValue(
v.second->getType()),
2840llvm::Constant *CGObjCGNU::
2841GenerateMethodList(StringRef ClassName,
2842 StringRef CategoryName,
2844 bool isClassMethodList) {
2845 if (Methods.empty())
2850 auto MethodList = Builder.beginStruct();
2851 MethodList.addNullPointer(CGM.
Int8PtrTy);
2852 MethodList.addInt(Int32Ty, Methods.size());
2855 llvm::StructType *ObjCMethodTy =
2864 llvm::DataLayout td(&TheModule);
2865 MethodList.addInt(SizeTy, td.getTypeSizeInBits(ObjCMethodTy) /
2881 auto MethodArray = MethodList.beginArray();
2883 for (
const auto *OMD : Methods) {
2884 llvm::Constant *FnPtr =
2885 TheModule.getFunction(getSymbolNameForMethod(OMD));
2886 assert(FnPtr &&
"Can't generate metadata for method that doesn't exist");
2887 auto Method = MethodArray.beginStruct(ObjCMethodTy);
2890 Method.
add(GetConstantSelector(OMD->getSelector(),
2894 Method.
add(MakeConstantString(OMD->getSelector().getAsString()));
2898 Method.finishAndAddTo(MethodArray);
2900 MethodArray.finishAndAddTo(MethodList);
2903 return MethodList.finishAndCreateGlobal(
".objc_method_list",
2908llvm::Constant *CGObjCGNU::
2914 if (IvarNames.empty())
2920 auto IvarList = Builder.beginStruct();
2921 IvarList.addInt(IntTy, (
int)IvarNames.size());
2924 llvm::StructType *ObjCIvarTy =
2925 llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, IntTy);
2928 auto Ivars = IvarList.beginArray(ObjCIvarTy);
2929 for (
unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {
2930 auto Ivar = Ivars.beginStruct(ObjCIvarTy);
2931 Ivar.
add(IvarNames[i]);
2932 Ivar.
add(IvarTypes[i]);
2933 Ivar.
add(IvarOffsets[i]);
2934 Ivar.finishAndAddTo(Ivars);
2936 Ivars.finishAndAddTo(IvarList);
2939 return IvarList.finishAndCreateGlobal(
".objc_ivar_list",
2944llvm::Constant *CGObjCGNU::GenerateClassStructure(
2945 llvm::Constant *MetaClass,
2946 llvm::Constant *SuperClass,
2949 llvm::Constant *Version,
2950 llvm::Constant *InstanceSize,
2951 llvm::Constant *IVars,
2952 llvm::Constant *Methods,
2953 llvm::Constant *Protocols,
2954 llvm::Constant *IvarOffsets,
2955 llvm::Constant *Properties,
2956 llvm::Constant *StrongIvarBitmap,
2957 llvm::Constant *WeakIvarBitmap,
2966 llvm::StructType *ClassTy = llvm::StructType::get(
2983 IvarOffsets->getType(),
2984 Properties->getType(),
2990 auto Elements = Builder.beginStruct(ClassTy);
2995 Elements.add(MetaClass);
2997 Elements.add(SuperClass);
2999 Elements.add(MakeConstantString(Name,
".class_name"));
3001 Elements.addInt(LongTy, 0);
3003 Elements.addInt(LongTy, info);
3006 llvm::DataLayout td(&TheModule);
3007 Elements.addInt(LongTy,
3008 td.getTypeSizeInBits(ClassTy) /
3011 Elements.add(InstanceSize);
3013 Elements.add(IVars);
3015 Elements.add(Methods);
3018 Elements.add(NULLPtr);
3020 Elements.add(NULLPtr);
3022 Elements.add(NULLPtr);
3024 Elements.add(Protocols);
3026 Elements.add(NULLPtr);
3028 Elements.addInt(LongTy, ClassABIVersion);
3030 Elements.add(IvarOffsets);
3032 Elements.add(Properties);
3034 Elements.add(StrongIvarBitmap);
3036 Elements.add(WeakIvarBitmap);
3041 std::string ClassSym((isMeta ?
"_OBJC_METACLASS_":
"_OBJC_CLASS_") +
3043 llvm::GlobalVariable *ClassRef = TheModule.getNamedGlobal(ClassSym);
3044 llvm::Constant *
Class =
3045 Elements.finishAndCreateGlobal(ClassSym, CGM.
getPointerAlign(),
false,
3046 llvm::GlobalValue::ExternalLinkage);
3048 ClassRef->replaceAllUsesWith(Class);
3049 ClassRef->removeFromParent();
3050 Class->setName(ClassSym);
3055llvm::Constant *CGObjCGNU::
3058 llvm::StructType *ObjCMethodDescTy =
3059 llvm::StructType::get(CGM.
getLLVMContext(), { PtrToInt8Ty, PtrToInt8Ty });
3062 auto MethodList = Builder.beginStruct();
3063 MethodList.addInt(IntTy, Methods.size());
3064 auto MethodArray = MethodList.beginArray(ObjCMethodDescTy);
3065 for (
auto *M : Methods) {
3066 auto Method = MethodArray.beginStruct(ObjCMethodDescTy);
3067 Method.
add(MakeConstantString(M->getSelector().getAsString()));
3069 Method.finishAndAddTo(MethodArray);
3071 MethodArray.finishAndAddTo(MethodList);
3072 return MethodList.finishAndCreateGlobal(
".objc_method_list",
3081 auto ProtocolList = Builder.beginStruct();
3082 ProtocolList.add(NULLPtr);
3083 ProtocolList.addInt(LongTy, Protocols.size());
3085 auto Elements = ProtocolList.beginArray(PtrToInt8Ty);
3086 for (
const std::string *iter = Protocols.begin(), *endIter = Protocols.end();
3087 iter != endIter ; iter++) {
3088 llvm::Constant *protocol =
nullptr;
3089 llvm::StringMap<llvm::Constant*>::iterator value =
3090 ExistingProtocols.find(*iter);
3091 if (value == ExistingProtocols.end()) {
3092 protocol = GenerateEmptyProtocol(*iter);
3094 protocol = value->getValue();
3096 Elements.add(protocol);
3098 Elements.finishAndAddTo(ProtocolList);
3099 return ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
3105 auto protocol = GenerateProtocolRef(PD);
3108 return CGF.
Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(T));
3111llvm::Constant *CGObjCGNU::GenerateProtocolRef(
const ObjCProtocolDecl *PD) {
3114 GenerateProtocol(PD);
3115 assert(protocol &&
"Unknown protocol");
3120CGObjCGNU::GenerateEmptyProtocol(StringRef ProtocolName) {
3121 llvm::Constant *ProtocolList = GenerateProtocolList({});
3122 llvm::Constant *MethodList = GenerateProtocolMethodList({});
3126 auto Elements = Builder.beginStruct();
3130 Elements.add(llvm::ConstantExpr::getIntToPtr(
3131 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3133 Elements.add(MakeConstantString(ProtocolName,
".objc_protocol_name"));
3134 Elements.add(ProtocolList);
3135 Elements.add(MethodList);
3136 Elements.add(MethodList);
3137 Elements.add(MethodList);
3138 Elements.add(MethodList);
3139 Elements.add(NULLPtr);
3140 Elements.add(NULLPtr);
3141 return Elements.finishAndCreateGlobal(SymbolForProtocol(ProtocolName),
3157 Protocols.push_back(PI->getNameAsString());
3161 if (I->isOptional())
3162 OptionalInstanceMethods.push_back(I);
3164 InstanceMethods.push_back(I);
3169 if (I->isOptional())
3170 OptionalClassMethods.push_back(I);
3172 ClassMethods.push_back(I);
3174 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
3175 llvm::Constant *InstanceMethodList =
3176 GenerateProtocolMethodList(InstanceMethods);
3177 llvm::Constant *ClassMethodList =
3178 GenerateProtocolMethodList(ClassMethods);
3179 llvm::Constant *OptionalInstanceMethodList =
3180 GenerateProtocolMethodList(OptionalInstanceMethods);
3181 llvm::Constant *OptionalClassMethodList =
3182 GenerateProtocolMethodList(OptionalClassMethods);
3190 llvm::Constant *PropertyList =
3191 GeneratePropertyList(
nullptr, PD,
false,
false);
3192 llvm::Constant *OptionalPropertyList =
3193 GeneratePropertyList(
nullptr, PD,
false,
true);
3200 auto Elements = Builder.beginStruct();
3202 llvm::ConstantExpr::getIntToPtr(
3203 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
3204 Elements.add(MakeConstantString(ProtocolName));
3205 Elements.add(ProtocolList);
3206 Elements.add(InstanceMethodList);
3207 Elements.add(ClassMethodList);
3208 Elements.add(OptionalInstanceMethodList);
3209 Elements.add(OptionalClassMethodList);
3210 Elements.add(PropertyList);
3211 Elements.add(OptionalPropertyList);
3212 ExistingProtocols[ProtocolName] =
3213 Elements.finishAndCreateGlobal(
".objc_protocol", CGM.
getPointerAlign());
3215void CGObjCGNU::GenerateProtocolHolderCategory() {
3219 auto Elements = Builder.beginStruct();
3221 const std::string ClassName =
"__ObjC_Protocol_Holder_Ugly_Hack";
3222 const std::string CategoryName =
"AnotherHack";
3223 Elements.add(MakeConstantString(CategoryName));
3224 Elements.add(MakeConstantString(ClassName));
3226 Elements.add(GenerateMethodList(ClassName, CategoryName, {},
false));
3228 Elements.add(GenerateMethodList(ClassName, CategoryName, {},
true));
3232 auto ProtocolList = ProtocolListBuilder.beginStruct();
3233 ProtocolList.add(NULLPtr);
3234 ProtocolList.addInt(LongTy, ExistingProtocols.size());
3235 auto ProtocolElements = ProtocolList.beginArray(PtrTy);
3236 for (
auto iter = ExistingProtocols.begin(), endIter = ExistingProtocols.end();
3237 iter != endIter ; iter++) {
3238 ProtocolElements.add(iter->getValue());
3240 ProtocolElements.finishAndAddTo(ProtocolList);
3241 Elements.add(ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
3243 Categories.push_back(
3259 int bitCount = bits.size();
3261 if (bitCount < ptrBits) {
3263 for (
int i=0 ; i<bitCount ; ++i) {
3264 if (bits[i]) val |= 1ULL<<(i+1);
3266 return llvm::ConstantInt::get(IntPtrTy, val);
3270 while (
v < bitCount) {
3272 for (
int i=0 ; (i<32) && (
v<bitCount) ; ++i) {
3273 if (bits[
v]) word |= 1<<i;
3276 values.push_back(llvm::ConstantInt::get(Int32Ty, word));
3280 auto fields = builder.beginStruct();
3281 fields.addInt(Int32Ty, values.size());
3282 auto array = fields.beginArray();
3283 for (
auto *
v : values) array.add(
v);
3284 array.finishAndAddTo(fields);
3286 llvm::Constant *GS =
3288 llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy);
3292llvm::Constant *CGObjCGNU::GenerateCategoryProtocolList(
const
3295 const auto RuntimeProtos =
3296 GetRuntimeProtocolList(RefPro.begin(), RefPro.end());
3298 for (
const auto *PD : RuntimeProtos)
3300 return GenerateProtocolList(Protocols);
3305 std::string ClassName =
Class->getNameAsString();
3312 auto Elements = Builder.beginStruct();
3313 Elements.add(MakeConstantString(CategoryName));
3314 Elements.add(MakeConstantString(ClassName));
3317 InstanceMethods.insert(InstanceMethods.begin(), OCD->
instmeth_begin(),
3320 GenerateMethodList(ClassName, CategoryName, InstanceMethods,
false));
3327 Elements.add(GenerateMethodList(ClassName, CategoryName, ClassMethods,
true));
3330 Elements.add(GenerateCategoryProtocolList(CatDecl));
3336 Elements.add(GeneratePropertyList(OCD,
Category,
false));
3338 Elements.add(GeneratePropertyList(OCD,
Category,
true));
3340 Elements.addNullPointer(PtrTy);
3341 Elements.addNullPointer(PtrTy);
3345 Categories.push_back(Elements.finishAndCreateGlobal(
3346 std::string(
".objc_category_") + ClassName + CategoryName,
3350llvm::Constant *CGObjCGNU::GeneratePropertyList(
const Decl *Container,
3352 bool isClassProperty,
3353 bool protocolOptionalProperties) {
3357 bool isProtocol = isa<ObjCProtocolDecl>(OCD);
3360 std::function<void(
const ObjCProtocolDecl *Proto)> collectProtocolProperties
3362 for (
const auto *
P : Proto->protocols())
3363 collectProtocolProperties(
P);
3364 for (
const auto *PD : Proto->properties()) {
3365 if (isClassProperty != PD->isClassProperty())
3373 Properties.push_back(PD);
3379 for (
auto *PD : ClassExt->properties()) {
3380 if (isClassProperty != PD->isClassProperty())
3383 Properties.push_back(PD);
3387 if (isClassProperty != PD->isClassProperty())
3391 if (isProtocol && (protocolOptionalProperties != PD->isOptional()))
3398 Properties.push_back(PD);
3403 collectProtocolProperties(
P);
3405 for (
const auto *
P : CD->protocols())
3406 collectProtocolProperties(
P);
3408 auto numProperties = Properties.size();
3410 if (numProperties == 0)
3414 auto propertyList = builder.beginStruct();
3415 auto properties = PushPropertyListHeader(propertyList, numProperties);
3419 for (
auto *property : Properties) {
3420 bool isSynthesized =
false;
3421 bool isDynamic =
false;
3425 isSynthesized = (propertyImpl->getPropertyImplementation() ==
3427 isDynamic = (propertyImpl->getPropertyImplementation() ==
3431 PushProperty(properties, property, Container, isSynthesized, isDynamic);
3433 properties.finishAndAddTo(propertyList);
3435 return propertyList.finishAndCreateGlobal(
".objc_property_list",
3453 std::string SuperClassName;
3454 if (SuperClassDecl) {
3456 EmitClassRef(SuperClassName);
3466 std::string classSymbolName =
"__objc_class_name_" + ClassName;
3467 if (
auto *symbol = TheModule.getGlobalVariable(classSymbolName)) {
3468 symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0));
3470 new llvm::GlobalVariable(TheModule, LongTy,
false,
3471 llvm::GlobalValue::ExternalLinkage,
3472 llvm::ConstantInt::get(LongTy, 0),
3488 auto IvarOffsetValues = IvarOffsetBuilder.beginArray(PtrToIntTy);
3492 int superInstanceSize = !SuperClassDecl ? 0 :
3497 instanceSize = 0 - (instanceSize - superInstanceSize);
3503 IvarNames.push_back(MakeConstantString(IVD->getNameAsString()));
3505 std::string TypeStr;
3507 IvarTypes.push_back(MakeConstantString(TypeStr));
3508 IvarAligns.push_back(llvm::ConstantInt::get(IntTy,
3511 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
3514 Offset = BaseOffset - superInstanceSize;
3516 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
3518 std::string OffsetName =
"__objc_ivar_offset_value_" + ClassName +
"." +
3519 IVD->getNameAsString();
3521 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
3523 OffsetVar->setInitializer(OffsetValue);
3527 OffsetVar->setLinkage(llvm::GlobalValue::ExternalLinkage);
3529 OffsetVar =
new llvm::GlobalVariable(TheModule, Int32Ty,
3530 false, llvm::GlobalValue::ExternalLinkage,
3531 OffsetValue, OffsetName);
3532 IvarOffsets.push_back(OffsetValue);
3533 IvarOffsetValues.add(OffsetVar);
3535 IvarOwnership.push_back(lt);
3538 StrongIvars.push_back(
true);
3539 WeakIvars.push_back(
false);
3542 StrongIvars.push_back(
false);
3543 WeakIvars.push_back(
true);
3546 StrongIvars.push_back(
false);
3547 WeakIvars.push_back(
false);
3550 llvm::Constant *StrongIvarBitmap = MakeBitField(StrongIvars);
3551 llvm::Constant *WeakIvarBitmap = MakeBitField(WeakIvars);
3552 llvm::GlobalVariable *IvarOffsetArray =
3553 IvarOffsetValues.finishAndCreateGlobal(
".ivar.offsets",
3558 InstanceMethods.insert(InstanceMethods.begin(), OID->
instmeth_begin(),
3565 llvm::Constant *Properties = GeneratePropertyList(OID, ClassDecl);
3568 auto RefProtocols = ClassDecl->
protocols();
3569 auto RuntimeProtocols =
3570 GetRuntimeProtocolList(RefProtocols.begin(), RefProtocols.end());
3572 for (
const auto *I : RuntimeProtocols)
3573 Protocols.push_back(I->getNameAsString());
3576 llvm::Constant *SuperClass;
3577 if (!SuperClassName.empty()) {
3578 SuperClass = MakeConstantString(SuperClassName,
".super_class_name");
3580 SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty);
3585 llvm::Constant *MethodList = GenerateMethodList(ClassName,
"",
3586 InstanceMethods,
false);
3587 llvm::Constant *ClassMethodList = GenerateMethodList(ClassName,
"",
3588 ClassMethods,
true);
3589 llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
3590 IvarOffsets, IvarAligns, IvarOwnership);
3601 llvm::Type *IndexTy = Int32Ty;
3602 llvm::Constant *offsetPointerIndexes[] = {Zeros[0],
3603 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 2 : 1),
nullptr,
3604 llvm::ConstantInt::get(IndexTy, ClassABIVersion > 1 ? 3 : 2) };
3606 unsigned ivarIndex = 0;
3609 const std::string Name = GetIVarOffsetVariableName(ClassDecl, IVD);
3610 offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, ivarIndex);
3612 llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr(
3613 cast<llvm::GlobalVariable>(IvarList)->getValueType(), IvarList,
3614 offsetPointerIndexes);
3616 llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name);
3618 offset->setInitializer(offsetValue);
3622 offset->setLinkage(llvm::GlobalValue::ExternalLinkage);
3625 new llvm::GlobalVariable(TheModule, offsetValue->getType(),
3626 false, llvm::GlobalValue::ExternalLinkage, offsetValue, Name);
3629 llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0);
3632 llvm::Constant *MetaClassStruct = GenerateClassStructure(
3633 NULLPtr, NULLPtr, 0x12L, ClassName.c_str(),
nullptr, Zeros[0],
3634 NULLPtr, ClassMethodList, NULLPtr, NULLPtr,
3635 GeneratePropertyList(OID, ClassDecl,
true), ZeroPtr, ZeroPtr,
true);
3640 llvm::Constant *ClassStruct = GenerateClassStructure(
3641 MetaClassStruct, SuperClass, 0x11L, ClassName.c_str(),
nullptr,
3642 llvm::ConstantInt::get(LongTy, instanceSize), IvarList, MethodList,
3643 GenerateProtocolList(Protocols), IvarOffsetArray, Properties,
3644 StrongIvarBitmap, WeakIvarBitmap);
3649 if (ClassPtrAlias) {
3650 ClassPtrAlias->replaceAllUsesWith(ClassStruct);
3651 ClassPtrAlias->eraseFromParent();
3652 ClassPtrAlias =
nullptr;
3654 if (MetaClassPtrAlias) {
3655 MetaClassPtrAlias->replaceAllUsesWith(MetaClassStruct);
3656 MetaClassPtrAlias->eraseFromParent();
3657 MetaClassPtrAlias =
nullptr;
3661 Classes.push_back(ClassStruct);
3664llvm::Function *CGObjCGNU::ModuleInitFunction() {
3666 if (Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
3671 GenerateProtocolHolderCategory();
3673 llvm::StructType *selStructTy = dyn_cast<llvm::StructType>(SelectorElemTy);
3676 { PtrToInt8Ty, PtrToInt8Ty });
3680 llvm::Constant *statics = NULLPtr;
3681 if (!ConstantStrings.empty()) {
3682 llvm::GlobalVariable *fileStatics = [&] {
3684 auto staticsStruct = builder.beginStruct();
3687 if (stringClass.empty()) stringClass =
"NXConstantString";
3688 staticsStruct.add(MakeConstantString(stringClass,
3689 ".objc_static_class_name"));
3691 auto array = staticsStruct.beginArray();
3692 array.addAll(ConstantStrings);
3694 array.finishAndAddTo(staticsStruct);
3696 return staticsStruct.finishAndCreateGlobal(
".objc_statics",
3701 auto allStaticsArray = builder.beginArray(fileStatics->getType());
3702 allStaticsArray.add(fileStatics);
3703 allStaticsArray.addNullPointer(fileStatics->getType());
3705 statics = allStaticsArray.finishAndCreateGlobal(
".objc_statics_ptr",
3712 unsigned selectorCount;
3715 llvm::GlobalVariable *selectorList = [&] {
3717 auto selectors = builder.beginArray(selStructTy);
3719 std::vector<Selector> allSelectors;
3720 for (
auto &entry : table)
3721 allSelectors.push_back(entry.first);
3722 llvm::sort(allSelectors);
3724 for (
auto &untypedSel : allSelectors) {
3725 std::string selNameStr = untypedSel.getAsString();
3726 llvm::Constant *selName = ExportUniqueString(selNameStr,
".objc_sel_name");
3728 for (TypedSelector &sel : table[untypedSel]) {
3729 llvm::Constant *selectorTypeEncoding = NULLPtr;
3730 if (!sel.first.empty())
3731 selectorTypeEncoding =
3732 MakeConstantString(sel.first,
".objc_sel_types");
3734 auto selStruct = selectors.beginStruct(selStructTy);
3735 selStruct.add(selName);
3736 selStruct.add(selectorTypeEncoding);
3737 selStruct.finishAndAddTo(selectors);
3740 selectorAliases.push_back(sel.second);
3745 selectorCount = selectors.size();
3751 auto selStruct = selectors.beginStruct(selStructTy);
3752 selStruct.add(NULLPtr);
3753 selStruct.add(NULLPtr);
3754 selStruct.finishAndAddTo(selectors);
3756 return selectors.finishAndCreateGlobal(
".objc_selector_list",
3761 for (
unsigned i = 0; i < selectorCount; ++i) {
3762 llvm::Constant *idxs[] = {
3764 llvm::ConstantInt::get(Int32Ty, i)
3767 llvm::Constant *selPtr = llvm::ConstantExpr::getGetElementPtr(
3768 selectorList->getValueType(), selectorList, idxs);
3769 selectorAliases[i]->replaceAllUsesWith(selPtr);
3770 selectorAliases[i]->eraseFromParent();
3773 llvm::GlobalVariable *symtab = [&] {
3775 auto symtab = builder.beginStruct();
3778 symtab.addInt(LongTy, selectorCount);
3780 symtab.add(selectorList);
3783 symtab.addInt(CGM.
Int16Ty, Classes.size());
3785 symtab.addInt(CGM.
Int16Ty, Categories.size());
3788 auto classList = symtab.beginArray(PtrToInt8Ty);
3789 classList.addAll(Classes);
3790 classList.addAll(Categories);
3792 classList.add(statics);
3793 classList.add(NULLPtr);
3794 classList.finishAndAddTo(symtab);
3802 llvm::Constant *module = [&] {
3803 llvm::Type *moduleEltTys[] = {
3804 LongTy, LongTy, PtrToInt8Ty, symtab->getType(), IntTy
3806 llvm::StructType *moduleTy = llvm::StructType::get(
3808 ArrayRef(moduleEltTys).drop_back(
unsigned(RuntimeVersion < 10)));
3811 auto module = builder.beginStruct(moduleTy);
3813 module.addInt(LongTy, RuntimeVersion);
3815 module.addInt(LongTy, CGM.
getDataLayout().getTypeStoreSize(moduleTy));
3822 module.add(MakeConstantString(path,
".objc_source_file_name"));
3825 if (RuntimeVersion >= 10) {
3828 module.addInt(IntTy, 2);
3832 module.addInt(IntTy, 1);
3834 module.addInt(IntTy, 0);
3837 module.addInt(IntTy, 1);
3847 llvm::Function * LoadFunction = llvm::Function::Create(
3848 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
3849 llvm::GlobalValue::InternalLinkage,
".objc_load_function",
3851 llvm::BasicBlock *EntryBB =
3852 llvm::BasicBlock::Create(VMContext,
"entry", LoadFunction);
3854 Builder.SetInsertPoint(EntryBB);
3856 llvm::FunctionType *FT =
3857 llvm::FunctionType::get(Builder.getVoidTy(), module->getType(),
true);
3858 llvm::FunctionCallee Register =
3860 Builder.CreateCall(Register, module);
3862 if (!ClassAliases.empty()) {
3863 llvm::Type *ArgTypes[2] = {PtrTy, PtrToInt8Ty};
3864 llvm::FunctionType *RegisterAliasTy =
3865 llvm::FunctionType::get(Builder.getVoidTy(),
3867 llvm::Function *RegisterAlias = llvm::Function::Create(
3869 llvm::GlobalValue::ExternalWeakLinkage,
"class_registerAlias_np",
3871 llvm::BasicBlock *AliasBB =
3872 llvm::BasicBlock::Create(VMContext,
"alias", LoadFunction);
3873 llvm::BasicBlock *NoAliasBB =
3874 llvm::BasicBlock::Create(VMContext,
"no_alias", LoadFunction);
3877 llvm::Value *HasRegisterAlias = Builder.CreateICmpNE(RegisterAlias,
3878 llvm::Constant::getNullValue(RegisterAlias->getType()));
3879 Builder.CreateCondBr(HasRegisterAlias, AliasBB, NoAliasBB);
3882 Builder.SetInsertPoint(AliasBB);
3884 for (std::vector<ClassAliasPair>::iterator iter = ClassAliases.begin();
3885 iter != ClassAliases.end(); ++iter) {
3886 llvm::Constant *TheClass =
3887 TheModule.getGlobalVariable(
"_OBJC_CLASS_" + iter->first,
true);
3889 Builder.CreateCall(RegisterAlias,
3890 {TheClass, MakeConstantString(iter->second)});
3894 Builder.CreateBr(NoAliasBB);
3897 Builder.SetInsertPoint(NoAliasBB);
3899 Builder.CreateRetVoid();
3901 return LoadFunction;
3904llvm::Function *CGObjCGNU::GenerateMethod(
const ObjCMethodDecl *OMD,
3907 llvm::FunctionType *MethodTy =
3908 Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
3909 std::string FunctionName = getSymbolNameForMethod(OMD);
3911 llvm::Function *Method
3912 = llvm::Function::Create(MethodTy,
3913 llvm::GlobalValue::InternalLinkage,
3926llvm::FunctionCallee CGObjCGNU::GetPropertyGetFunction() {
3927 return GetPropertyFn;
3930llvm::FunctionCallee CGObjCGNU::GetPropertySetFunction() {
3931 return SetPropertyFn;
3934llvm::FunctionCallee CGObjCGNU::GetOptimizedPropertySetFunction(
bool atomic,
3939llvm::FunctionCallee CGObjCGNU::GetGetStructFunction() {
3940 return GetStructPropertyFn;
3943llvm::FunctionCallee CGObjCGNU::GetSetStructFunction() {
3944 return SetStructPropertyFn;
3947llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectGetFunction() {
3951llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectSetFunction() {
3955llvm::FunctionCallee CGObjCGNU::EnumerationMutationFunction() {
3956 return EnumerationMutationFn;
3961 EmitAtSynchronizedStmt(CGF, S, SyncEnterFn, SyncExitFn);
3978 EmitTryCatchStmt(CGF, S, EnterCatchFn, ExitCatchFn, ExceptionReThrowFn);
3983 bool ClearInsertionPoint) {
3984 llvm::Value *ExceptionAsObject;
3985 bool isRethrow =
false;
3987 if (
const Expr *ThrowExpr = S.getThrowExpr()) {
3989 ExceptionAsObject = Exception;
3992 "Unexpected rethrow outside @catch block.");
3996 if (isRethrow && usesSEHExceptions) {
4005 Throw->setDoesNotReturn();
4008 ExceptionAsObject = CGF.
Builder.CreateBitCast(ExceptionAsObject, IdTy);
4009 llvm::CallBase *Throw =
4011 Throw->setDoesNotReturn();
4013 CGF.
Builder.CreateUnreachable();
4014 if (ClearInsertionPoint)
4015 CGF.
Builder.ClearInsertionPoint();
4021 return B.CreateCall(WeakReadFn,
4022 EnforceType(B, AddrWeakObj.
getPointer(), PtrToIdTy));
4026 llvm::Value *src,
Address dst) {
4028 src = EnforceType(B, src, IdTy);
4029 llvm::Value *dstVal = EnforceType(B, dst.
getPointer(), PtrToIdTy);
4030 B.CreateCall(WeakAssignFn, {src, dstVal});
4034 llvm::Value *src,
Address dst,
4037 src = EnforceType(B, src, IdTy);
4038 llvm::Value *dstVal = EnforceType(B, dst.
getPointer(), PtrToIdTy);
4040 assert(!threadlocal &&
"EmitObjCGlobalAssign - Threal Local API NYI");
4041 B.CreateCall(GlobalAssignFn, {src, dstVal});
4045 llvm::Value *src,
Address dst,
4046 llvm::Value *ivarOffset) {
4048 src = EnforceType(B, src, IdTy);
4049 llvm::Value *dstVal = EnforceType(B, dst.
getPointer(), IdTy);
4050 B.CreateCall(IvarAssignFn, {src, dstVal, ivarOffset});
4054 llvm::Value *src,
Address dst) {
4056 src = EnforceType(B, src, IdTy);
4057 llvm::Value *dstVal = EnforceType(B, dst.
getPointer(), PtrToIdTy);
4058 B.CreateCall(StrongCastAssignFn, {src, dstVal});
4064 llvm::Value *Size) {
4066 llvm::Value *DestPtrVal = EnforceType(B, DestPtr.
getPointer(), PtrTy);
4067 llvm::Value *SrcPtrVal = EnforceType(B, SrcPtr.
getPointer(), PtrTy);
4069 B.CreateCall(MemMoveFn, {DestPtrVal, SrcPtrVal,
Size});
4072llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
4075 const std::string Name = GetIVarOffsetVariableName(ID, Ivar);
4079 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
4080 if (!IvarOffsetPointer)
4081 IvarOffsetPointer =
new llvm::GlobalVariable(
4082 TheModule, llvm::PointerType::getUnqual(VMContext),
false,
4083 llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
4084 return IvarOffsetPointer;
4089 llvm::Value *BaseValue,
4091 unsigned CVRQualifiers) {
4094 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
4095 EmitIvarOffset(CGF, ID, Ivar));
4123 if (RuntimeVersion < 10 ||
4125 return CGF.
Builder.CreateZExtOrBitCast(
4129 llvm::PointerType::getUnqual(VMContext),
4130 ObjCIvarOffsetVariable(
Interface, Ivar),
4134 std::string
name =
"__objc_ivar_offset_value_" +
4137 llvm::Value *Offset = TheModule.getGlobalVariable(name);
4139 auto GV =
new llvm::GlobalVariable(TheModule, IntTy,
4140 false, llvm::GlobalValue::LinkOnceAnyLinkage,
4141 llvm::Constant::getNullValue(IntTy), name);
4146 if (Offset->getType() != PtrDiffTy)
4147 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
4151 return llvm::ConstantInt::get(PtrDiffTy, Offset,
true);
4157 switch (Runtime.getKind()) {
4159 if (Runtime.getVersion() >= VersionTuple(2, 0))
4160 return new CGObjCGNUstep2(CGM);
4161 return new CGObjCGNUstep(CGM);
4164 return new CGObjCGCC(CGM);
4167 return new CGObjCObjFW(CGM);
4173 llvm_unreachable(
"these runtimes are not GNU runtimes");
4175 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.
llvm::Value * EmitObjCThrowOperand(const Expr *expr)
llvm::Value * LoadObjCSelf()
LoadObjCSelf - Load the value of self.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
static bool hasAggregateEvaluationKind(QualType T)
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.
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.
bool hasParamDestroyedInCallee() const
True if the method has a parameter that's destroyed in the callee.
Selector getSelector() const
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 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