28 #include "llvm/ADT/SmallVector.h"
29 #include "llvm/ADT/StringMap.h"
30 #include "llvm/IR/CallSite.h"
31 #include "llvm/IR/DataLayout.h"
32 #include "llvm/IR/Intrinsics.h"
33 #include "llvm/IR/LLVMContext.h"
34 #include "llvm/IR/Module.h"
35 #include "llvm/Support/Compiler.h"
38 using namespace clang;
39 using namespace CodeGen;
45 class LazyRuntimeFunction {
47 llvm::FunctionType *FTy;
48 const char *FunctionName;
56 : CGM(nullptr), FunctionName(nullptr),
Function(nullptr) {}
65 std::vector<llvm::Type *> ArgTys;
69 ArgTys.push_back(ArgTy);
71 FTy = llvm::FunctionType::get(RetTy, ArgTys,
false);
74 llvm::FunctionType *getType() {
return FTy; }
78 operator llvm::Constant *() {
83 cast<llvm::Constant>(CGM->CreateRuntimeFunction(FTy, FunctionName));
87 operator llvm::Function *() {
88 return cast<llvm::Function>((llvm::Constant *)*
this);
99 llvm::Module &TheModule;
102 llvm::StructType *ObjCSuperTy;
105 llvm::PointerType *PtrToObjCSuperTy;
109 llvm::PointerType *SelectorTy;
112 llvm::IntegerType *Int8Ty;
115 llvm::PointerType *PtrToInt8Ty;
121 llvm::PointerType *IMPTy;
126 llvm::PointerType *IdTy;
129 llvm::PointerType *PtrToIdTy;
134 llvm::IntegerType *IntTy;
138 llvm::PointerType *PtrTy;
142 llvm::IntegerType *LongTy;
144 llvm::IntegerType *SizeTy;
146 llvm::IntegerType *IntPtrTy;
148 llvm::IntegerType *PtrDiffTy;
151 llvm::PointerType *PtrToIntTy;
155 llvm::IntegerType *Int32Ty;
157 llvm::IntegerType *Int64Ty;
161 unsigned msgSendMDKind;
166 llvm::Constant *MakeConstantString(
const std::string &Str,
167 const std::string &
Name=
"") {
169 return llvm::ConstantExpr::getGetElementPtr(Array.
getElementType(),
177 llvm::Constant *ExportUniqueString(
const std::string &Str,
178 const std::string prefix) {
179 std::string name = prefix + Str;
180 auto *ConstStr = TheModule.getGlobalVariable(name);
182 llvm::Constant *value = llvm::ConstantDataArray::getString(VMContext,Str);
183 ConstStr =
new llvm::GlobalVariable(TheModule, value->getType(),
true,
184 llvm::GlobalValue::LinkOnceODRLinkage, value, prefix + Str);
186 return llvm::ConstantExpr::getGetElementPtr(ConstStr->getValueType(),
193 llvm::GlobalVariable *MakeGlobal(llvm::StructType *Ty,
197 llvm::GlobalValue::LinkageTypes linkage
199 llvm::Constant *
C = llvm::ConstantStruct::get(Ty, V);
200 auto GV =
new llvm::GlobalVariable(TheModule, Ty,
false,
209 llvm::GlobalVariable *MakeGlobal(llvm::ArrayType *Ty,
213 llvm::GlobalValue::LinkageTypes linkage
215 llvm::Constant *C = llvm::ConstantArray::get(Ty, V);
216 auto GV =
new llvm::GlobalVariable(TheModule, Ty,
false,
224 llvm::GlobalVariable *MakeGlobalArray(
llvm::Type *Ty,
228 llvm::GlobalValue::LinkageTypes linkage
230 llvm::ArrayType *ArrayTy = llvm::ArrayType::get(Ty, V.size());
231 return MakeGlobal(ArrayTy, V, Align,
Name, linkage);
236 const Decl *Container) {
240 std::string NameAndAttributes;
242 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr);
243 NameAndAttributes +=
'\0';
244 NameAndAttributes += TypeStr.length() + 3;
245 NameAndAttributes += TypeStr;
246 NameAndAttributes +=
'\0';
248 return MakeConstantString(NameAndAttributes);
254 void PushPropertyAttributes(std::vector<llvm::Constant*> &Fields,
257 int attrs =
property->getPropertyAttributes();
266 Fields.push_back(llvm::ConstantInt::get(Int8Ty, attrs & 0xff));
272 attrs |= isSynthesized ? (1<<0) : 0;
276 Fields.push_back(llvm::ConstantInt::get(Int8Ty, attrs & 0xff));
278 Fields.push_back(llvm::ConstantInt::get(Int8Ty, 0));
279 Fields.push_back(llvm::ConstantInt::get(Int8Ty, 0));
286 if (V->getType() == Ty)
return V;
290 if (V.
getType() == Ty)
return V;
295 llvm::Constant *Zeros[2];
297 llvm::Constant *NULLPtr;
299 llvm::LLVMContext &VMContext;
306 llvm::GlobalAlias *ClassPtrAlias;
311 llvm::GlobalAlias *MetaClassPtrAlias;
313 std::vector<llvm::Constant*> Classes;
315 std::vector<llvm::Constant*> Categories;
318 std::vector<llvm::Constant*> ConstantStrings;
322 llvm::StringMap<llvm::Constant*> ObjCStrings;
324 llvm::StringMap<llvm::Constant*> ExistingProtocols;
330 typedef std::pair<std::string, llvm::GlobalAlias*> TypedSelector;
334 typedef llvm::DenseMap<Selector, SmallVector<TypedSelector, 2> >
342 Selector RetainSel, ReleaseSel, AutoreleaseSel;
346 LazyRuntimeFunction IvarAssignFn, StrongCastAssignFn, MemMoveFn, WeakReadFn,
347 WeakAssignFn, GlobalAssignFn;
349 typedef std::pair<std::string, std::string> ClassAliasPair;
351 std::vector<ClassAliasPair> ClassAliases;
355 LazyRuntimeFunction ExceptionThrowFn;
358 LazyRuntimeFunction ExceptionReThrowFn;
361 LazyRuntimeFunction EnterCatchFn;
364 LazyRuntimeFunction ExitCatchFn;
366 LazyRuntimeFunction SyncEnterFn;
368 LazyRuntimeFunction SyncExitFn;
373 LazyRuntimeFunction EnumerationMutationFn;
376 LazyRuntimeFunction GetPropertyFn;
379 LazyRuntimeFunction SetPropertyFn;
381 LazyRuntimeFunction GetStructPropertyFn;
383 LazyRuntimeFunction SetStructPropertyFn;
394 const int ProtocolVersion;
409 llvm::Constant *GenerateMethodList(StringRef ClassName,
410 StringRef CategoryName,
413 bool isClassMethodList);
418 llvm::Constant *GenerateEmptyProtocol(
const std::string &ProtocolName);
434 void GenerateProtocolHolderCategory();
437 llvm::Constant *GenerateClassStructure(
438 llvm::Constant *MetaClass,
439 llvm::Constant *SuperClass,
442 llvm::Constant *Version,
443 llvm::Constant *InstanceSize,
444 llvm::Constant *IVars,
445 llvm::Constant *Methods,
446 llvm::Constant *Protocols,
447 llvm::Constant *IvarOffsets,
448 llvm::Constant *Properties,
449 llvm::Constant *StrongIvarBitmap,
450 llvm::Constant *WeakIvarBitmap,
455 llvm::Constant *GenerateProtocolMethodList(
462 const std::string &TypeEncoding);
471 void EmitClassRef(
const std::string &className);
475 const std::string &
Name,
bool isWeak);
484 MessageSendInfo &MSI) = 0;
492 MessageSendInfo &MSI) = 0;
509 unsigned protocolClassVersion);
532 llvm::Constant *GetEHType(
QualType T)
override;
542 llvm::Function *ModuleInitFunction()
override;
543 llvm::Constant *GetPropertyGetFunction()
override;
544 llvm::Constant *GetPropertySetFunction()
override;
545 llvm::Constant *GetOptimizedPropertySetFunction(
bool atomic,
547 llvm::Constant *GetSetStructFunction()
override;
548 llvm::Constant *GetGetStructFunction()
override;
549 llvm::Constant *GetCppAtomicObjectGetFunction()
override;
550 llvm::Constant *GetCppAtomicObjectSetFunction()
override;
551 llvm::Constant *EnumerationMutationFunction()
override;
559 bool ClearInsertionPoint=
true)
override;
566 bool threadlocal=
false)
override;
576 unsigned CVRQualifiers)
override;
594 llvm::GlobalVariable *GetClassGlobal(StringRef
Name,
595 bool Weak =
false)
override {
608 class CGObjCGCC :
public CGObjCGNU {
611 LazyRuntimeFunction MsgLookupFn;
615 LazyRuntimeFunction MsgLookupSuperFn;
620 MessageSendInfo &MSI)
override {
623 EnforceType(Builder, Receiver, IdTy),
624 EnforceType(Builder, cmd, SelectorTy) };
626 imp->setMetadata(msgSendMDKind, node);
627 return imp.getInstruction();
633 llvm::Value *lookupArgs[] = {EnforceType(Builder, ObjCSuper,
634 PtrToObjCSuperTy).getPointer(), cmd};
641 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy,
644 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
645 PtrToObjCSuperTy, SelectorTy,
nullptr);
650 class CGObjCGNUstep :
public CGObjCGNU {
653 LazyRuntimeFunction SlotLookupFn;
658 LazyRuntimeFunction SlotLookupSuperFn;
660 LazyRuntimeFunction SetPropertyAtomic;
662 LazyRuntimeFunction SetPropertyAtomicCopy;
664 LazyRuntimeFunction SetPropertyNonAtomic;
666 LazyRuntimeFunction SetPropertyNonAtomicCopy;
669 LazyRuntimeFunction CxxAtomicObjectGetFn;
672 LazyRuntimeFunction CxxAtomicObjectSetFn;
678 llvm::Constant *GetEHType(
QualType T)
override;
683 MessageSendInfo &MSI)
override {
685 llvm::Function *LookupFn = SlotLookupFn;
697 self = llvm::ConstantPointerNull::get(IdTy);
701 LookupFn->setDoesNotCapture(1);
704 EnforceType(Builder, ReceiverPtr.
getPointer(), PtrToIdTy),
705 EnforceType(Builder, cmd, SelectorTy),
706 EnforceType(Builder,
self, IdTy) };
708 slot.setOnlyReadsMemory();
709 slot->setMetadata(msgSendMDKind, node);
718 Receiver = Builder.
CreateLoad(ReceiverPtr,
true);
724 MessageSendInfo &MSI)
override {
728 llvm::CallInst *slot =
730 slot->setOnlyReadsMemory();
740 llvm::StructType *SlotStructTy = llvm::StructType::get(PtrTy,
741 PtrTy, PtrTy, IntTy, IMPTy,
nullptr);
742 SlotTy = llvm::PointerType::getUnqual(SlotStructTy);
744 SlotLookupFn.init(&CGM,
"objc_msg_lookup_sender", SlotTy, PtrToIdTy,
745 SelectorTy, IdTy,
nullptr);
747 SlotLookupSuperFn.init(&CGM,
"objc_slot_lookup_super", SlotTy,
748 PtrToObjCSuperTy, SelectorTy,
nullptr);
750 if (CGM.getLangOpts().CPlusPlus) {
751 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
753 EnterCatchFn.init(&CGM,
"__cxa_begin_catch", PtrTy, PtrTy,
nullptr);
755 ExitCatchFn.init(&CGM,
"__cxa_end_catch", VoidTy,
nullptr);
757 ExceptionReThrowFn.init(&CGM,
"_Unwind_Resume_or_Rethrow", VoidTy,
760 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
762 EnterCatchFn.init(&CGM,
"objc_begin_catch", IdTy, PtrTy,
nullptr);
764 ExitCatchFn.init(&CGM,
"objc_end_catch", VoidTy,
nullptr);
766 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy,
769 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
770 SetPropertyAtomic.init(&CGM,
"objc_setProperty_atomic", VoidTy, IdTy,
771 SelectorTy, IdTy, PtrDiffTy,
nullptr);
772 SetPropertyAtomicCopy.init(&CGM,
"objc_setProperty_atomic_copy", VoidTy,
773 IdTy, SelectorTy, IdTy, PtrDiffTy,
nullptr);
774 SetPropertyNonAtomic.init(&CGM,
"objc_setProperty_nonatomic", VoidTy,
775 IdTy, SelectorTy, IdTy, PtrDiffTy,
nullptr);
776 SetPropertyNonAtomicCopy.init(&CGM,
"objc_setProperty_nonatomic_copy",
777 VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy,
nullptr);
780 CxxAtomicObjectSetFn.init(&CGM,
"objc_setCppObjectAtomic", VoidTy, PtrTy,
781 PtrTy, PtrTy,
nullptr);
784 CxxAtomicObjectGetFn.init(&CGM,
"objc_getCppObjectAtomic", VoidTy, PtrTy,
785 PtrTy, PtrTy,
nullptr);
788 llvm::Constant *GetCppAtomicObjectGetFunction()
override {
791 assert (CGM.getLangOpts().ObjCRuntime.getVersion() >=
793 return CxxAtomicObjectGetFn;
796 llvm::Constant *GetCppAtomicObjectSetFunction()
override {
799 assert (CGM.getLangOpts().ObjCRuntime.getVersion() >=
801 return CxxAtomicObjectSetFn;
804 llvm::Constant *GetOptimizedPropertySetFunction(
bool atomic,
805 bool copy)
override {
812 assert (CGM.getLangOpts().ObjCRuntime.getVersion() >=
816 if (copy)
return SetPropertyAtomicCopy;
817 return SetPropertyAtomic;
820 return copy ? SetPropertyNonAtomicCopy : SetPropertyNonAtomic;
825 class CGObjCObjFW:
public CGObjCGNU {
829 LazyRuntimeFunction MsgLookupFn;
832 LazyRuntimeFunction MsgLookupFnSRet;
836 LazyRuntimeFunction MsgLookupSuperFn, MsgLookupSuperFnSRet;
840 MessageSendInfo &MSI)
override {
843 EnforceType(Builder, Receiver, IdTy),
844 EnforceType(Builder, cmd, SelectorTy) };
847 if (CGM.ReturnTypeUsesSRet(MSI.CallInfo))
852 imp->setMetadata(msgSendMDKind, node);
853 return imp.getInstruction();
860 EnforceType(Builder, ObjCSuper.
getPointer(), PtrToObjCSuperTy), cmd,
863 if (CGM.ReturnTypeUsesSRet(MSI.CallInfo))
870 bool isWeak)
override {
872 return CGObjCGNU::GetClassNamed(CGF, Name, isWeak);
875 std::string SymbolName =
"_OBJC_CLASS_" +
Name;
876 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(SymbolName);
878 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
880 nullptr, SymbolName);
887 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy,
nullptr);
888 MsgLookupFnSRet.init(&CGM,
"objc_msg_lookup_stret", IMPTy, IdTy,
889 SelectorTy,
nullptr);
891 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
892 PtrToObjCSuperTy, SelectorTy,
nullptr);
893 MsgLookupSuperFnSRet.init(&CGM,
"objc_msg_lookup_super_stret", IMPTy,
894 PtrToObjCSuperTy, SelectorTy,
nullptr);
902 void CGObjCGNU::EmitClassRef(
const std::string &className) {
903 std::string symbolRef =
"__objc_class_ref_" + className;
905 if (TheModule.getGlobalVariable(symbolRef))
907 std::string symbolName =
"__objc_class_name_" + className;
908 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
910 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
912 nullptr, symbolName);
914 new llvm::GlobalVariable(TheModule, ClassSymbol->getType(),
true,
915 llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef);
919 StringRef CategoryName,
const Selector MethodName,
920 bool isClassMethod) {
921 std::string MethodNameColonStripped = MethodName.
getAsString();
922 std::replace(MethodNameColonStripped.begin(), MethodNameColonStripped.end(),
924 return (Twine(isClassMethod ?
"_c_" :
"_i_") + ClassName +
"_" +
925 CategoryName +
"_" + MethodNameColonStripped).str();
928 CGObjCGNU::CGObjCGNU(
CodeGenModule &cgm,
unsigned runtimeABIVersion,
929 unsigned protocolClassVersion)
931 VMContext(cgm.getLLVMContext()), ClassPtrAlias(nullptr),
932 MetaClassPtrAlias(nullptr), RuntimeVersion(runtimeABIVersion),
933 ProtocolVersion(protocolClassVersion) {
935 msgSendMDKind = VMContext.getMDKindID(
"GNUObjCMessageSend");
938 IntTy = cast<llvm::IntegerType>(
940 LongTy = cast<llvm::IntegerType>(
942 SizeTy = cast<llvm::IntegerType>(
943 Types.
ConvertType(CGM.getContext().getSizeType()));
944 PtrDiffTy = cast<llvm::IntegerType>(
945 Types.
ConvertType(CGM.getContext().getPointerDiffType()));
946 BoolTy = CGM.getTypes().ConvertType(CGM.getContext().BoolTy);
948 Int8Ty = llvm::Type::getInt8Ty(VMContext);
950 PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
952 Zeros[0] = llvm::ConstantInt::get(LongTy, 0);
954 NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty);
956 QualType selTy = CGM.getContext().getObjCSelType();
958 SelectorTy = PtrToInt8Ty;
960 SelectorTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(selTy));
963 PtrToIntTy = llvm::PointerType::getUnqual(IntTy);
966 Int32Ty = llvm::Type::getInt32Ty(VMContext);
967 Int64Ty = llvm::Type::getInt64Ty(VMContext);
970 CGM.getDataLayout().getPointerSizeInBits() == 32 ? Int32Ty : Int64Ty;
973 QualType UnqualIdTy = CGM.getContext().getObjCIdType();
976 ASTIdTy = CGM.getContext().getCanonicalType(UnqualIdTy);
977 IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy));
981 PtrToIdTy = llvm::PointerType::getUnqual(IdTy);
983 ObjCSuperTy = llvm::StructType::get(IdTy, IdTy,
nullptr);
984 PtrToObjCSuperTy = llvm::PointerType::getUnqual(ObjCSuperTy);
986 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
989 ExceptionThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy,
nullptr);
990 ExceptionReThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy,
nullptr);
992 SyncEnterFn.init(&CGM,
"objc_sync_enter", IntTy, IdTy,
nullptr);
994 SyncExitFn.init(&CGM,
"objc_sync_exit", IntTy, IdTy,
nullptr);
997 EnumerationMutationFn.init(&CGM,
"objc_enumerationMutation", VoidTy,
1001 GetPropertyFn.init(&CGM,
"objc_getProperty", IdTy, IdTy, SelectorTy,
1002 PtrDiffTy, BoolTy,
nullptr);
1004 SetPropertyFn.init(&CGM,
"objc_setProperty", VoidTy, IdTy, SelectorTy,
1005 PtrDiffTy, IdTy, BoolTy, BoolTy,
nullptr);
1007 GetStructPropertyFn.init(&CGM,
"objc_getPropertyStruct", VoidTy, PtrTy, PtrTy,
1008 PtrDiffTy, BoolTy, BoolTy,
nullptr);
1010 SetStructPropertyFn.init(&CGM,
"objc_setPropertyStruct", VoidTy, PtrTy, PtrTy,
1011 PtrDiffTy, BoolTy, BoolTy,
nullptr);
1014 llvm::Type *IMPArgs[] = { IdTy, SelectorTy };
1015 IMPTy = llvm::PointerType::getUnqual(llvm::FunctionType::get(IdTy, IMPArgs,
1019 if ((Opts.getGC() != LangOptions::NonGC) || Opts.ObjCAutoRefCount)
1020 RuntimeVersion = 10;
1023 if (Opts.getGC() != LangOptions::NonGC) {
1035 IvarAssignFn.init(&CGM,
"objc_assign_ivar", IdTy, IdTy, IdTy, PtrDiffTy,
1038 StrongCastAssignFn.init(&CGM,
"objc_assign_strongCast", IdTy, IdTy,
1039 PtrToIdTy,
nullptr);
1041 GlobalAssignFn.init(&CGM,
"objc_assign_global", IdTy, IdTy, PtrToIdTy,
1044 WeakAssignFn.init(&CGM,
"objc_assign_weak", IdTy, IdTy, PtrToIdTy,
nullptr);
1046 WeakReadFn.init(&CGM,
"objc_read_weak", IdTy, PtrToIdTy,
nullptr);
1048 MemMoveFn.init(&CGM,
"objc_memmove_collectable", PtrTy, PtrTy, PtrTy,
1054 const std::string &Name,
bool isWeak) {
1055 llvm::Constant *ClassName = MakeConstantString(Name);
1066 llvm::Constant *ClassLookupFn =
1067 CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, PtrToInt8Ty,
true),
1068 "objc_lookup_class");
1078 if (CGM.getTriple().isOSBinFormatCOFF()) {
1079 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value)) {
1080 auto DLLStorage = llvm::GlobalValue::DefaultStorageClass;
1081 if (OID->hasAttr<DLLExportAttr>())
1082 DLLStorage = llvm::GlobalValue::DLLExportStorageClass;
1083 else if (OID->hasAttr<DLLImportAttr>())
1084 DLLStorage = llvm::GlobalValue::DLLImportStorageClass;
1085 ClassSymbol->setDLLStorageClass(DLLStorage);
1092 auto *
Value = GetClassNamed(CGF,
"NSAutoreleasePool",
false);
1093 if (CGM.getTriple().isOSBinFormatCOFF()) {
1094 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value)) {
1097 DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl);
1100 for (
const auto &Result : DC->
lookup(&II))
1101 if ((VD = dyn_cast<VarDecl>(Result)))
1104 auto DLLStorage = llvm::GlobalValue::DefaultStorageClass;
1105 if (!VD || VD->hasAttr<DLLImportAttr>())
1106 DLLStorage = llvm::GlobalValue::DLLImportStorageClass;
1107 else if (VD->hasAttr<DLLExportAttr>())
1108 DLLStorage = llvm::GlobalValue::DLLExportStorageClass;
1110 ClassSymbol->setDLLStorageClass(DLLStorage);
1117 const std::string &TypeEncoding) {
1119 llvm::GlobalAlias *SelValue =
nullptr;
1122 e = Types.end() ; i!=e ; i++) {
1123 if (i->first == TypeEncoding) {
1124 SelValue = i->second;
1130 SelectorTy->getElementType(), 0, llvm::GlobalValue::PrivateLinkage,
1131 ".objc_selector_" + Sel.
getAsString(), &TheModule);
1132 Types.emplace_back(TypeEncoding, SelValue);
1150 return GetSelector(CGF, Sel, std::string());
1155 std::string SelTypes;
1156 CGM.getContext().getObjCEncodingForMethodDecl(Method, SelTypes);
1157 return GetSelector(CGF, Method->
getSelector(), SelTypes);
1160 llvm::Constant *CGObjCGNU::GetEHType(
QualType T) {
1166 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
1167 return MakeConstantString(
"@id");
1175 assert(OPT &&
"Invalid @catch type.");
1177 assert(IDecl &&
"Invalid @catch type.");
1181 llvm::Constant *CGObjCGNUstep::GetEHType(
QualType T) {
1182 if (!CGM.getLangOpts().CPlusPlus)
1183 return CGObjCGNU::GetEHType(T);
1191 llvm::Constant *IDEHType =
1192 CGM.getModule().getGlobalVariable(
"__objc_id_type_info");
1195 new llvm::GlobalVariable(CGM.getModule(), PtrToInt8Ty,
1198 nullptr,
"__objc_id_type_info");
1199 return llvm::ConstantExpr::getBitCast(IDEHType, PtrToInt8Ty);
1204 assert(PT &&
"Invalid @catch type.");
1206 assert(IT &&
"Invalid @catch type.");
1209 std::string typeinfoName =
"__objc_eh_typeinfo_" + className;
1212 llvm::Constant *typeinfo = TheModule.getGlobalVariable(typeinfoName);
1214 return llvm::ConstantExpr::getBitCast(typeinfo, PtrToInt8Ty);
1221 const char *vtableName =
"_ZTVN7gnustep7libobjc22__objc_class_type_infoE";
1222 auto *Vtable = TheModule.getGlobalVariable(vtableName);
1224 Vtable =
new llvm::GlobalVariable(TheModule, PtrToInt8Ty,
true,
1226 nullptr, vtableName);
1228 llvm::Constant *Two = llvm::ConstantInt::get(IntTy, 2);
1229 auto *BVtable = llvm::ConstantExpr::getBitCast(
1230 llvm::ConstantExpr::getGetElementPtr(Vtable->getValueType(), Vtable, Two),
1233 llvm::Constant *typeName =
1234 ExportUniqueString(className,
"__objc_eh_typename_");
1236 std::vector<llvm::Constant*> fields;
1237 fields.push_back(BVtable);
1238 fields.push_back(typeName);
1239 llvm::Constant *TI =
1240 MakeGlobal(llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty,
nullptr),
1241 fields, CGM.getPointerAlign(),
1242 "__objc_eh_typeinfo_" + className,
1243 llvm::GlobalValue::LinkOnceODRLinkage);
1244 return llvm::ConstantExpr::getBitCast(TI, PtrToInt8Ty);
1250 std::string Str = SL->
getString().str();
1251 CharUnits Align = CGM.getPointerAlign();
1255 if (old != ObjCStrings.end())
1258 StringRef StringClass = CGM.getLangOpts().ObjCConstantStringClass;
1260 if (StringClass.empty()) StringClass =
"NXConstantString";
1262 std::string Sym =
"_OBJC_CLASS_";
1265 llvm::Constant *
isa = TheModule.getNamedGlobal(Sym);
1268 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
1269 llvm::GlobalValue::ExternalWeakLinkage,
nullptr, Sym);
1270 else if (isa->getType() != PtrToIdTy)
1271 isa = llvm::ConstantExpr::getBitCast(isa, PtrToIdTy);
1273 std::vector<llvm::Constant*> Ivars;
1274 Ivars.push_back(isa);
1275 Ivars.push_back(MakeConstantString(Str));
1276 Ivars.push_back(llvm::ConstantInt::get(IntTy, Str.size()));
1277 llvm::Constant *ObjCStr = MakeGlobal(
1278 llvm::StructType::get(PtrToIdTy, PtrToInt8Ty, IntTy,
nullptr),
1279 Ivars, Align,
".objc_str");
1280 ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStr, PtrToInt8Ty);
1281 ObjCStrings[Str] = ObjCStr;
1282 ConstantStrings.push_back(ObjCStr);
1295 bool isCategoryImpl,
1297 bool IsClassMessage,
1301 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
1302 if (Sel == RetainSel || Sel == AutoreleaseSel) {
1303 return RValue::get(EnforceType(Builder, Receiver,
1304 CGM.getTypes().ConvertType(ResultType)));
1306 if (Sel == ReleaseSel) {
1307 return RValue::get(
nullptr);
1314 ActualArgs.
add(RValue::get(EnforceType(Builder, Receiver, IdTy)), ASTIdTy);
1318 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
1321 if (isCategoryImpl) {
1322 llvm::Constant *classLookupFunction =
nullptr;
1323 if (IsClassMessage) {
1324 classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
1325 IdTy, PtrTy,
true),
"objc_get_meta_class");
1327 classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
1328 IdTy, PtrTy,
true),
"objc_get_class");
1330 ReceiverClass = Builder.CreateCall(classLookupFunction,
1338 if (IsClassMessage) {
1339 if (!MetaClassPtrAlias) {
1344 ReceiverClass = MetaClassPtrAlias;
1346 if (!ClassPtrAlias) {
1351 ReceiverClass = ClassPtrAlias;
1355 llvm::Type *CastTy = llvm::StructType::get(IdTy, IdTy,
nullptr);
1357 llvm::PointerType::getUnqual(CastTy));
1364 llvm::StructType *ObjCSuperTy = llvm::StructType::get(
1365 Receiver->getType(), IdTy,
nullptr);
1376 ObjCSuper = EnforceType(Builder, ObjCSuper, PtrToObjCSuperTy);
1379 llvm::Value *imp = LookupIMPSuper(CGF, ObjCSuper, cmd, MSI);
1380 imp = EnforceType(Builder, imp, MSI.MessengerType);
1382 llvm::Metadata *impMD[] = {
1383 llvm::MDString::get(VMContext, Sel.
getAsString()),
1385 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
1386 llvm::Type::getInt1Ty(VMContext), IsClassMessage))};
1387 llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD);
1389 llvm::Instruction *call;
1390 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, imp, Return, ActualArgs,
1392 call->setMetadata(msgSendMDKind, node);
1409 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
1410 if (Sel == RetainSel || Sel == AutoreleaseSel) {
1411 return RValue::get(EnforceType(Builder, Receiver,
1412 CGM.getTypes().ConvertType(ResultType)));
1414 if (Sel == ReleaseSel) {
1415 return RValue::get(
nullptr);
1433 llvm::BasicBlock *startBB =
nullptr;
1434 llvm::BasicBlock *messageBB =
nullptr;
1435 llvm::BasicBlock *continueBB =
nullptr;
1437 if (!isPointerSizedReturn) {
1438 startBB = Builder.GetInsertBlock();
1442 llvm::Value *isNil = Builder.CreateICmpEQ(Receiver,
1443 llvm::Constant::getNullValue(Receiver->getType()));
1444 Builder.CreateCondBr(isNil, continueBB, messageBB);
1448 IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy));
1451 cmd = GetSelector(CGF, Method);
1453 cmd = GetSelector(CGF, Sel);
1454 cmd = EnforceType(Builder, cmd, SelectorTy);
1455 Receiver = EnforceType(Builder, Receiver, IdTy);
1457 llvm::Metadata *impMD[] = {
1458 llvm::MDString::get(VMContext, Sel.
getAsString()),
1459 llvm::MDString::get(VMContext, Class ? Class->
getNameAsString() :
""),
1460 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
1461 llvm::Type::getInt1Ty(VMContext), Class !=
nullptr))};
1462 llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD);
1465 ActualArgs.
add(RValue::get(Receiver), ASTIdTy);
1469 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
1477 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
1478 case CodeGenOptions::Legacy:
1479 imp = LookupIMP(CGF, Receiver, cmd, node, MSI);
1481 case CodeGenOptions::Mixed:
1482 case CodeGenOptions::NonLegacy:
1483 if (CGM.ReturnTypeUsesFPRet(ResultType)) {
1484 imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy,
true),
1485 "objc_msgSend_fpret");
1486 }
else if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) {
1489 imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy,
true),
1490 "objc_msgSend_stret");
1492 imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy,
true),
1498 ActualArgs[0] =
CallArg(RValue::get(Receiver), ASTIdTy,
false);
1500 imp = EnforceType(Builder, imp, MSI.MessengerType);
1502 llvm::Instruction *call;
1503 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, imp, Return, ActualArgs,
1505 call->setMetadata(msgSendMDKind, node);
1508 if (!isPointerSizedReturn) {
1509 messageBB = CGF.
Builder.GetInsertBlock();
1510 CGF.
Builder.CreateBr(continueBB);
1514 llvm::PHINode *phi = Builder.CreatePHI(v->getType(), 2);
1515 phi->addIncoming(v, messageBB);
1516 phi->addIncoming(llvm::Constant::getNullValue(v->getType()), startBB);
1517 msgRet = RValue::get(phi);
1520 llvm::PHINode *phi = Builder.CreatePHI(v.
getType(), 2);
1523 CGF.
InitTempAlloca(NullVal, llvm::Constant::getNullValue(RetTy));
1525 phi->addIncoming(NullVal.
getPointer(), startBB);
1528 std::pair<llvm::Value*,llvm::Value*> v = msgRet.
getComplexVal();
1529 llvm::PHINode *phi = Builder.CreatePHI(v.first->getType(), 2);
1530 phi->addIncoming(v.first, messageBB);
1531 phi->addIncoming(llvm::Constant::getNullValue(v.first->getType()),
1533 llvm::PHINode *phi2 = Builder.CreatePHI(v.second->getType(), 2);
1534 phi2->addIncoming(v.second, messageBB);
1535 phi2->addIncoming(llvm::Constant::getNullValue(v.second->getType()),
1537 msgRet = RValue::getComplex(phi, phi2);
1545 llvm::Constant *CGObjCGNU::
1546 GenerateMethodList(StringRef ClassName,
1547 StringRef CategoryName,
1550 bool isClassMethodList) {
1551 if (MethodSels.empty())
1554 llvm::StructType *ObjCMethodTy = llvm::StructType::get(
1559 std::vector<llvm::Constant*> Methods;
1560 for (
unsigned int i = 0, e = MethodTypes.size(); i < e; ++i) {
1561 llvm::Constant *Method =
1564 isClassMethodList));
1565 assert(Method &&
"Can't generate metadata for method that doesn't exist");
1566 llvm::Constant *C = MakeConstantString(MethodSels[i].getAsString());
1567 Method = llvm::ConstantExpr::getBitCast(Method,
1570 llvm::ConstantStruct::get(ObjCMethodTy, {
C, MethodTypes[i], Method}));
1574 llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodTy,
1576 llvm::Constant *MethodArray = llvm::ConstantArray::get(ObjCMethodArrayTy,
1581 llvm::Type *NextPtrTy = llvm::PointerType::getUnqual(ObjCMethodListTy);
1582 ObjCMethodListTy->setBody(
1589 Methods.push_back(llvm::ConstantPointerNull::get(
1590 llvm::PointerType::getUnqual(ObjCMethodListTy)));
1591 Methods.push_back(llvm::ConstantInt::get(Int32Ty, MethodTypes.size()));
1592 Methods.push_back(MethodArray);
1595 return MakeGlobal(ObjCMethodListTy, Methods, CGM.getPointerAlign(),
1596 ".objc_method_list");
1600 llvm::Constant *CGObjCGNU::
1604 if (IvarNames.size() == 0)
1607 llvm::StructType *ObjCIvarTy = llvm::StructType::get(
1612 std::vector<llvm::Constant*> Ivars;
1613 for (
unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {
1614 Ivars.push_back(llvm::ConstantStruct::get(
1615 ObjCIvarTy, {IvarNames[i], IvarTypes[i], IvarOffsets[i]}));
1619 llvm::ArrayType *ObjCIvarArrayTy = llvm::ArrayType::get(ObjCIvarTy,
1622 llvm::Constant *Elements[] = {
1623 llvm::ConstantInt::get(IntTy, (
int)IvarNames.size()),
1624 llvm::ConstantArray::get(ObjCIvarArrayTy, Ivars)};
1626 llvm::StructType *ObjCIvarListTy = llvm::StructType::get(IntTy,
1631 return MakeGlobal(ObjCIvarListTy, Elements, CGM.getPointerAlign(),
1636 llvm::Constant *CGObjCGNU::GenerateClassStructure(
1637 llvm::Constant *MetaClass,
1638 llvm::Constant *SuperClass,
1641 llvm::Constant *Version,
1642 llvm::Constant *InstanceSize,
1643 llvm::Constant *IVars,
1644 llvm::Constant *Methods,
1645 llvm::Constant *Protocols,
1646 llvm::Constant *IvarOffsets,
1647 llvm::Constant *Properties,
1648 llvm::Constant *StrongIvarBitmap,
1649 llvm::Constant *WeakIvarBitmap,
1658 llvm::StructType *ClassTy = llvm::StructType::get(
1675 IvarOffsets->getType(),
1676 Properties->getType(),
1680 llvm::Constant *Zero = llvm::ConstantInt::get(LongTy, 0);
1682 std::vector<llvm::Constant*> Elements;
1683 Elements.push_back(llvm::ConstantExpr::getBitCast(MetaClass, PtrToInt8Ty));
1684 Elements.push_back(SuperClass);
1685 Elements.push_back(MakeConstantString(Name,
".class_name"));
1686 Elements.push_back(Zero);
1687 Elements.push_back(llvm::ConstantInt::get(LongTy, info));
1689 llvm::DataLayout td(&TheModule);
1691 llvm::ConstantInt::get(LongTy,
1692 td.getTypeSizeInBits(ClassTy) /
1693 CGM.getContext().getCharWidth()));
1695 Elements.push_back(InstanceSize);
1696 Elements.push_back(IVars);
1697 Elements.push_back(Methods);
1698 Elements.push_back(NULLPtr);
1699 Elements.push_back(NULLPtr);
1700 Elements.push_back(NULLPtr);
1701 Elements.push_back(llvm::ConstantExpr::getBitCast(Protocols, PtrTy));
1702 Elements.push_back(NULLPtr);
1703 Elements.push_back(llvm::ConstantInt::get(LongTy, 1));
1704 Elements.push_back(IvarOffsets);
1705 Elements.push_back(Properties);
1706 Elements.push_back(StrongIvarBitmap);
1707 Elements.push_back(WeakIvarBitmap);
1712 std::string ClassSym((isMeta ?
"_OBJC_METACLASS_":
"_OBJC_CLASS_") +
1714 llvm::GlobalVariable *ClassRef = TheModule.getNamedGlobal(ClassSym);
1715 llvm::Constant *Class =
1716 MakeGlobal(ClassTy, Elements, CGM.getPointerAlign(), ClassSym,
1719 ClassRef->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(Class,
1720 ClassRef->getType()));
1721 ClassRef->removeFromParent();
1722 Class->setName(ClassSym);
1727 llvm::Constant *CGObjCGNU::
1731 llvm::StructType *ObjCMethodDescTy = llvm::StructType::get(
1735 std::vector<llvm::Constant*> Methods;
1736 for (
unsigned int i = 0, e = MethodTypes.size() ; i < e ; i++) {
1737 Methods.push_back(llvm::ConstantStruct::get(
1738 ObjCMethodDescTy, {MethodNames[i], MethodTypes[i]}));
1740 llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodDescTy,
1741 MethodNames.size());
1742 llvm::Constant *Array = llvm::ConstantArray::get(ObjCMethodArrayTy,
1744 llvm::StructType *ObjCMethodDescListTy = llvm::StructType::get(
1745 IntTy, ObjCMethodArrayTy,
nullptr);
1747 Methods.push_back(llvm::ConstantInt::get(IntTy, MethodNames.size()));
1748 Methods.push_back(Array);
1749 return MakeGlobal(ObjCMethodDescListTy, Methods, CGM.getPointerAlign(),
1750 ".objc_method_list");
1755 llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrToInt8Ty,
1757 llvm::StructType *ProtocolListTy = llvm::StructType::get(
1762 std::vector<llvm::Constant*> Elements;
1763 for (
const std::string *iter = Protocols.begin(), *endIter = Protocols.end();
1764 iter != endIter ; iter++) {
1765 llvm::Constant *protocol =
nullptr;
1767 ExistingProtocols.find(*iter);
1768 if (value == ExistingProtocols.end()) {
1769 protocol = GenerateEmptyProtocol(*iter);
1771 protocol = value->getValue();
1773 llvm::Constant *Ptr = llvm::ConstantExpr::getBitCast(protocol,
1775 Elements.push_back(Ptr);
1777 llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
1780 Elements.push_back(NULLPtr);
1781 Elements.push_back(llvm::ConstantInt::get(LongTy, Protocols.size()));
1782 Elements.push_back(ProtocolArray);
1783 return MakeGlobal(ProtocolListTy, Elements, CGM.getPointerAlign(),
1784 ".objc_protocol_list");
1791 CGM.getTypes().ConvertType(CGM.getContext().getObjCProtoType());
1795 llvm::Constant *CGObjCGNU::GenerateEmptyProtocol(
1796 const std::string &ProtocolName) {
1800 llvm::Constant *ProtocolList = GenerateProtocolList(EmptyStringVector);
1801 llvm::Constant *MethodList =
1802 GenerateProtocolMethodList(EmptyConstantVector, EmptyConstantVector);
1805 llvm::StructType *ProtocolTy = llvm::StructType::get(IdTy,
1807 ProtocolList->getType(),
1808 MethodList->getType(),
1809 MethodList->getType(),
1810 MethodList->getType(),
1811 MethodList->getType(),
1815 llvm::Constant *Elements[] = {
1816 llvm::ConstantExpr::getIntToPtr(
1817 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy),
1818 MakeConstantString(ProtocolName,
".objc_protocol_name"), ProtocolList,
1819 MethodList, MethodList, MethodList, MethodList};
1820 return MakeGlobal(ProtocolTy, Elements, CGM.getPointerAlign(),
1834 Protocols.push_back(PI->getNameAsString());
1840 std::string TypeStr;
1842 if (
I->getImplementationControl() == ObjCMethodDecl::Optional) {
1843 OptionalInstanceMethodNames.push_back(
1844 MakeConstantString(
I->getSelector().getAsString()));
1845 OptionalInstanceMethodTypes.push_back(MakeConstantString(TypeStr));
1847 InstanceMethodNames.push_back(
1848 MakeConstantString(
I->getSelector().getAsString()));
1849 InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
1858 std::string TypeStr;
1860 if (
I->getImplementationControl() == ObjCMethodDecl::Optional) {
1861 OptionalClassMethodNames.push_back(
1862 MakeConstantString(
I->getSelector().getAsString()));
1863 OptionalClassMethodTypes.push_back(MakeConstantString(TypeStr));
1865 ClassMethodNames.push_back(
1866 MakeConstantString(
I->getSelector().getAsString()));
1867 ClassMethodTypes.push_back(MakeConstantString(TypeStr));
1871 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
1872 llvm::Constant *InstanceMethodList =
1873 GenerateProtocolMethodList(InstanceMethodNames, InstanceMethodTypes);
1874 llvm::Constant *ClassMethodList =
1875 GenerateProtocolMethodList(ClassMethodNames, ClassMethodTypes);
1876 llvm::Constant *OptionalInstanceMethodList =
1877 GenerateProtocolMethodList(OptionalInstanceMethodNames,
1878 OptionalInstanceMethodTypes);
1879 llvm::Constant *OptionalClassMethodList =
1880 GenerateProtocolMethodList(OptionalClassMethodNames,
1881 OptionalClassMethodTypes);
1888 llvm::StructType *PropertyMetadataTy = llvm::StructType::get(
1889 PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty,
1890 PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty,
nullptr);
1891 std::vector<llvm::Constant*> Properties;
1892 std::vector<llvm::Constant*> OptionalProperties;
1897 std::vector<llvm::Constant*> Fields;
1899 Fields.push_back(MakePropertyEncodingString(property,
nullptr));
1900 PushPropertyAttributes(Fields, property);
1903 std::string TypeStr;
1905 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
1906 InstanceMethodTypes.push_back(TypeEncoding);
1907 Fields.push_back(MakeConstantString(getter->getSelector().getAsString()));
1908 Fields.push_back(TypeEncoding);
1910 Fields.push_back(NULLPtr);
1911 Fields.push_back(NULLPtr);
1914 std::string TypeStr;
1916 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
1917 InstanceMethodTypes.push_back(TypeEncoding);
1918 Fields.push_back(MakeConstantString(setter->getSelector().getAsString()));
1919 Fields.push_back(TypeEncoding);
1921 Fields.push_back(NULLPtr);
1922 Fields.push_back(NULLPtr);
1925 OptionalProperties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
1927 Properties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
1930 llvm::Constant *PropertyArray = llvm::ConstantArray::get(
1931 llvm::ArrayType::get(PropertyMetadataTy, Properties.size()), Properties);
1932 llvm::Constant* PropertyListInitFields[] =
1933 {llvm::ConstantInt::get(IntTy, Properties.size()), NULLPtr, PropertyArray};
1935 llvm::Constant *PropertyListInit =
1936 llvm::ConstantStruct::getAnon(PropertyListInitFields);
1937 llvm::Constant *PropertyList =
new llvm::GlobalVariable(TheModule,
1939 PropertyListInit,
".objc_property_list");
1941 llvm::Constant *OptionalPropertyArray =
1942 llvm::ConstantArray::get(llvm::ArrayType::get(PropertyMetadataTy,
1943 OptionalProperties.size()) , OptionalProperties);
1944 llvm::Constant* OptionalPropertyListInitFields[] = {
1945 llvm::ConstantInt::get(IntTy, OptionalProperties.size()), NULLPtr,
1946 OptionalPropertyArray };
1948 llvm::Constant *OptionalPropertyListInit =
1949 llvm::ConstantStruct::getAnon(OptionalPropertyListInitFields);
1950 llvm::Constant *OptionalPropertyList =
new llvm::GlobalVariable(TheModule,
1951 OptionalPropertyListInit->getType(),
false,
1953 ".objc_property_list");
1957 llvm::StructType *ProtocolTy = llvm::StructType::get(IdTy,
1959 ProtocolList->getType(),
1960 InstanceMethodList->getType(),
1961 ClassMethodList->getType(),
1962 OptionalInstanceMethodList->getType(),
1963 OptionalClassMethodList->getType(),
1964 PropertyList->getType(),
1965 OptionalPropertyList->getType(),
1969 llvm::Constant *Elements[] = {
1970 llvm::ConstantExpr::getIntToPtr(
1971 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy),
1972 MakeConstantString(ProtocolName,
".objc_protocol_name"), ProtocolList,
1973 InstanceMethodList, ClassMethodList, OptionalInstanceMethodList,
1974 OptionalClassMethodList, PropertyList, OptionalPropertyList};
1975 ExistingProtocols[ProtocolName] =
1976 llvm::ConstantExpr::getBitCast(MakeGlobal(ProtocolTy, Elements,
1977 CGM.getPointerAlign(),
".objc_protocol"), IdTy);
1979 void CGObjCGNU::GenerateProtocolHolderCategory() {
1984 std::vector<llvm::Constant*> Elements;
1985 const std::string ClassName =
"__ObjC_Protocol_Holder_Ugly_Hack";
1986 const std::string CategoryName =
"AnotherHack";
1987 Elements.push_back(MakeConstantString(CategoryName));
1988 Elements.push_back(MakeConstantString(ClassName));
1990 Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
1991 ClassName, CategoryName, MethodSels, MethodTypes,
false), PtrTy));
1993 Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
1994 ClassName, CategoryName, MethodSels, MethodTypes,
true), PtrTy));
1996 llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrTy,
1997 ExistingProtocols.size());
1998 llvm::StructType *ProtocolListTy = llvm::StructType::get(
2003 std::vector<llvm::Constant*> ProtocolElements;
2004 for (llvm::StringMapIterator<llvm::Constant*> iter =
2005 ExistingProtocols.begin(), endIter = ExistingProtocols.end();
2006 iter != endIter ; iter++) {
2007 llvm::Constant *Ptr = llvm::ConstantExpr::getBitCast(iter->getValue(),
2009 ProtocolElements.push_back(Ptr);
2011 llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
2013 ProtocolElements.clear();
2014 ProtocolElements.push_back(NULLPtr);
2015 ProtocolElements.push_back(llvm::ConstantInt::get(LongTy,
2016 ExistingProtocols.size()));
2017 ProtocolElements.push_back(ProtocolArray);
2018 Elements.push_back(llvm::ConstantExpr::getBitCast(MakeGlobal(ProtocolListTy,
2019 ProtocolElements, CGM.getPointerAlign(),
2020 ".objc_protocol_list"), PtrTy));
2021 Categories.push_back(llvm::ConstantExpr::getBitCast(
2022 MakeGlobal(llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty,
2023 PtrTy, PtrTy, PtrTy,
nullptr), Elements, CGM.getPointerAlign()),
2039 int bitCount = bits.size();
2040 int ptrBits = CGM.getDataLayout().getPointerSizeInBits();
2041 if (bitCount < ptrBits) {
2043 for (
int i=0 ; i<bitCount ; ++i) {
2044 if (bits[i]) val |= 1ULL<<(i+1);
2046 return llvm::ConstantInt::get(IntPtrTy, val);
2050 while (v < bitCount) {
2052 for (
int i=0 ; (i<32) && (v<bitCount) ; ++i) {
2053 if (bits[v]) word |= 1<<i;
2056 values.push_back(llvm::ConstantInt::get(Int32Ty, word));
2058 llvm::ArrayType *arrayTy = llvm::ArrayType::get(Int32Ty, values.size());
2059 llvm::Constant *array = llvm::ConstantArray::get(arrayTy, values);
2060 llvm::Constant *fields[2] = {
2061 llvm::ConstantInt::get(Int32Ty, values.size()),
2063 llvm::Constant *GS = MakeGlobal(llvm::StructType::get(Int32Ty, arrayTy,
2064 nullptr), fields, CharUnits::fromQuantity(4));
2065 llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy);
2076 InstanceMethodSels.push_back(
I->getSelector());
2077 std::string TypeStr;
2078 CGM.getContext().getObjCEncodingForMethodDecl(
I,TypeStr);
2079 InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
2086 ClassMethodSels.push_back(
I->getSelector());
2087 std::string TypeStr;
2088 CGM.getContext().getObjCEncodingForMethodDecl(
I,TypeStr);
2089 ClassMethodTypes.push_back(MakeConstantString(TypeStr));
2097 E = Protos.
end();
I !=
E; ++
I)
2098 Protocols.push_back((*I)->getNameAsString());
2100 llvm::Constant *Elements[] = {
2101 MakeConstantString(CategoryName), MakeConstantString(ClassName),
2103 llvm::ConstantExpr::getBitCast(
2104 GenerateMethodList(ClassName, CategoryName, InstanceMethodSels,
2105 InstanceMethodTypes,
false),
2108 llvm::ConstantExpr::getBitCast(GenerateMethodList(ClassName, CategoryName,
2110 ClassMethodTypes,
true),
2113 llvm::ConstantExpr::getBitCast(GenerateProtocolList(Protocols), PtrTy)};
2114 Categories.push_back(llvm::ConstantExpr::getBitCast(
2115 MakeGlobal(llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty,
2116 PtrTy, PtrTy, PtrTy,
nullptr), Elements, CGM.getPointerAlign()),
2126 llvm::StructType *PropertyMetadataTy = llvm::StructType::get(
2127 PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty,
2128 PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty,
nullptr);
2129 std::vector<llvm::Constant*> Properties;
2134 std::vector<llvm::Constant*> Fields;
2136 bool isSynthesized = (propertyImpl->getPropertyImplementation() ==
2137 ObjCPropertyImplDecl::Synthesize);
2138 bool isDynamic = (propertyImpl->getPropertyImplementation() ==
2139 ObjCPropertyImplDecl::Dynamic);
2141 Fields.push_back(MakePropertyEncodingString(property, OID));
2142 PushPropertyAttributes(Fields, property, isSynthesized, isDynamic);
2144 std::string TypeStr;
2146 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
2147 if (isSynthesized) {
2148 InstanceMethodTypes.push_back(TypeEncoding);
2149 InstanceMethodSels.push_back(getter->getSelector());
2151 Fields.push_back(MakeConstantString(getter->getSelector().getAsString()));
2152 Fields.push_back(TypeEncoding);
2154 Fields.push_back(NULLPtr);
2155 Fields.push_back(NULLPtr);
2158 std::string TypeStr;
2160 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
2161 if (isSynthesized) {
2162 InstanceMethodTypes.push_back(TypeEncoding);
2163 InstanceMethodSels.push_back(setter->getSelector());
2165 Fields.push_back(MakeConstantString(setter->getSelector().getAsString()));
2166 Fields.push_back(TypeEncoding);
2168 Fields.push_back(NULLPtr);
2169 Fields.push_back(NULLPtr);
2171 Properties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
2173 llvm::ArrayType *PropertyArrayTy =
2174 llvm::ArrayType::get(PropertyMetadataTy, Properties.size());
2175 llvm::Constant *PropertyArray = llvm::ConstantArray::get(PropertyArrayTy,
2177 llvm::Constant* PropertyListInitFields[] =
2178 {llvm::ConstantInt::get(IntTy, Properties.size()), NULLPtr, PropertyArray};
2180 llvm::Constant *PropertyListInit =
2181 llvm::ConstantStruct::getAnon(PropertyListInitFields);
2182 return new llvm::GlobalVariable(TheModule, PropertyListInit->getType(),
false,
2184 ".objc_property_list");
2201 std::string SuperClassName;
2202 if (SuperClassDecl) {
2204 EmitClassRef(SuperClassName);
2214 std::string classSymbolName =
"__objc_class_name_" + ClassName;
2215 if (
auto *symbol = TheModule.getGlobalVariable(classSymbolName)) {
2216 symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0));
2218 new llvm::GlobalVariable(TheModule, LongTy,
false,
2220 llvm::ConstantInt::get(LongTy, 0),
2233 std::vector<llvm::Constant*> IvarOffsetValues;
2237 int superInstanceSize = !SuperClassDecl ? 0 :
2241 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
2242 instanceSize = 0 - (instanceSize - superInstanceSize);
2248 IvarNames.push_back(MakeConstantString(IVD->getNameAsString()));
2250 std::string TypeStr;
2252 IvarTypes.push_back(MakeConstantString(TypeStr));
2254 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
2255 uint64_t
Offset = BaseOffset;
2256 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
2257 Offset = BaseOffset - superInstanceSize;
2259 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
2261 std::string OffsetName =
"__objc_ivar_offset_value_" + ClassName +
"." +
2262 IVD->getNameAsString();
2263 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
2265 OffsetVar->setInitializer(OffsetValue);
2271 OffsetVar =
new llvm::GlobalVariable(TheModule, IntTy,
2274 "__objc_ivar_offset_value_" + ClassName +
"." +
2275 IVD->getNameAsString());
2276 IvarOffsets.push_back(OffsetValue);
2277 IvarOffsetValues.push_back(OffsetVar);
2280 case Qualifiers::OCL_Strong:
2281 StrongIvars.push_back(
true);
2282 WeakIvars.push_back(
false);
2284 case Qualifiers::OCL_Weak:
2285 StrongIvars.push_back(
false);
2286 WeakIvars.push_back(
true);
2289 StrongIvars.push_back(
false);
2290 WeakIvars.push_back(
false);
2293 llvm::Constant *StrongIvarBitmap = MakeBitField(StrongIvars);
2294 llvm::Constant *WeakIvarBitmap = MakeBitField(WeakIvars);
2295 llvm::GlobalVariable *IvarOffsetArray =
2296 MakeGlobalArray(PtrToIntTy, IvarOffsetValues, CGM.getPointerAlign(),
2303 InstanceMethodSels.push_back(
I->getSelector());
2304 std::string TypeStr;
2306 InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
2309 llvm::Constant *Properties = GeneratePropertyList(OID, InstanceMethodSels,
2310 InstanceMethodTypes);
2316 ClassMethodSels.push_back(
I->getSelector());
2317 std::string TypeStr;
2319 ClassMethodTypes.push_back(MakeConstantString(TypeStr));
2324 Protocols.push_back(
I->getNameAsString());
2327 llvm::Constant *SuperClass;
2328 if (!SuperClassName.empty()) {
2329 SuperClass = MakeConstantString(SuperClassName,
".super_class_name");
2331 SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty);
2336 llvm::Constant *MethodList = GenerateMethodList(ClassName,
"",
2337 InstanceMethodSels, InstanceMethodTypes,
false);
2338 llvm::Constant *ClassMethodList = GenerateMethodList(ClassName,
"",
2339 ClassMethodSels, ClassMethodTypes,
true);
2340 llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
2352 llvm::Type *IndexTy = Int32Ty;
2353 llvm::Constant *offsetPointerIndexes[] = {Zeros[0],
2354 llvm::ConstantInt::get(IndexTy, 1),
nullptr,
2355 llvm::ConstantInt::get(IndexTy, 2) };
2357 unsigned ivarIndex = 0;
2360 const std::string Name =
"__objc_ivar_offset_" + ClassName +
'.'
2361 + IVD->getNameAsString();
2362 offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, ivarIndex);
2364 llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr(
2365 cast<llvm::GlobalVariable>(IvarList)->getValueType(), IvarList,
2366 offsetPointerIndexes);
2368 llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name);
2370 offset->setInitializer(offsetValue);
2377 offset =
new llvm::GlobalVariable(TheModule, offsetValue->getType(),
2383 llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0);
2386 llvm::Constant *MetaClassStruct = GenerateClassStructure(
2387 NULLPtr, NULLPtr, 0x12L, ClassName.c_str(),
nullptr, Zeros[0],
2388 GenerateIvarList(empty, empty, empty), ClassMethodList, NULLPtr, NULLPtr,
2389 NULLPtr, ZeroPtr, ZeroPtr,
true);
2390 if (CGM.getTriple().isOSBinFormatCOFF()) {
2391 auto Storage = llvm::GlobalValue::DefaultStorageClass;
2393 Storage = llvm::GlobalValue::DLLImportStorageClass;
2395 Storage = llvm::GlobalValue::DLLExportStorageClass;
2396 cast<llvm::GlobalValue>(MetaClassStruct)->setDLLStorageClass(Storage);
2400 llvm::Constant *ClassStruct = GenerateClassStructure(
2401 MetaClassStruct, SuperClass, 0x11L, ClassName.c_str(),
nullptr,
2402 llvm::ConstantInt::get(LongTy, instanceSize), IvarList, MethodList,
2403 GenerateProtocolList(Protocols), IvarOffsetArray, Properties,
2404 StrongIvarBitmap, WeakIvarBitmap);
2405 if (CGM.getTriple().isOSBinFormatCOFF()) {
2406 auto Storage = llvm::GlobalValue::DefaultStorageClass;
2408 Storage = llvm::GlobalValue::DLLImportStorageClass;
2410 Storage = llvm::GlobalValue::DLLExportStorageClass;
2411 cast<llvm::GlobalValue>(ClassStruct)->setDLLStorageClass(Storage);
2415 if (ClassPtrAlias) {
2416 ClassPtrAlias->replaceAllUsesWith(
2417 llvm::ConstantExpr::getBitCast(ClassStruct, IdTy));
2418 ClassPtrAlias->eraseFromParent();
2419 ClassPtrAlias =
nullptr;
2421 if (MetaClassPtrAlias) {
2422 MetaClassPtrAlias->replaceAllUsesWith(
2423 llvm::ConstantExpr::getBitCast(MetaClassStruct, IdTy));
2424 MetaClassPtrAlias->eraseFromParent();
2425 MetaClassPtrAlias =
nullptr;
2429 ClassStruct = llvm::ConstantExpr::getBitCast(ClassStruct, PtrToInt8Ty);
2430 Classes.push_back(ClassStruct);
2433 llvm::Function *CGObjCGNU::ModuleInitFunction() {
2435 if (Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
2440 GenerateProtocolHolderCategory();
2442 llvm::StructType *SelStructTy = dyn_cast<llvm::StructType>(
2443 SelectorTy->getElementType());
2444 llvm::Type *SelStructPtrTy = SelectorTy;
2446 SelStructTy = llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty,
nullptr);
2447 SelStructPtrTy = llvm::PointerType::getUnqual(SelStructTy);
2450 std::vector<llvm::Constant*> Elements;
2451 llvm::Constant *Statics = NULLPtr;
2453 if (!ConstantStrings.empty()) {
2454 llvm::ArrayType *StaticsArrayTy = llvm::ArrayType::get(PtrToInt8Ty,
2455 ConstantStrings.size() + 1);
2456 ConstantStrings.push_back(NULLPtr);
2458 StringRef StringClass = CGM.getLangOpts().ObjCConstantStringClass;
2460 if (StringClass.empty()) StringClass =
"NXConstantString";
2462 Elements.push_back(MakeConstantString(StringClass,
2463 ".objc_static_class_name"));
2464 Elements.push_back(llvm::ConstantArray::get(StaticsArrayTy,
2466 llvm::StructType *StaticsListTy =
2467 llvm::StructType::get(PtrToInt8Ty, StaticsArrayTy,
nullptr);
2468 llvm::Type *StaticsListPtrTy =
2469 llvm::PointerType::getUnqual(StaticsListTy);
2470 Statics = MakeGlobal(StaticsListTy, Elements, CGM.getPointerAlign(),
2472 llvm::ArrayType *StaticsListArrayTy =
2473 llvm::ArrayType::get(StaticsListPtrTy, 2);
2475 Elements.push_back(Statics);
2476 Elements.push_back(llvm::Constant::getNullValue(StaticsListPtrTy));
2477 Statics = MakeGlobal(StaticsListArrayTy, Elements,
2478 CGM.getPointerAlign(),
".objc_statics_ptr");
2479 Statics = llvm::ConstantExpr::getBitCast(Statics, PtrTy);
2482 llvm::ArrayType *ClassListTy = llvm::ArrayType::get(PtrToInt8Ty,
2483 Classes.size() + Categories.size() + 2);
2484 llvm::StructType *SymTabTy = llvm::StructType::get(LongTy, SelStructPtrTy,
2485 llvm::Type::getInt16Ty(VMContext),
2486 llvm::Type::getInt16Ty(VMContext),
2487 ClassListTy,
nullptr);
2491 std::vector<llvm::Constant*> Selectors;
2492 std::vector<llvm::GlobalAlias*> SelectorAliases;
2496 std::string SelNameStr = iter->first.getAsString();
2497 llvm::Constant *SelName = ExportUniqueString(SelNameStr,
".objc_sel_name");
2501 e = Types.end() ; i!=e ; i++) {
2503 llvm::Constant *SelectorTypeEncoding = NULLPtr;
2504 if (!i->first.empty())
2505 SelectorTypeEncoding = MakeConstantString(i->first,
".objc_sel_types");
2507 Elements.push_back(SelName);
2508 Elements.push_back(SelectorTypeEncoding);
2509 Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements));
2513 SelectorAliases.push_back(i->second);
2516 unsigned SelectorCount = Selectors.size();
2521 Elements.push_back(NULLPtr);
2522 Elements.push_back(NULLPtr);
2523 Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements));
2527 Elements.push_back(llvm::ConstantInt::get(LongTy, SelectorCount));
2528 llvm::GlobalVariable *SelectorList =
2529 MakeGlobalArray(SelStructTy, Selectors, CGM.getPointerAlign(),
2530 ".objc_selector_list");
2531 Elements.push_back(llvm::ConstantExpr::getBitCast(SelectorList,
2535 for (
unsigned int i=0 ; i<SelectorCount ; i++) {
2537 llvm::Constant *Idxs[] = {Zeros[0],
2538 llvm::ConstantInt::get(Int32Ty, i), Zeros[0]};
2540 llvm::Constant *SelPtr = llvm::ConstantExpr::getGetElementPtr(
2541 SelectorList->getValueType(), SelectorList, makeArrayRef(Idxs, 2));
2544 SelPtr = llvm::ConstantExpr::getBitCast(SelPtr, SelectorTy);
2545 SelectorAliases[i]->replaceAllUsesWith(SelPtr);
2546 SelectorAliases[i]->eraseFromParent();
2550 Elements.push_back(llvm::ConstantInt::get(llvm::Type::getInt16Ty(VMContext),
2553 Elements.push_back(llvm::ConstantInt::get(llvm::Type::getInt16Ty(VMContext),
2554 Categories.size()));
2556 Classes.insert(Classes.end(), Categories.begin(), Categories.end());
2558 Classes.push_back(Statics);
2559 Classes.push_back(NULLPtr);
2560 llvm::Constant *ClassList = llvm::ConstantArray::get(ClassListTy, Classes);
2561 Elements.push_back(ClassList);
2563 llvm::Constant *SymTab =
2564 MakeGlobal(SymTabTy, Elements, CGM.getPointerAlign());
2568 llvm::StructType * ModuleTy = llvm::StructType::get(LongTy, LongTy,
2569 PtrToInt8Ty, llvm::PointerType::getUnqual(SymTabTy),
2570 (RuntimeVersion >= 10) ? IntTy :
nullptr,
nullptr);
2573 Elements.push_back(llvm::ConstantInt::get(LongTy, RuntimeVersion));
2575 llvm::DataLayout td(&TheModule);
2577 llvm::ConstantInt::get(LongTy,
2578 td.getTypeSizeInBits(ModuleTy) /
2579 CGM.getContext().getCharWidth()));
2586 Elements.push_back(MakeConstantString(path,
".objc_source_file_name"));
2587 Elements.push_back(SymTab);
2589 if (RuntimeVersion >= 10)
2590 switch (CGM.getLangOpts().getGC()) {
2591 case LangOptions::GCOnly:
2592 Elements.push_back(llvm::ConstantInt::get(IntTy, 2));
2594 case LangOptions::NonGC:
2595 if (CGM.getLangOpts().ObjCAutoRefCount)
2596 Elements.push_back(llvm::ConstantInt::get(IntTy, 1));
2598 Elements.push_back(llvm::ConstantInt::get(IntTy, 0));
2600 case LangOptions::HybridGC:
2601 Elements.push_back(llvm::ConstantInt::get(IntTy, 1));
2610 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
2613 llvm::BasicBlock *EntryBB =
2616 Builder.SetInsertPoint(EntryBB);
2618 llvm::FunctionType *FT =
2619 llvm::FunctionType::get(Builder.getVoidTy(),
2620 llvm::PointerType::getUnqual(ModuleTy),
true);
2621 llvm::Value *Register = CGM.CreateRuntimeFunction(FT,
"__objc_exec_class");
2622 Builder.CreateCall(Register, Module);
2624 if (!ClassAliases.empty()) {
2625 llvm::Type *ArgTypes[2] = {PtrTy, PtrToInt8Ty};
2626 llvm::FunctionType *RegisterAliasTy =
2627 llvm::FunctionType::get(Builder.getVoidTy(),
2631 llvm::GlobalValue::ExternalWeakLinkage,
"class_registerAlias_np",
2633 llvm::BasicBlock *AliasBB =
2635 llvm::BasicBlock *NoAliasBB =
2639 llvm::Value *HasRegisterAlias = Builder.CreateICmpNE(RegisterAlias,
2640 llvm::Constant::getNullValue(RegisterAlias->getType()));
2641 Builder.CreateCondBr(HasRegisterAlias, AliasBB, NoAliasBB);
2644 Builder.SetInsertPoint(AliasBB);
2647 iter != ClassAliases.end(); ++iter) {
2648 llvm::Constant *TheClass =
2649 TheModule.getGlobalVariable((
"_OBJC_CLASS_" + iter->first).c_str(),
2652 TheClass = llvm::ConstantExpr::getBitCast(TheClass, PtrTy);
2653 Builder.CreateCall(RegisterAlias,
2654 {TheClass, MakeConstantString(iter->second)});
2658 Builder.CreateBr(NoAliasBB);
2661 Builder.SetInsertPoint(NoAliasBB);
2663 Builder.CreateRetVoid();
2665 return LoadFunction;
2668 llvm::Function *CGObjCGNU::GenerateMethod(
const ObjCMethodDecl *OMD,
2672 StringRef CategoryName = OCD ? OCD->
getName() :
"";
2673 StringRef ClassName = CD->
getName();
2678 llvm::FunctionType *MethodTy =
2681 MethodName, isClassMethod);
2683 llvm::Function *Method
2691 llvm::Constant *CGObjCGNU::GetPropertyGetFunction() {
2692 return GetPropertyFn;
2695 llvm::Constant *CGObjCGNU::GetPropertySetFunction() {
2696 return SetPropertyFn;
2699 llvm::Constant *CGObjCGNU::GetOptimizedPropertySetFunction(
bool atomic,
2704 llvm::Constant *CGObjCGNU::GetGetStructFunction() {
2705 return GetStructPropertyFn;
2708 llvm::Constant *CGObjCGNU::GetSetStructFunction() {
2709 return SetStructPropertyFn;
2712 llvm::Constant *CGObjCGNU::GetCppAtomicObjectGetFunction() {
2716 llvm::Constant *CGObjCGNU::GetCppAtomicObjectSetFunction() {
2720 llvm::Constant *CGObjCGNU::EnumerationMutationFunction() {
2721 return EnumerationMutationFn;
2726 EmitAtSynchronizedStmt(CGF, S, SyncEnterFn, SyncExitFn);
2743 EmitTryCatchStmt(CGF, S, EnterCatchFn, ExitCatchFn, ExceptionReThrowFn);
2748 bool ClearInsertionPoint) {
2753 ExceptionAsObject = Exception;
2756 "Unexpected rethrow outside @catch block.");
2760 llvm::CallSite Throw =
2762 Throw.setDoesNotReturn();
2763 CGF.
Builder.CreateUnreachable();
2764 if (ClearInsertionPoint)
2765 CGF.
Builder.ClearInsertionPoint();
2771 AddrWeakObj = EnforceType(B, AddrWeakObj, PtrToIdTy);
2772 return B.CreateCall(WeakReadFn.getType(), WeakReadFn,
2779 src = EnforceType(B, src, IdTy);
2780 dst = EnforceType(B, dst, PtrToIdTy);
2781 B.CreateCall(WeakAssignFn.getType(), WeakAssignFn,
2789 src = EnforceType(B, src, IdTy);
2790 dst = EnforceType(B, dst, PtrToIdTy);
2792 assert(!threadlocal &&
"EmitObjCGlobalAssign - Threal Local API NYI");
2793 B.CreateCall(GlobalAssignFn.getType(), GlobalAssignFn,
2801 src = EnforceType(B, src, IdTy);
2802 dst = EnforceType(B, dst, IdTy);
2803 B.CreateCall(IvarAssignFn.getType(), IvarAssignFn,
2810 src = EnforceType(B, src, IdTy);
2811 dst = EnforceType(B, dst, PtrToIdTy);
2812 B.CreateCall(StrongCastAssignFn.getType(), StrongCastAssignFn,
2821 DestPtr = EnforceType(B, DestPtr, PtrTy);
2822 SrcPtr = EnforceType(B, SrcPtr, PtrTy);
2824 B.CreateCall(MemMoveFn.getType(), MemMoveFn,
2828 llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
2831 const std::string Name =
"__objc_ivar_offset_" + ID->
getNameAsString()
2836 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
2837 if (!IvarOffsetPointer) {
2841 uint64_t Offset = -1;
2848 if (!CGM.getContext().getObjCImplementation(
2849 const_cast<ObjCInterfaceDecl *>(ID)))
2850 Offset = ComputeIvarBaseOffset(CGM, ID, Ivar);
2852 llvm::ConstantInt *OffsetGuess = llvm::ConstantInt::get(Int32Ty, Offset,
2858 if (CGM.getLangOpts().PICLevel) {
2859 llvm::GlobalVariable *IvarOffsetGV =
new llvm::GlobalVariable(TheModule,
2861 llvm::GlobalValue::PrivateLinkage, OffsetGuess, Name+
".guess");
2862 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule,
2863 IvarOffsetGV->getType(),
false, llvm::GlobalValue::LinkOnceAnyLinkage,
2864 IvarOffsetGV,
Name);
2866 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule,
2867 llvm::Type::getInt32PtrTy(VMContext),
false,
2871 return IvarOffsetPointer;
2878 unsigned CVRQualifiers) {
2881 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
2882 EmitIvarOffset(CGF, ID, Ivar));
2904 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
2910 if (RuntimeVersion < 10 ||
2912 return CGF.
Builder.CreateZExtOrBitCast(
2914 ObjCIvarOffsetVariable(Interface, Ivar),
2917 std::string name =
"__objc_ivar_offset_value_" +
2920 llvm::Value *Offset = TheModule.getGlobalVariable(name);
2922 auto GV =
new llvm::GlobalVariable(TheModule, IntTy,
2923 false, llvm::GlobalValue::LinkOnceAnyLinkage,
2924 llvm::Constant::getNullValue(IntTy), name);
2929 if (Offset->getType() != PtrDiffTy)
2930 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
2933 uint64_t Offset = ComputeIvarBaseOffset(CGF.
CGM, Interface, Ivar);
2934 return llvm::ConstantInt::get(PtrDiffTy, Offset,
true);
2940 case ObjCRuntime::GNUstep:
2941 return new CGObjCGNUstep(CGM);
2943 case ObjCRuntime::GCC:
2944 return new CGObjCGCC(CGM);
2946 case ObjCRuntime::ObjFW:
2947 return new CGObjCObjFW(CGM);
2949 case ObjCRuntime::FragileMacOSX:
2950 case ObjCRuntime::MacOSX:
2951 case ObjCRuntime::iOS:
2952 case ObjCRuntime::WatchOS:
2953 llvm_unreachable(
"these runtimes are not GNU runtimes");
2955 llvm_unreachable(
"bad runtime");
ReturnValueSlot - Contains the address where the return value of a function can be stored...
Defines the clang::ASTContext interface.
static std::string SymbolNameForMethod(StringRef ClassName, StringRef CategoryName, const Selector MethodName, bool isClassMethod)
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
static Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
External linkage, which indicates that the entity can be referred to from other translation units...
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
protocol_range protocols() const
Smart pointer class that efficiently represents Objective-C method names.
A (possibly-)qualified type.
Represents a version number in the form major[.minor[.subminor[.build]]].
Defines the clang::FileManager interface and associated types.
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
PropertyControl getPropertyImplementation() const
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
CreateTempAlloca - This creates a alloca and inserts it into the entry block.
Implements runtime-specific code generation functions.
Defines the SourceManager interface.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
llvm::LoadInst * CreateDefaultAlignedLoad(llvm::Value *Addr, const llvm::Twine &Name="")
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
Represents Objective-C's @throw statement.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
const ASTRecordLayout & getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const
Get or compute information about the layout of the specified Objective-C implementation.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
llvm::Type * getElementType() const
Return the type of the values stored in this address.
ObjCMethodDecl - Represents an instance or class method declaration.
virtual bool isDynamic(OpenMPScheduleClauseKind ScheduleKind) const
Check if the specified ScheduleKind is dynamic.
Defines the Objective-C statement AST node classes.
llvm::Constant * getPointer() const
llvm::Value * EmitObjCThrowOperand(const Expr *expr)
One of these records is kept for each identifier that is lexed.
This table allows us to fully hide how we implement multi-keyword caching.
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
Represents a class type in Objective C.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool isAnyPointerType() const
static const ObjCInterfaceDecl * FindIvarInterface(ASTContext &Context, const ObjCInterfaceDecl *OID, const ObjCIvarDecl *OIVD)
RValue EmitCall(const CGFunctionInfo &FnInfo, llvm::Value *Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, CGCalleeInfo CalleeInfo=CGCalleeInfo(), llvm::Instruction **callOrInvoke=nullptr)
EmitCall - Generate a call of the given function, expecting the given result type, and using the given argument list which specifies both the LLVM arguments and the types they were derived from.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
void InitTempAlloca(Address Alloca, llvm::Value *Value)
InitTempAlloca - Provide an initial value for the given alloca which will be observable at all locati...
Describes a module or submodule.
ObjCContainerDecl - Represents a container for method declarations.
CharUnits - This is an opaque type for sizes expressed in character units.
CharUnits getPointerSize() const
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface...
ObjCRuntime()
A bogus initialization of the runtime.
std::string getNameAsString() const
getNameAsString - Get a human-readable name for the declaration, even if it is one of the special kin...
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
Represents an Objective-C protocol declaration.
Represents an ObjC class declaration.
propimpl_range property_impls() const
detail::InMemoryDirectory::const_iterator I
llvm::CallSite EmitRuntimeCallOrInvoke(llvm::Value *callee, ArrayRef< llvm::Value * > args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
void addFrom(const CallArgList &other)
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
CGBlockInfo - Information to generate a block literal.
const TargetInfo & getTarget() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
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.
llvm::Value * getPointer() const
Expr - This represents one expression.
StringRef getName() const
Return the actual identifier string.
ASTContext & getContext() const
Represents Objective-C's @synchronized statement.
void add(RValue rvalue, QualType type, bool needscopy=false)
bool isObjCIdType() const
bool isInstanceMethod() const
clang::ObjCRuntime ObjCRuntime
bool isa(CodeGen::Address addr)
'gnustep' is the modern non-fragile GNUstep runtime.
ObjCCategoryDecl * getCategoryDecl() const
The l-value was considered opaque, so the alignment was determined from a type.
Address CreateBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
const char * getName() const
ASTContext & getContext() const
CharUnits getPointerAlign() const
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
CharUnits getSize() const
getSize - Get the record size in characters.
const TemplateArgument * iterator
Interfaces are the core concept in Objective-C for object oriented design.
const ObjCInterfaceDecl * getClassInterface() const
SmallVector< llvm::Value *, 8 > ObjCEHValueStack
ObjCEHValueStack - Stack of Objective-C exception values, used for rethrows.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
Cached information about one file (either on disk or in the virtual file system). ...
const CGFunctionInfo & arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD)
Objective-C methods are C functions with some implicit parameters.
ObjCCategoryDecl - Represents a category declaration.
const ObjCInterfaceDecl * getClassInterface() const
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
#define va_start(ap, param)
const LangOptions & getLangOpts() const
std::string getAsString() const
Derive the full selector name (e.g.
Represents one property declaration in an Objective-C interface.
const VersionTuple & getVersion() const
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
FileID getMainFileID() const
Returns the FileID of the main source file.
const char * getName() const
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
ObjCIvarDecl * getNextIvar()
CharUnits getAlignment() const
Return the alignment of this pointer.
instmeth_range instance_methods() const
This class organizes the cross-function state that is used while generating LLVM code.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
std::string getNameAsString() const
Get the name of the class associated with this interface.
The basic abstraction for the target Objective-C runtime.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
Address CreateStructGEP(Address Addr, unsigned Index, CharUnits Offset, const llvm::Twine &Name="")
llvm::LoadInst * CreateAlignedLoad(llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
__builtin_va_list va_list
const ObjCInterfaceType * getInterfaceType() const
If this pointer points to an Objective C @interface type, gets the type for that interface.
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
StringRef getString() const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Selector getSelector() const
detail::InMemoryDirectory::const_iterator E
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Represents a pointer to an Objective C object.
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
ObjCMethodDecl * getGetterMethodDecl() const
llvm::PointerType * getType() const
Return the type of the pointer value.
const T * getAs() const
Member-template getAs<specific type>'.
ObjCMethodDecl * getSetterMethodDecl() const
instprop_range instance_properties() const
This class organizes the cross-module state that is used while lowering AST types to LLVM types...
bool isObjCQualifiedIdType() const
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
protocol_range protocols() const
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
bool getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, std::string &S, bool Extended=false) const
Emit the encoded type for the method declaration Decl into S.
classmeth_range class_methods() const
BoundNodesTreeBuilder *const Builder
StringRef getName() const
getName - Get the name of identifier for the class interface associated with this implementation as a...
A specialization of Address that requires the address to be an LLVM Constant.
ObjCIvarDecl - Represents an ObjC instance variable.
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
Represents Objective-C's @try ... @catch ... @finally statement.
const Expr * getThrowExpr() const
StringLiteral - This represents a string literal expression, e.g.
ObjCInterfaceDecl * getSuperClass() const
TranslationUnitDecl - The top declaration context.
llvm::Value * LoadObjCSelf()
LoadObjCSelf - Load the value of self.
LValue - This represents an lvalue references.
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
const ASTRecordLayout & getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const
Get or compute information about the layout of the specified Objective-C interface.
const DirectoryEntry * getDir() const
Return the directory the file lives in.
CallArgList - Type for representing both the value and type of arguments in a call.
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration...
This class handles loading and caching of source files into memory.
CGCalleeInfo - Class to encapsulate the information about a callee to be used during the generation o...
ObjCCompatibleAliasDecl - Represents alias of a class.
const ObjCProtocolList & getReferencedProtocols() const
CGObjCRuntime * CreateGNUObjCRuntime(CodeGenModule &CGM)
Creates an instance of an Objective-C runtime class.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.