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"
39 using namespace clang;
40 using namespace CodeGen;
47 class LazyRuntimeFunction {
49 llvm::FunctionType *FTy;
50 const char *FunctionName;
51 llvm::Constant *Function;
58 : CGM(nullptr), FunctionName(nullptr), Function(nullptr) {}
63 void init(
CodeGenModule *Mod,
const char *name, llvm::Type *RetTy, ...) {
67 std::vector<llvm::Type *> ArgTys;
70 while (llvm::Type *ArgTy =
va_arg(Args, llvm::Type *))
71 ArgTys.push_back(ArgTy);
73 FTy = llvm::FunctionType::get(RetTy, ArgTys,
false);
76 llvm::FunctionType *getType() {
return FTy; }
80 operator llvm::Constant *() {
85 cast<llvm::Constant>(CGM->CreateRuntimeFunction(FTy, FunctionName));
89 operator llvm::Function *() {
90 return cast<llvm::Function>((llvm::Constant *)*
this);
101 llvm::Module &TheModule;
104 llvm::StructType *ObjCSuperTy;
107 llvm::PointerType *PtrToObjCSuperTy;
111 llvm::PointerType *SelectorTy;
114 llvm::IntegerType *Int8Ty;
117 llvm::PointerType *PtrToInt8Ty;
123 llvm::PointerType *IMPTy;
128 llvm::PointerType *IdTy;
131 llvm::PointerType *PtrToIdTy;
136 llvm::IntegerType *IntTy;
140 llvm::PointerType *PtrTy;
144 llvm::IntegerType *LongTy;
146 llvm::IntegerType *SizeTy;
148 llvm::IntegerType *IntPtrTy;
150 llvm::IntegerType *PtrDiffTy;
153 llvm::PointerType *PtrToIntTy;
157 llvm::IntegerType *Int32Ty;
159 llvm::IntegerType *Int64Ty;
163 unsigned msgSendMDKind;
167 llvm::Constant *MakeConstantString(
const std::string &Str,
168 const std::string &Name=
"") {
169 auto *ConstStr = CGM.GetAddrOfConstantCString(Str, Name.c_str());
170 return llvm::ConstantExpr::getGetElementPtr(ConstStr->getValueType(),
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(),
192 llvm::GlobalVariable *MakeGlobal(llvm::StructType *Ty,
195 llvm::GlobalValue::LinkageTypes linkage
197 llvm::Constant *
C = llvm::ConstantStruct::get(Ty, V);
198 return new llvm::GlobalVariable(TheModule, Ty,
false,
204 llvm::GlobalVariable *MakeGlobal(llvm::ArrayType *Ty,
207 llvm::GlobalValue::LinkageTypes linkage
209 llvm::Constant *
C = llvm::ConstantArray::get(Ty, V);
210 return new llvm::GlobalVariable(TheModule, Ty,
false,
215 llvm::GlobalVariable *MakeGlobalArray(llvm::Type *Ty,
218 llvm::GlobalValue::LinkageTypes linkage
220 llvm::ArrayType *ArrayTy = llvm::ArrayType::get(Ty, V.size());
221 return MakeGlobal(ArrayTy, V, Name, linkage);
225 const Decl *Container) {
229 std::string NameAndAttributes;
231 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr);
232 NameAndAttributes +=
'\0';
233 NameAndAttributes += TypeStr.length() + 3;
234 NameAndAttributes += TypeStr;
235 NameAndAttributes +=
'\0';
237 auto *ConstStr = CGM.GetAddrOfConstantCString(NameAndAttributes);
238 return llvm::ConstantExpr::getGetElementPtr(ConstStr->getValueType(),
244 void PushPropertyAttributes(std::vector<llvm::Constant*> &Fields,
247 int attrs =
property->getPropertyAttributes();
256 Fields.push_back(llvm::ConstantInt::get(Int8Ty, attrs & 0xff));
262 attrs |= isSynthesized ? (1<<0) : 0;
266 Fields.push_back(llvm::ConstantInt::get(Int8Ty, attrs & 0xff));
268 Fields.push_back(llvm::ConstantInt::get(Int8Ty, 0));
269 Fields.push_back(llvm::ConstantInt::get(Int8Ty, 0));
275 if (V->getType() == Ty)
return V;
276 return B.CreateBitCast(V, Ty);
279 llvm::Constant *Zeros[2];
281 llvm::Constant *NULLPtr;
283 llvm::LLVMContext &VMContext;
289 llvm::GlobalAlias *ClassPtrAlias;
294 llvm::GlobalAlias *MetaClassPtrAlias;
296 std::vector<llvm::Constant*> Classes;
298 std::vector<llvm::Constant*> Categories;
301 std::vector<llvm::Constant*> ConstantStrings;
305 llvm::StringMap<llvm::Constant*> ObjCStrings;
307 llvm::StringMap<llvm::Constant*> ExistingProtocols;
313 typedef std::pair<std::string, llvm::GlobalAlias*> TypedSelector;
317 typedef llvm::DenseMap<Selector, SmallVector<TypedSelector, 2> >
325 Selector RetainSel, ReleaseSel, AutoreleaseSel;
329 LazyRuntimeFunction IvarAssignFn, StrongCastAssignFn, MemMoveFn, WeakReadFn,
330 WeakAssignFn, GlobalAssignFn;
332 typedef std::pair<std::string, std::string> ClassAliasPair;
334 std::vector<ClassAliasPair> ClassAliases;
338 LazyRuntimeFunction ExceptionThrowFn;
341 LazyRuntimeFunction ExceptionReThrowFn;
344 LazyRuntimeFunction EnterCatchFn;
347 LazyRuntimeFunction ExitCatchFn;
349 LazyRuntimeFunction SyncEnterFn;
351 LazyRuntimeFunction SyncExitFn;
357 LazyRuntimeFunction EnumerationMutationFn;
360 LazyRuntimeFunction GetPropertyFn;
363 LazyRuntimeFunction SetPropertyFn;
365 LazyRuntimeFunction GetStructPropertyFn;
367 LazyRuntimeFunction SetStructPropertyFn;
378 const int ProtocolVersion;
392 llvm::Constant *GenerateMethodList(StringRef ClassName,
393 StringRef CategoryName,
396 bool isClassMethodList);
400 llvm::Constant *GenerateEmptyProtocol(
const std::string &ProtocolName);
413 void GenerateProtocolHolderCategory();
415 llvm::Constant *GenerateClassStructure(
416 llvm::Constant *MetaClass,
417 llvm::Constant *SuperClass,
420 llvm::Constant *Version,
421 llvm::Constant *InstanceSize,
422 llvm::Constant *IVars,
423 llvm::Constant *Methods,
424 llvm::Constant *Protocols,
425 llvm::Constant *IvarOffsets,
426 llvm::Constant *Properties,
427 llvm::Constant *StrongIvarBitmap,
428 llvm::Constant *WeakIvarBitmap,
432 llvm::Constant *GenerateProtocolMethodList(
438 const std::string &TypeEncoding,
bool lval);
445 void EmitClassRef(
const std::string &className);
448 const std::string &Name,
bool isWeak);
456 MessageSendInfo &MSI) = 0;
463 MessageSendInfo &MSI) = 0;
478 unsigned protocolClassVersion);
480 llvm::Constant *GenerateConstantString(
const StringLiteral *)
override;
498 bool lval =
false)
override;
501 llvm::Constant *GetEHType(
QualType T)
override;
511 llvm::Function *ModuleInitFunction()
override;
512 llvm::Constant *GetPropertyGetFunction()
override;
513 llvm::Constant *GetPropertySetFunction()
override;
514 llvm::Constant *GetOptimizedPropertySetFunction(
bool atomic,
516 llvm::Constant *GetSetStructFunction()
override;
517 llvm::Constant *GetGetStructFunction()
override;
518 llvm::Constant *GetCppAtomicObjectGetFunction()
override;
519 llvm::Constant *GetCppAtomicObjectSetFunction()
override;
520 llvm::Constant *EnumerationMutationFunction()
override;
528 bool ClearInsertionPoint=
true)
override;
535 bool threadlocal=
false)
override;
545 unsigned CVRQualifiers)
override;
563 llvm::GlobalVariable *GetClassGlobal(
const std::string &Name,
564 bool Weak =
false)
override {
576 class CGObjCGCC :
public CGObjCGNU {
579 LazyRuntimeFunction MsgLookupFn;
583 LazyRuntimeFunction MsgLookupSuperFn;
587 MessageSendInfo &MSI)
override {
590 EnforceType(Builder, Receiver, IdTy),
591 EnforceType(Builder, cmd, SelectorTy) };
593 imp->setMetadata(msgSendMDKind, node);
594 return imp.getInstruction();
599 llvm::Value *lookupArgs[] = {EnforceType(Builder, ObjCSuper,
600 PtrToObjCSuperTy), cmd};
606 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy,
609 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
610 PtrToObjCSuperTy, SelectorTy,
nullptr);
614 class CGObjCGNUstep :
public CGObjCGNU {
617 LazyRuntimeFunction SlotLookupFn;
622 LazyRuntimeFunction SlotLookupSuperFn;
624 LazyRuntimeFunction SetPropertyAtomic;
626 LazyRuntimeFunction SetPropertyAtomicCopy;
628 LazyRuntimeFunction SetPropertyNonAtomic;
630 LazyRuntimeFunction SetPropertyNonAtomicCopy;
633 LazyRuntimeFunction CxxAtomicObjectGetFn;
636 LazyRuntimeFunction CxxAtomicObjectSetFn;
641 llvm::Constant *GetEHType(
QualType T)
override;
645 MessageSendInfo &MSI)
override {
647 llvm::Function *LookupFn = SlotLookupFn;
651 Builder.CreateStore(Receiver, ReceiverPtr);
658 self = llvm::ConstantPointerNull::get(IdTy);
662 LookupFn->setDoesNotCapture(1);
665 EnforceType(Builder, ReceiverPtr, PtrToIdTy),
666 EnforceType(Builder, cmd, SelectorTy),
667 EnforceType(Builder,
self, IdTy) };
669 slot.setOnlyReadsMemory();
670 slot->setMetadata(msgSendMDKind, node);
674 Builder.CreateStructGEP(
nullptr, slot.getInstruction(), 4));
678 Receiver = Builder.CreateLoad(ReceiverPtr,
true);
683 MessageSendInfo &MSI)
override {
687 llvm::CallInst *slot =
689 slot->setOnlyReadsMemory();
691 return Builder.CreateLoad(Builder.CreateStructGEP(
nullptr, slot, 4));
697 llvm::StructType *SlotStructTy = llvm::StructType::get(PtrTy,
698 PtrTy, PtrTy, IntTy, IMPTy,
nullptr);
699 SlotTy = llvm::PointerType::getUnqual(SlotStructTy);
701 SlotLookupFn.init(&CGM,
"objc_msg_lookup_sender", SlotTy, PtrToIdTy,
702 SelectorTy, IdTy,
nullptr);
704 SlotLookupSuperFn.init(&CGM,
"objc_slot_lookup_super", SlotTy,
705 PtrToObjCSuperTy, SelectorTy,
nullptr);
707 if (CGM.getLangOpts().CPlusPlus) {
708 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
710 EnterCatchFn.init(&CGM,
"__cxa_begin_catch", PtrTy, PtrTy,
nullptr);
712 ExitCatchFn.init(&CGM,
"__cxa_end_catch", VoidTy,
nullptr);
714 ExceptionReThrowFn.init(&CGM,
"_Unwind_Resume_or_Rethrow", VoidTy,
717 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
719 EnterCatchFn.init(&CGM,
"objc_begin_catch", IdTy, PtrTy,
nullptr);
721 ExitCatchFn.init(&CGM,
"objc_end_catch", VoidTy,
nullptr);
723 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy,
726 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
727 SetPropertyAtomic.init(&CGM,
"objc_setProperty_atomic", VoidTy, IdTy,
728 SelectorTy, IdTy, PtrDiffTy,
nullptr);
729 SetPropertyAtomicCopy.init(&CGM,
"objc_setProperty_atomic_copy", VoidTy,
730 IdTy, SelectorTy, IdTy, PtrDiffTy,
nullptr);
731 SetPropertyNonAtomic.init(&CGM,
"objc_setProperty_nonatomic", VoidTy,
732 IdTy, SelectorTy, IdTy, PtrDiffTy,
nullptr);
733 SetPropertyNonAtomicCopy.init(&CGM,
"objc_setProperty_nonatomic_copy",
734 VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy,
nullptr);
737 CxxAtomicObjectSetFn.init(&CGM,
"objc_setCppObjectAtomic", VoidTy, PtrTy,
738 PtrTy, PtrTy,
nullptr);
741 CxxAtomicObjectGetFn.init(&CGM,
"objc_getCppObjectAtomic", VoidTy, PtrTy,
742 PtrTy, PtrTy,
nullptr);
744 llvm::Constant *GetCppAtomicObjectGetFunction()
override {
747 assert (CGM.getLangOpts().ObjCRuntime.getVersion() >=
749 return CxxAtomicObjectGetFn;
751 llvm::Constant *GetCppAtomicObjectSetFunction()
override {
754 assert (CGM.getLangOpts().ObjCRuntime.getVersion() >=
756 return CxxAtomicObjectSetFn;
758 llvm::Constant *GetOptimizedPropertySetFunction(
bool atomic,
759 bool copy)
override {
766 assert (CGM.getLangOpts().ObjCRuntime.getVersion() >=
770 if (copy)
return SetPropertyAtomicCopy;
771 return SetPropertyAtomic;
774 return copy ? SetPropertyNonAtomicCopy : SetPropertyNonAtomic;
779 class CGObjCObjFW:
public CGObjCGNU {
783 LazyRuntimeFunction MsgLookupFn;
786 LazyRuntimeFunction MsgLookupFnSRet;
790 LazyRuntimeFunction MsgLookupSuperFn, MsgLookupSuperFnSRet;
794 MessageSendInfo &MSI)
override {
797 EnforceType(Builder, Receiver, IdTy),
798 EnforceType(Builder, cmd, SelectorTy) };
801 if (CGM.ReturnTypeUsesSRet(MSI.CallInfo))
806 imp->setMetadata(msgSendMDKind, node);
807 return imp.getInstruction();
813 llvm::Value *lookupArgs[] = {EnforceType(Builder, ObjCSuper,
814 PtrToObjCSuperTy), cmd};
816 if (CGM.ReturnTypeUsesSRet(MSI.CallInfo))
823 const std::string &Name,
bool isWeak)
override {
825 return CGObjCGNU::GetClassNamed(CGF, Name, isWeak);
829 std::string SymbolName =
"_OBJC_CLASS_" + Name;
831 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(SymbolName);
834 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
836 nullptr, SymbolName);
844 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy,
nullptr);
845 MsgLookupFnSRet.init(&CGM,
"objc_msg_lookup_stret", IMPTy, IdTy,
846 SelectorTy,
nullptr);
848 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
849 PtrToObjCSuperTy, SelectorTy,
nullptr);
850 MsgLookupSuperFnSRet.init(&CGM,
"objc_msg_lookup_super_stret", IMPTy,
851 PtrToObjCSuperTy, SelectorTy,
nullptr);
860 void CGObjCGNU::EmitClassRef(
const std::string &className) {
861 std::string symbolRef =
"__objc_class_ref_" + className;
863 if (TheModule.getGlobalVariable(symbolRef))
865 std::string symbolName =
"__objc_class_name_" + className;
866 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
868 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
870 nullptr, symbolName);
872 new llvm::GlobalVariable(TheModule, ClassSymbol->getType(),
true,
873 llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef);
877 StringRef CategoryName,
const Selector MethodName,
878 bool isClassMethod) {
879 std::string MethodNameColonStripped = MethodName.
getAsString();
880 std::replace(MethodNameColonStripped.begin(), MethodNameColonStripped.end(),
882 return (Twine(isClassMethod ?
"_c_" :
"_i_") + ClassName +
"_" +
883 CategoryName +
"_" + MethodNameColonStripped).str();
886 CGObjCGNU::CGObjCGNU(
CodeGenModule &cgm,
unsigned runtimeABIVersion,
887 unsigned protocolClassVersion)
889 VMContext(cgm.getLLVMContext()), ClassPtrAlias(nullptr),
890 MetaClassPtrAlias(nullptr), RuntimeVersion(runtimeABIVersion),
891 ProtocolVersion(protocolClassVersion) {
893 msgSendMDKind = VMContext.getMDKindID(
"GNUObjCMessageSend");
896 IntTy = cast<llvm::IntegerType>(
898 LongTy = cast<llvm::IntegerType>(
900 SizeTy = cast<llvm::IntegerType>(
901 Types.
ConvertType(CGM.getContext().getSizeType()));
902 PtrDiffTy = cast<llvm::IntegerType>(
903 Types.
ConvertType(CGM.getContext().getPointerDiffType()));
904 BoolTy = CGM.getTypes().ConvertType(CGM.getContext().BoolTy);
906 Int8Ty = llvm::Type::getInt8Ty(VMContext);
908 PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
910 Zeros[0] = llvm::ConstantInt::get(LongTy, 0);
912 NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty);
914 QualType selTy = CGM.getContext().getObjCSelType();
916 SelectorTy = PtrToInt8Ty;
918 SelectorTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(selTy));
921 PtrToIntTy = llvm::PointerType::getUnqual(IntTy);
924 Int32Ty = llvm::Type::getInt32Ty(VMContext);
925 Int64Ty = llvm::Type::getInt64Ty(VMContext);
928 CGM.getDataLayout().getPointerSizeInBits() == 32 ? Int32Ty : Int64Ty;
931 QualType UnqualIdTy = CGM.getContext().getObjCIdType();
934 ASTIdTy = CGM.getContext().getCanonicalType(UnqualIdTy);
935 IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy));
939 PtrToIdTy = llvm::PointerType::getUnqual(IdTy);
941 ObjCSuperTy = llvm::StructType::get(IdTy, IdTy,
nullptr);
942 PtrToObjCSuperTy = llvm::PointerType::getUnqual(ObjCSuperTy);
944 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
947 ExceptionThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy,
nullptr);
948 ExceptionReThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy,
nullptr);
950 SyncEnterFn.init(&CGM,
"objc_sync_enter", IntTy, IdTy,
nullptr);
952 SyncExitFn.init(&CGM,
"objc_sync_exit", IntTy, IdTy,
nullptr);
955 EnumerationMutationFn.init(&CGM,
"objc_enumerationMutation", VoidTy,
959 GetPropertyFn.init(&CGM,
"objc_getProperty", IdTy, IdTy, SelectorTy,
960 PtrDiffTy, BoolTy,
nullptr);
962 SetPropertyFn.init(&CGM,
"objc_setProperty", VoidTy, IdTy, SelectorTy,
963 PtrDiffTy, IdTy, BoolTy, BoolTy,
nullptr);
965 GetStructPropertyFn.init(&CGM,
"objc_getPropertyStruct", VoidTy, PtrTy, PtrTy,
966 PtrDiffTy, BoolTy, BoolTy,
nullptr);
968 SetStructPropertyFn.init(&CGM,
"objc_setPropertyStruct", VoidTy, PtrTy, PtrTy,
969 PtrDiffTy, BoolTy, BoolTy,
nullptr);
972 llvm::Type *IMPArgs[] = { IdTy, SelectorTy };
973 IMPTy = llvm::PointerType::getUnqual(llvm::FunctionType::get(IdTy, IMPArgs,
977 if ((Opts.getGC() != LangOptions::NonGC) || Opts.ObjCAutoRefCount)
981 if (Opts.getGC() != LangOptions::NonGC) {
993 IvarAssignFn.init(&CGM,
"objc_assign_ivar", IdTy, IdTy, IdTy, PtrDiffTy,
996 StrongCastAssignFn.init(&CGM,
"objc_assign_strongCast", IdTy, IdTy,
999 GlobalAssignFn.init(&CGM,
"objc_assign_global", IdTy, IdTy, PtrToIdTy,
1002 WeakAssignFn.init(&CGM,
"objc_assign_weak", IdTy, IdTy, PtrToIdTy,
nullptr);
1004 WeakReadFn.init(&CGM,
"objc_read_weak", IdTy, PtrToIdTy,
nullptr);
1006 MemMoveFn.init(&CGM,
"objc_memmove_collectable", PtrTy, PtrTy, PtrTy,
1012 const std::string &Name,
1014 llvm::GlobalVariable *ClassNameGV = CGM.GetAddrOfConstantCString(Name);
1025 CGF.
Builder.CreateStructGEP(ClassNameGV->getValueType(), ClassNameGV, 0);
1027 llvm::Constant *ClassLookupFn =
1028 CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, PtrToInt8Ty,
true),
1029 "objc_lookup_class");
1040 return GetClassNamed(CGF,
"NSAutoreleasePool",
false);
1044 const std::string &TypeEncoding,
bool lval) {
1047 llvm::GlobalAlias *SelValue =
nullptr;
1050 e = Types.end() ; i!=e ; i++) {
1051 if (i->first == TypeEncoding) {
1052 SelValue = i->second;
1058 SelectorTy, llvm::GlobalValue::PrivateLinkage,
1059 ".objc_selector_" + Sel.
getAsString(), &TheModule);
1060 Types.emplace_back(TypeEncoding, SelValue);
1065 CGF.
Builder.CreateStore(SelValue, tmp);
1073 return GetSelector(CGF, Sel, std::string(), lval);
1078 std::string SelTypes;
1079 CGM.getContext().getObjCEncodingForMethodDecl(Method, SelTypes);
1080 return GetSelector(CGF, Method->
getSelector(), SelTypes,
false);
1083 llvm::Constant *CGObjCGNU::GetEHType(
QualType T) {
1089 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
1090 return MakeConstantString(
"@id");
1098 assert(OPT &&
"Invalid @catch type.");
1100 assert(IDecl &&
"Invalid @catch type.");
1104 llvm::Constant *CGObjCGNUstep::GetEHType(
QualType T) {
1105 if (!CGM.getLangOpts().CPlusPlus)
1106 return CGObjCGNU::GetEHType(T);
1114 llvm::Constant *IDEHType =
1115 CGM.getModule().getGlobalVariable(
"__objc_id_type_info");
1118 new llvm::GlobalVariable(CGM.getModule(), PtrToInt8Ty,
1121 nullptr,
"__objc_id_type_info");
1122 return llvm::ConstantExpr::getBitCast(IDEHType, PtrToInt8Ty);
1127 assert(PT &&
"Invalid @catch type.");
1129 assert(IT &&
"Invalid @catch type.");
1132 std::string typeinfoName =
"__objc_eh_typeinfo_" + className;
1135 llvm::Constant *typeinfo = TheModule.getGlobalVariable(typeinfoName);
1137 return llvm::ConstantExpr::getBitCast(typeinfo, PtrToInt8Ty);
1144 const char *vtableName =
"_ZTVN7gnustep7libobjc22__objc_class_type_infoE";
1145 auto *Vtable = TheModule.getGlobalVariable(vtableName);
1147 Vtable =
new llvm::GlobalVariable(TheModule, PtrToInt8Ty,
true,
1149 nullptr, vtableName);
1151 llvm::Constant *Two = llvm::ConstantInt::get(IntTy, 2);
1152 auto *BVtable = llvm::ConstantExpr::getBitCast(
1153 llvm::ConstantExpr::getGetElementPtr(Vtable->getValueType(), Vtable, Two),
1156 llvm::Constant *typeName =
1157 ExportUniqueString(className,
"__objc_eh_typename_");
1159 std::vector<llvm::Constant*> fields;
1160 fields.push_back(BVtable);
1161 fields.push_back(typeName);
1162 llvm::Constant *TI =
1163 MakeGlobal(llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty,
1164 nullptr), fields,
"__objc_eh_typeinfo_" + className,
1165 llvm::GlobalValue::LinkOnceODRLinkage);
1166 return llvm::ConstantExpr::getBitCast(TI, PtrToInt8Ty);
1170 llvm::Constant *CGObjCGNU::GenerateConstantString(
const StringLiteral *SL) {
1172 std::string Str = SL->
getString().str();
1175 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
1176 if (old != ObjCStrings.end())
1177 return old->getValue();
1179 StringRef StringClass = CGM.getLangOpts().ObjCConstantStringClass;
1181 if (StringClass.empty()) StringClass =
"NXConstantString";
1183 std::string Sym =
"_OBJC_CLASS_";
1186 llvm::Constant *isa = TheModule.getNamedGlobal(Sym);
1189 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
1190 llvm::GlobalValue::ExternalWeakLinkage,
nullptr, Sym);
1191 else if (isa->getType() != PtrToIdTy)
1192 isa = llvm::ConstantExpr::getBitCast(isa, PtrToIdTy);
1194 std::vector<llvm::Constant*> Ivars;
1195 Ivars.push_back(isa);
1196 Ivars.push_back(MakeConstantString(Str));
1197 Ivars.push_back(llvm::ConstantInt::get(IntTy, Str.size()));
1198 llvm::Constant *ObjCStr = MakeGlobal(
1199 llvm::StructType::get(PtrToIdTy, PtrToInt8Ty, IntTy,
nullptr),
1200 Ivars,
".objc_str");
1201 ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStr, PtrToInt8Ty);
1202 ObjCStrings[Str] = ObjCStr;
1203 ConstantStrings.push_back(ObjCStr);
1216 bool isCategoryImpl,
1218 bool IsClassMessage,
1222 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
1223 if (Sel == RetainSel || Sel == AutoreleaseSel) {
1224 return RValue::get(EnforceType(Builder, Receiver,
1225 CGM.getTypes().ConvertType(ResultType)));
1227 if (Sel == ReleaseSel) {
1228 return RValue::get(
nullptr);
1237 ActualArgs.
add(RValue::get(EnforceType(Builder, Receiver, IdTy)), ASTIdTy);
1241 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
1244 if (isCategoryImpl) {
1245 llvm::Constant *classLookupFunction =
nullptr;
1246 if (IsClassMessage) {
1247 classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
1248 IdTy, PtrTy,
true),
"objc_get_meta_class");
1250 classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
1251 IdTy, PtrTy,
true),
"objc_get_class");
1253 ReceiverClass = Builder.CreateCall(classLookupFunction,
1261 if (IsClassMessage) {
1262 if (!MetaClassPtrAlias) {
1267 ReceiverClass = MetaClassPtrAlias;
1269 if (!ClassPtrAlias) {
1274 ReceiverClass = ClassPtrAlias;
1278 llvm::Type *CastTy = llvm::StructType::get(IdTy, IdTy,
nullptr);
1279 ReceiverClass = Builder.CreateBitCast(ReceiverClass,
1280 llvm::PointerType::getUnqual(CastTy));
1282 ReceiverClass = Builder.CreateStructGEP(CastTy, ReceiverClass, 1);
1284 ReceiverClass = Builder.CreateLoad(ReceiverClass);
1286 llvm::StructType *ObjCSuperTy = llvm::StructType::get(
1287 Receiver->getType(), IdTy,
nullptr);
1288 llvm::Value *ObjCSuper = Builder.CreateAlloca(ObjCSuperTy);
1290 Builder.CreateStore(Receiver,
1291 Builder.CreateStructGEP(ObjCSuperTy, ObjCSuper, 0));
1292 Builder.CreateStore(ReceiverClass,
1293 Builder.CreateStructGEP(ObjCSuperTy, ObjCSuper, 1));
1295 ObjCSuper = EnforceType(Builder, ObjCSuper, PtrToObjCSuperTy);
1298 llvm::Value *imp = LookupIMPSuper(CGF, ObjCSuper, cmd, MSI);
1299 imp = EnforceType(Builder, imp, MSI.MessengerType);
1301 llvm::Metadata *impMD[] = {
1302 llvm::MDString::get(VMContext, Sel.
getAsString()),
1304 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
1305 llvm::Type::getInt1Ty(VMContext), IsClassMessage))};
1306 llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD);
1308 llvm::Instruction *call;
1309 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, imp, Return, ActualArgs,
nullptr,
1311 call->setMetadata(msgSendMDKind, node);
1328 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
1329 if (Sel == RetainSel || Sel == AutoreleaseSel) {
1330 return RValue::get(EnforceType(Builder, Receiver,
1331 CGM.getTypes().ConvertType(ResultType)));
1333 if (Sel == ReleaseSel) {
1334 return RValue::get(
nullptr);
1352 llvm::BasicBlock *startBB =
nullptr;
1353 llvm::BasicBlock *messageBB =
nullptr;
1354 llvm::BasicBlock *continueBB =
nullptr;
1356 if (!isPointerSizedReturn) {
1357 startBB = Builder.GetInsertBlock();
1361 llvm::Value *isNil = Builder.CreateICmpEQ(Receiver,
1362 llvm::Constant::getNullValue(Receiver->getType()));
1363 Builder.CreateCondBr(isNil, continueBB, messageBB);
1367 IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy));
1370 cmd = GetSelector(CGF, Method);
1372 cmd = GetSelector(CGF, Sel);
1373 cmd = EnforceType(Builder, cmd, SelectorTy);
1374 Receiver = EnforceType(Builder, Receiver, IdTy);
1376 llvm::Metadata *impMD[] = {
1377 llvm::MDString::get(VMContext, Sel.
getAsString()),
1378 llvm::MDString::get(VMContext, Class ? Class->
getNameAsString() :
""),
1379 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
1380 llvm::Type::getInt1Ty(VMContext), Class !=
nullptr))};
1381 llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD);
1384 ActualArgs.
add(RValue::get(Receiver), ASTIdTy);
1388 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
1396 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
1397 case CodeGenOptions::Legacy:
1398 imp = LookupIMP(CGF, Receiver, cmd, node, MSI);
1400 case CodeGenOptions::Mixed:
1401 case CodeGenOptions::NonLegacy:
1402 if (CGM.ReturnTypeUsesFPRet(ResultType)) {
1403 imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy,
true),
1404 "objc_msgSend_fpret");
1405 }
else if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) {
1408 imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy,
true),
1409 "objc_msgSend_stret");
1411 imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy,
true),
1417 ActualArgs[0] =
CallArg(RValue::get(Receiver), ASTIdTy,
false);
1419 imp = EnforceType(Builder, imp, MSI.MessengerType);
1421 llvm::Instruction *call;
1422 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, imp, Return, ActualArgs,
nullptr,
1424 call->setMetadata(msgSendMDKind, node);
1427 if (!isPointerSizedReturn) {
1428 messageBB = CGF.
Builder.GetInsertBlock();
1429 CGF.
Builder.CreateBr(continueBB);
1433 llvm::PHINode *phi = Builder.CreatePHI(v->getType(), 2);
1434 phi->addIncoming(v, messageBB);
1435 phi->addIncoming(llvm::Constant::getNullValue(v->getType()), startBB);
1436 msgRet = RValue::get(phi);
1439 llvm::PHINode *phi = Builder.CreatePHI(v->getType(), 2);
1440 llvm::PointerType *RetTy = cast<llvm::PointerType>(v->getType());
1441 llvm::AllocaInst *NullVal =
1444 llvm::Constant::getNullValue(RetTy->getElementType()));
1445 phi->addIncoming(v, messageBB);
1446 phi->addIncoming(NullVal, startBB);
1447 msgRet = RValue::getAggregate(phi);
1449 std::pair<llvm::Value*,llvm::Value*> v = msgRet.
getComplexVal();
1450 llvm::PHINode *phi = Builder.CreatePHI(v.first->getType(), 2);
1451 phi->addIncoming(v.first, messageBB);
1452 phi->addIncoming(llvm::Constant::getNullValue(v.first->getType()),
1454 llvm::PHINode *phi2 = Builder.CreatePHI(v.second->getType(), 2);
1455 phi2->addIncoming(v.second, messageBB);
1456 phi2->addIncoming(llvm::Constant::getNullValue(v.second->getType()),
1458 msgRet = RValue::getComplex(phi, phi2);
1466 llvm::Constant *CGObjCGNU::
1467 GenerateMethodList(StringRef ClassName,
1468 StringRef CategoryName,
1471 bool isClassMethodList) {
1472 if (MethodSels.empty())
1475 llvm::StructType *ObjCMethodTy = llvm::StructType::get(
1480 std::vector<llvm::Constant*> Methods;
1481 std::vector<llvm::Constant*> Elements;
1482 for (
unsigned int i = 0, e = MethodTypes.size(); i < e; ++i) {
1484 llvm::Constant *Method =
1487 isClassMethodList));
1488 assert(Method &&
"Can't generate metadata for method that doesn't exist");
1489 llvm::Constant *
C = MakeConstantString(MethodSels[i].getAsString());
1490 Elements.push_back(C);
1491 Elements.push_back(MethodTypes[i]);
1492 Method = llvm::ConstantExpr::getBitCast(Method,
1494 Elements.push_back(Method);
1495 Methods.push_back(llvm::ConstantStruct::get(ObjCMethodTy, Elements));
1499 llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodTy,
1501 llvm::Constant *MethodArray = llvm::ConstantArray::get(ObjCMethodArrayTy,
1506 llvm::Type *NextPtrTy = llvm::PointerType::getUnqual(ObjCMethodListTy);
1507 ObjCMethodListTy->setBody(
1514 Methods.push_back(llvm::ConstantPointerNull::get(
1515 llvm::PointerType::getUnqual(ObjCMethodListTy)));
1516 Methods.push_back(llvm::ConstantInt::get(Int32Ty, MethodTypes.size()));
1517 Methods.push_back(MethodArray);
1520 return MakeGlobal(ObjCMethodListTy, Methods,
".objc_method_list");
1524 llvm::Constant *CGObjCGNU::
1528 if (IvarNames.size() == 0)
1531 llvm::StructType *ObjCIvarTy = llvm::StructType::get(
1536 std::vector<llvm::Constant*> Ivars;
1537 std::vector<llvm::Constant*> Elements;
1538 for (
unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {
1540 Elements.push_back(IvarNames[i]);
1541 Elements.push_back(IvarTypes[i]);
1542 Elements.push_back(IvarOffsets[i]);
1543 Ivars.push_back(llvm::ConstantStruct::get(ObjCIvarTy, Elements));
1547 llvm::ArrayType *ObjCIvarArrayTy = llvm::ArrayType::get(ObjCIvarTy,
1552 Elements.push_back(llvm::ConstantInt::get(IntTy, (
int)IvarNames.size()));
1553 Elements.push_back(llvm::ConstantArray::get(ObjCIvarArrayTy, Ivars));
1555 llvm::StructType *ObjCIvarListTy = llvm::StructType::get(IntTy,
1560 return MakeGlobal(ObjCIvarListTy, Elements,
".objc_ivar_list");
1564 llvm::Constant *CGObjCGNU::GenerateClassStructure(
1565 llvm::Constant *MetaClass,
1566 llvm::Constant *SuperClass,
1569 llvm::Constant *Version,
1570 llvm::Constant *InstanceSize,
1571 llvm::Constant *IVars,
1572 llvm::Constant *Methods,
1573 llvm::Constant *Protocols,
1574 llvm::Constant *IvarOffsets,
1575 llvm::Constant *Properties,
1576 llvm::Constant *StrongIvarBitmap,
1577 llvm::Constant *WeakIvarBitmap,
1586 llvm::StructType *ClassTy = llvm::StructType::get(
1603 IvarOffsets->getType(),
1604 Properties->getType(),
1608 llvm::Constant *Zero = llvm::ConstantInt::get(LongTy, 0);
1610 std::vector<llvm::Constant*> Elements;
1611 Elements.push_back(llvm::ConstantExpr::getBitCast(MetaClass, PtrToInt8Ty));
1612 Elements.push_back(SuperClass);
1613 Elements.push_back(MakeConstantString(Name,
".class_name"));
1614 Elements.push_back(Zero);
1615 Elements.push_back(llvm::ConstantInt::get(LongTy, info));
1617 llvm::DataLayout td(&TheModule);
1619 llvm::ConstantInt::get(LongTy,
1620 td.getTypeSizeInBits(ClassTy) /
1621 CGM.getContext().getCharWidth()));
1623 Elements.push_back(InstanceSize);
1624 Elements.push_back(IVars);
1625 Elements.push_back(Methods);
1626 Elements.push_back(NULLPtr);
1627 Elements.push_back(NULLPtr);
1628 Elements.push_back(NULLPtr);
1629 Elements.push_back(llvm::ConstantExpr::getBitCast(Protocols, PtrTy));
1630 Elements.push_back(NULLPtr);
1631 Elements.push_back(llvm::ConstantInt::get(LongTy, 1));
1632 Elements.push_back(IvarOffsets);
1633 Elements.push_back(Properties);
1634 Elements.push_back(StrongIvarBitmap);
1635 Elements.push_back(WeakIvarBitmap);
1640 std::string ClassSym((isMeta ?
"_OBJC_METACLASS_":
"_OBJC_CLASS_") +
1642 llvm::GlobalVariable *ClassRef = TheModule.getNamedGlobal(ClassSym);
1643 llvm::Constant *Class = MakeGlobal(ClassTy, Elements, ClassSym,
1646 ClassRef->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(Class,
1647 ClassRef->getType()));
1648 ClassRef->removeFromParent();
1649 Class->setName(ClassSym);
1654 llvm::Constant *CGObjCGNU::
1658 llvm::StructType *ObjCMethodDescTy = llvm::StructType::get(
1662 std::vector<llvm::Constant*> Methods;
1663 std::vector<llvm::Constant*> Elements;
1664 for (
unsigned int i = 0, e = MethodTypes.size() ; i < e ; i++) {
1666 Elements.push_back(MethodNames[i]);
1667 Elements.push_back(MethodTypes[i]);
1668 Methods.push_back(llvm::ConstantStruct::get(ObjCMethodDescTy, Elements));
1670 llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodDescTy,
1671 MethodNames.size());
1672 llvm::Constant *Array = llvm::ConstantArray::get(ObjCMethodArrayTy,
1674 llvm::StructType *ObjCMethodDescListTy = llvm::StructType::get(
1675 IntTy, ObjCMethodArrayTy,
nullptr);
1677 Methods.push_back(llvm::ConstantInt::get(IntTy, MethodNames.size()));
1678 Methods.push_back(Array);
1679 return MakeGlobal(ObjCMethodDescListTy, Methods,
".objc_method_list");
1684 llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrToInt8Ty,
1686 llvm::StructType *ProtocolListTy = llvm::StructType::get(
1691 std::vector<llvm::Constant*> Elements;
1692 for (
const std::string *iter = Protocols.begin(), *endIter = Protocols.end();
1693 iter != endIter ; iter++) {
1694 llvm::Constant *protocol =
nullptr;
1695 llvm::StringMap<llvm::Constant*>::iterator value =
1696 ExistingProtocols.find(*iter);
1697 if (value == ExistingProtocols.end()) {
1698 protocol = GenerateEmptyProtocol(*iter);
1700 protocol = value->getValue();
1702 llvm::Constant *Ptr = llvm::ConstantExpr::getBitCast(protocol,
1704 Elements.push_back(Ptr);
1706 llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
1709 Elements.push_back(NULLPtr);
1710 Elements.push_back(llvm::ConstantInt::get(LongTy, Protocols.size()));
1711 Elements.push_back(ProtocolArray);
1712 return MakeGlobal(ProtocolListTy, Elements,
".objc_protocol_list");
1719 CGM.getTypes().ConvertType(CGM.getContext().getObjCProtoType());
1720 return CGF.
Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(T));
1723 llvm::Constant *CGObjCGNU::GenerateEmptyProtocol(
1724 const std::string &ProtocolName) {
1728 llvm::Constant *ProtocolList = GenerateProtocolList(EmptyStringVector);
1729 llvm::Constant *MethodList =
1730 GenerateProtocolMethodList(EmptyConstantVector, EmptyConstantVector);
1733 llvm::StructType *ProtocolTy = llvm::StructType::get(IdTy,
1735 ProtocolList->getType(),
1736 MethodList->getType(),
1737 MethodList->getType(),
1738 MethodList->getType(),
1739 MethodList->getType(),
1741 std::vector<llvm::Constant*> Elements;
1744 Elements.push_back(llvm::ConstantExpr::getIntToPtr(
1745 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
1746 Elements.push_back(MakeConstantString(ProtocolName,
".objc_protocol_name"));
1747 Elements.push_back(ProtocolList);
1748 Elements.push_back(MethodList);
1749 Elements.push_back(MethodList);
1750 Elements.push_back(MethodList);
1751 Elements.push_back(MethodList);
1752 return MakeGlobal(ProtocolTy, Elements,
".objc_protocol");
1765 Protocols.push_back(PI->getNameAsString());
1771 std::string TypeStr;
1773 if (I->getImplementationControl() == ObjCMethodDecl::Optional) {
1774 OptionalInstanceMethodNames.push_back(
1775 MakeConstantString(I->getSelector().getAsString()));
1776 OptionalInstanceMethodTypes.push_back(MakeConstantString(TypeStr));
1778 InstanceMethodNames.push_back(
1779 MakeConstantString(I->getSelector().getAsString()));
1780 InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
1789 std::string TypeStr;
1791 if (I->getImplementationControl() == ObjCMethodDecl::Optional) {
1792 OptionalClassMethodNames.push_back(
1793 MakeConstantString(I->getSelector().getAsString()));
1794 OptionalClassMethodTypes.push_back(MakeConstantString(TypeStr));
1796 ClassMethodNames.push_back(
1797 MakeConstantString(I->getSelector().getAsString()));
1798 ClassMethodTypes.push_back(MakeConstantString(TypeStr));
1802 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
1803 llvm::Constant *InstanceMethodList =
1804 GenerateProtocolMethodList(InstanceMethodNames, InstanceMethodTypes);
1805 llvm::Constant *ClassMethodList =
1806 GenerateProtocolMethodList(ClassMethodNames, ClassMethodTypes);
1807 llvm::Constant *OptionalInstanceMethodList =
1808 GenerateProtocolMethodList(OptionalInstanceMethodNames,
1809 OptionalInstanceMethodTypes);
1810 llvm::Constant *OptionalClassMethodList =
1811 GenerateProtocolMethodList(OptionalClassMethodNames,
1812 OptionalClassMethodTypes);
1819 llvm::StructType *PropertyMetadataTy = llvm::StructType::get(
1820 PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty,
1821 PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty,
nullptr);
1822 std::vector<llvm::Constant*> Properties;
1823 std::vector<llvm::Constant*> OptionalProperties;
1828 std::vector<llvm::Constant*> Fields;
1830 Fields.push_back(MakePropertyEncodingString(property,
nullptr));
1831 PushPropertyAttributes(Fields, property);
1834 std::string TypeStr;
1836 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
1837 InstanceMethodTypes.push_back(TypeEncoding);
1838 Fields.push_back(MakeConstantString(getter->getSelector().getAsString()));
1839 Fields.push_back(TypeEncoding);
1841 Fields.push_back(NULLPtr);
1842 Fields.push_back(NULLPtr);
1845 std::string TypeStr;
1847 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
1848 InstanceMethodTypes.push_back(TypeEncoding);
1849 Fields.push_back(MakeConstantString(setter->getSelector().getAsString()));
1850 Fields.push_back(TypeEncoding);
1852 Fields.push_back(NULLPtr);
1853 Fields.push_back(NULLPtr);
1856 OptionalProperties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
1858 Properties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
1861 llvm::Constant *PropertyArray = llvm::ConstantArray::get(
1862 llvm::ArrayType::get(PropertyMetadataTy, Properties.size()), Properties);
1863 llvm::Constant* PropertyListInitFields[] =
1864 {llvm::ConstantInt::get(IntTy, Properties.size()), NULLPtr, PropertyArray};
1866 llvm::Constant *PropertyListInit =
1867 llvm::ConstantStruct::getAnon(PropertyListInitFields);
1868 llvm::Constant *PropertyList =
new llvm::GlobalVariable(TheModule,
1870 PropertyListInit,
".objc_property_list");
1872 llvm::Constant *OptionalPropertyArray =
1873 llvm::ConstantArray::get(llvm::ArrayType::get(PropertyMetadataTy,
1874 OptionalProperties.size()) , OptionalProperties);
1875 llvm::Constant* OptionalPropertyListInitFields[] = {
1876 llvm::ConstantInt::get(IntTy, OptionalProperties.size()), NULLPtr,
1877 OptionalPropertyArray };
1879 llvm::Constant *OptionalPropertyListInit =
1880 llvm::ConstantStruct::getAnon(OptionalPropertyListInitFields);
1881 llvm::Constant *OptionalPropertyList =
new llvm::GlobalVariable(TheModule,
1882 OptionalPropertyListInit->getType(),
false,
1884 ".objc_property_list");
1888 llvm::StructType *ProtocolTy = llvm::StructType::get(IdTy,
1890 ProtocolList->getType(),
1891 InstanceMethodList->getType(),
1892 ClassMethodList->getType(),
1893 OptionalInstanceMethodList->getType(),
1894 OptionalClassMethodList->getType(),
1895 PropertyList->getType(),
1896 OptionalPropertyList->getType(),
1898 std::vector<llvm::Constant*> Elements;
1901 Elements.push_back(llvm::ConstantExpr::getIntToPtr(
1902 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
1903 Elements.push_back(MakeConstantString(ProtocolName,
".objc_protocol_name"));
1904 Elements.push_back(ProtocolList);
1905 Elements.push_back(InstanceMethodList);
1906 Elements.push_back(ClassMethodList);
1907 Elements.push_back(OptionalInstanceMethodList);
1908 Elements.push_back(OptionalClassMethodList);
1909 Elements.push_back(PropertyList);
1910 Elements.push_back(OptionalPropertyList);
1911 ExistingProtocols[ProtocolName] =
1912 llvm::ConstantExpr::getBitCast(MakeGlobal(ProtocolTy, Elements,
1913 ".objc_protocol"), IdTy);
1915 void CGObjCGNU::GenerateProtocolHolderCategory() {
1920 std::vector<llvm::Constant*> Elements;
1921 const std::string ClassName =
"__ObjC_Protocol_Holder_Ugly_Hack";
1922 const std::string CategoryName =
"AnotherHack";
1923 Elements.push_back(MakeConstantString(CategoryName));
1924 Elements.push_back(MakeConstantString(ClassName));
1926 Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
1927 ClassName, CategoryName, MethodSels, MethodTypes,
false), PtrTy));
1929 Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
1930 ClassName, CategoryName, MethodSels, MethodTypes,
true), PtrTy));
1932 llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrTy,
1933 ExistingProtocols.size());
1934 llvm::StructType *ProtocolListTy = llvm::StructType::get(
1939 std::vector<llvm::Constant*> ProtocolElements;
1940 for (llvm::StringMapIterator<llvm::Constant*> iter =
1941 ExistingProtocols.begin(), endIter = ExistingProtocols.end();
1942 iter != endIter ; iter++) {
1943 llvm::Constant *Ptr = llvm::ConstantExpr::getBitCast(iter->getValue(),
1945 ProtocolElements.push_back(Ptr);
1947 llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
1949 ProtocolElements.clear();
1950 ProtocolElements.push_back(NULLPtr);
1951 ProtocolElements.push_back(llvm::ConstantInt::get(LongTy,
1952 ExistingProtocols.size()));
1953 ProtocolElements.push_back(ProtocolArray);
1954 Elements.push_back(llvm::ConstantExpr::getBitCast(MakeGlobal(ProtocolListTy,
1955 ProtocolElements,
".objc_protocol_list"), PtrTy));
1956 Categories.push_back(llvm::ConstantExpr::getBitCast(
1957 MakeGlobal(llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty,
1958 PtrTy, PtrTy, PtrTy,
nullptr), Elements), PtrTy));
1973 int bitCount = bits.size();
1974 int ptrBits = CGM.getDataLayout().getPointerSizeInBits();
1975 if (bitCount < ptrBits) {
1977 for (
int i=0 ; i<bitCount ; ++i) {
1978 if (bits[i]) val |= 1ULL<<(i+1);
1980 return llvm::ConstantInt::get(IntPtrTy, val);
1984 while (v < bitCount) {
1986 for (
int i=0 ; (i<32) && (v<bitCount) ; ++i) {
1987 if (bits[v]) word |= 1<<i;
1990 values.push_back(llvm::ConstantInt::get(Int32Ty, word));
1992 llvm::ArrayType *arrayTy = llvm::ArrayType::get(Int32Ty, values.size());
1993 llvm::Constant *array = llvm::ConstantArray::get(arrayTy, values);
1994 llvm::Constant *fields[2] = {
1995 llvm::ConstantInt::get(Int32Ty, values.size()),
1997 llvm::Constant *GS = MakeGlobal(llvm::StructType::get(Int32Ty, arrayTy,
1999 llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy);
2010 InstanceMethodSels.push_back(I->getSelector());
2011 std::string TypeStr;
2012 CGM.getContext().getObjCEncodingForMethodDecl(I,TypeStr);
2013 InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
2020 ClassMethodSels.push_back(I->getSelector());
2021 std::string TypeStr;
2022 CGM.getContext().getObjCEncodingForMethodDecl(I,TypeStr);
2023 ClassMethodTypes.push_back(MakeConstantString(TypeStr));
2031 E = Protos.
end(); I != E; ++I)
2032 Protocols.push_back((*I)->getNameAsString());
2034 std::vector<llvm::Constant*> Elements;
2035 Elements.push_back(MakeConstantString(CategoryName));
2036 Elements.push_back(MakeConstantString(ClassName));
2038 Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
2039 ClassName, CategoryName, InstanceMethodSels, InstanceMethodTypes,
2042 Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
2043 ClassName, CategoryName, ClassMethodSels, ClassMethodTypes,
true),
2046 Elements.push_back(llvm::ConstantExpr::getBitCast(
2047 GenerateProtocolList(Protocols), PtrTy));
2048 Categories.push_back(llvm::ConstantExpr::getBitCast(
2049 MakeGlobal(llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty,
2050 PtrTy, PtrTy, PtrTy,
nullptr), Elements), PtrTy));
2059 llvm::StructType *PropertyMetadataTy = llvm::StructType::get(
2060 PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty,
2061 PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty,
nullptr);
2062 std::vector<llvm::Constant*> Properties;
2067 std::vector<llvm::Constant*> Fields;
2069 bool isSynthesized = (propertyImpl->getPropertyImplementation() ==
2070 ObjCPropertyImplDecl::Synthesize);
2071 bool isDynamic = (propertyImpl->getPropertyImplementation() ==
2072 ObjCPropertyImplDecl::Dynamic);
2074 Fields.push_back(MakePropertyEncodingString(property, OID));
2075 PushPropertyAttributes(Fields, property, isSynthesized, isDynamic);
2077 std::string TypeStr;
2079 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
2080 if (isSynthesized) {
2081 InstanceMethodTypes.push_back(TypeEncoding);
2082 InstanceMethodSels.push_back(getter->getSelector());
2084 Fields.push_back(MakeConstantString(getter->getSelector().getAsString()));
2085 Fields.push_back(TypeEncoding);
2087 Fields.push_back(NULLPtr);
2088 Fields.push_back(NULLPtr);
2091 std::string TypeStr;
2093 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
2094 if (isSynthesized) {
2095 InstanceMethodTypes.push_back(TypeEncoding);
2096 InstanceMethodSels.push_back(setter->getSelector());
2098 Fields.push_back(MakeConstantString(setter->getSelector().getAsString()));
2099 Fields.push_back(TypeEncoding);
2101 Fields.push_back(NULLPtr);
2102 Fields.push_back(NULLPtr);
2104 Properties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
2106 llvm::ArrayType *PropertyArrayTy =
2107 llvm::ArrayType::get(PropertyMetadataTy, Properties.size());
2108 llvm::Constant *PropertyArray = llvm::ConstantArray::get(PropertyArrayTy,
2110 llvm::Constant* PropertyListInitFields[] =
2111 {llvm::ConstantInt::get(IntTy, Properties.size()), NULLPtr, PropertyArray};
2113 llvm::Constant *PropertyListInit =
2114 llvm::ConstantStruct::getAnon(PropertyListInitFields);
2115 return new llvm::GlobalVariable(TheModule, PropertyListInit->getType(),
false,
2117 ".objc_property_list");
2134 std::string SuperClassName;
2135 if (SuperClassDecl) {
2137 EmitClassRef(SuperClassName);
2146 std::string classSymbolName =
"__objc_class_name_" + ClassName;
2147 if (llvm::GlobalVariable *symbol =
2148 TheModule.getGlobalVariable(classSymbolName)) {
2149 symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0));
2151 new llvm::GlobalVariable(TheModule, LongTy,
false,
2165 std::vector<llvm::Constant*> IvarOffsetValues;
2169 int superInstanceSize = !SuperClassDecl ? 0 :
2173 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
2174 instanceSize = 0 - (instanceSize - superInstanceSize);
2180 IvarNames.push_back(MakeConstantString(IVD->getNameAsString()));
2182 std::string TypeStr;
2184 IvarTypes.push_back(MakeConstantString(TypeStr));
2186 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
2187 uint64_t
Offset = BaseOffset;
2188 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
2189 Offset = BaseOffset - superInstanceSize;
2191 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
2193 std::string OffsetName =
"__objc_ivar_offset_value_" + ClassName +
"." +
2194 IVD->getNameAsString();
2195 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
2197 OffsetVar->setInitializer(OffsetValue);
2203 OffsetVar =
new llvm::GlobalVariable(TheModule, IntTy,
2206 "__objc_ivar_offset_value_" + ClassName +
"." +
2207 IVD->getNameAsString());
2208 IvarOffsets.push_back(OffsetValue);
2209 IvarOffsetValues.push_back(OffsetVar);
2212 case Qualifiers::OCL_Strong:
2213 StrongIvars.push_back(
true);
2214 WeakIvars.push_back(
false);
2216 case Qualifiers::OCL_Weak:
2217 StrongIvars.push_back(
false);
2218 WeakIvars.push_back(
true);
2221 StrongIvars.push_back(
false);
2222 WeakIvars.push_back(
false);
2225 llvm::Constant *StrongIvarBitmap = MakeBitField(StrongIvars);
2226 llvm::Constant *WeakIvarBitmap = MakeBitField(WeakIvars);
2227 llvm::GlobalVariable *IvarOffsetArray =
2228 MakeGlobalArray(PtrToIntTy, IvarOffsetValues,
".ivar.offsets");
2235 InstanceMethodSels.push_back(I->getSelector());
2236 std::string TypeStr;
2238 InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
2241 llvm::Constant *Properties = GeneratePropertyList(OID, InstanceMethodSels,
2242 InstanceMethodTypes);
2249 ClassMethodSels.push_back(I->getSelector());
2250 std::string TypeStr;
2252 ClassMethodTypes.push_back(MakeConstantString(TypeStr));
2256 for (
const auto *I : ClassDecl->
protocols())
2257 Protocols.push_back(I->getNameAsString());
2260 llvm::Constant *SuperClass;
2261 if (!SuperClassName.empty()) {
2262 SuperClass = MakeConstantString(SuperClassName,
".super_class_name");
2264 SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty);
2269 llvm::Constant *MethodList = GenerateMethodList(ClassName,
"",
2270 InstanceMethodSels, InstanceMethodTypes,
false);
2271 llvm::Constant *ClassMethodList = GenerateMethodList(ClassName,
"",
2272 ClassMethodSels, ClassMethodTypes,
true);
2273 llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
2285 llvm::Type *IndexTy = Int32Ty;
2286 llvm::Constant *offsetPointerIndexes[] = {Zeros[0],
2287 llvm::ConstantInt::get(IndexTy, 1),
nullptr,
2288 llvm::ConstantInt::get(IndexTy, 2) };
2290 unsigned ivarIndex = 0;
2293 const std::string Name =
"__objc_ivar_offset_" + ClassName +
'.'
2294 + IVD->getNameAsString();
2295 offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, ivarIndex);
2297 llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr(
2298 cast<llvm::GlobalVariable>(IvarList)->getValueType(), IvarList,
2299 offsetPointerIndexes);
2301 llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name);
2303 offset->setInitializer(offsetValue);
2310 offset =
new llvm::GlobalVariable(TheModule, offsetValue->getType(),
2316 llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0);
2318 llvm::Constant *MetaClassStruct = GenerateClassStructure(NULLPtr,
2319 NULLPtr, 0x12L, ClassName.c_str(),
nullptr, Zeros[0], GenerateIvarList(
2320 empty, empty, empty), ClassMethodList, NULLPtr,
2321 NULLPtr, NULLPtr, ZeroPtr, ZeroPtr,
true);
2324 llvm::Constant *ClassStruct =
2325 GenerateClassStructure(MetaClassStruct, SuperClass, 0x11L,
2326 ClassName.c_str(),
nullptr,
2327 llvm::ConstantInt::get(LongTy, instanceSize), IvarList,
2328 MethodList, GenerateProtocolList(Protocols), IvarOffsetArray,
2329 Properties, StrongIvarBitmap, WeakIvarBitmap);
2332 if (ClassPtrAlias) {
2333 ClassPtrAlias->replaceAllUsesWith(
2334 llvm::ConstantExpr::getBitCast(ClassStruct, IdTy));
2335 ClassPtrAlias->eraseFromParent();
2336 ClassPtrAlias =
nullptr;
2338 if (MetaClassPtrAlias) {
2339 MetaClassPtrAlias->replaceAllUsesWith(
2340 llvm::ConstantExpr::getBitCast(MetaClassStruct, IdTy));
2341 MetaClassPtrAlias->eraseFromParent();
2342 MetaClassPtrAlias =
nullptr;
2346 ClassStruct = llvm::ConstantExpr::getBitCast(ClassStruct, PtrToInt8Ty);
2347 Classes.push_back(ClassStruct);
2351 llvm::Function *CGObjCGNU::ModuleInitFunction() {
2353 if (Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
2358 GenerateProtocolHolderCategory();
2360 llvm::StructType *SelStructTy = dyn_cast<llvm::StructType>(
2361 SelectorTy->getElementType());
2362 llvm::Type *SelStructPtrTy = SelectorTy;
2364 SelStructTy = llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty,
nullptr);
2365 SelStructPtrTy = llvm::PointerType::getUnqual(SelStructTy);
2368 std::vector<llvm::Constant*> Elements;
2369 llvm::Constant *Statics = NULLPtr;
2371 if (!ConstantStrings.empty()) {
2372 llvm::ArrayType *StaticsArrayTy = llvm::ArrayType::get(PtrToInt8Ty,
2373 ConstantStrings.size() + 1);
2374 ConstantStrings.push_back(NULLPtr);
2376 StringRef StringClass = CGM.getLangOpts().ObjCConstantStringClass;
2378 if (StringClass.empty()) StringClass =
"NXConstantString";
2380 Elements.push_back(MakeConstantString(StringClass,
2381 ".objc_static_class_name"));
2382 Elements.push_back(llvm::ConstantArray::get(StaticsArrayTy,
2384 llvm::StructType *StaticsListTy =
2385 llvm::StructType::get(PtrToInt8Ty, StaticsArrayTy,
nullptr);
2386 llvm::Type *StaticsListPtrTy =
2387 llvm::PointerType::getUnqual(StaticsListTy);
2388 Statics = MakeGlobal(StaticsListTy, Elements,
".objc_statics");
2389 llvm::ArrayType *StaticsListArrayTy =
2390 llvm::ArrayType::get(StaticsListPtrTy, 2);
2392 Elements.push_back(Statics);
2393 Elements.push_back(llvm::Constant::getNullValue(StaticsListPtrTy));
2394 Statics = MakeGlobal(StaticsListArrayTy, Elements,
".objc_statics_ptr");
2395 Statics = llvm::ConstantExpr::getBitCast(Statics, PtrTy);
2398 llvm::ArrayType *ClassListTy = llvm::ArrayType::get(PtrToInt8Ty,
2399 Classes.size() + Categories.size() + 2);
2400 llvm::StructType *SymTabTy = llvm::StructType::get(LongTy, SelStructPtrTy,
2401 llvm::Type::getInt16Ty(VMContext),
2402 llvm::Type::getInt16Ty(VMContext),
2403 ClassListTy,
nullptr);
2407 std::vector<llvm::Constant*> Selectors;
2408 std::vector<llvm::GlobalAlias*> SelectorAliases;
2412 std::string SelNameStr = iter->first.getAsString();
2413 llvm::Constant *SelName = ExportUniqueString(SelNameStr,
".objc_sel_name");
2417 e = Types.end() ; i!=e ; i++) {
2419 llvm::Constant *SelectorTypeEncoding = NULLPtr;
2420 if (!i->first.empty())
2421 SelectorTypeEncoding = MakeConstantString(i->first,
".objc_sel_types");
2423 Elements.push_back(SelName);
2424 Elements.push_back(SelectorTypeEncoding);
2425 Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements));
2429 SelectorAliases.push_back(i->second);
2432 unsigned SelectorCount = Selectors.size();
2437 Elements.push_back(NULLPtr);
2438 Elements.push_back(NULLPtr);
2439 Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements));
2443 Elements.push_back(llvm::ConstantInt::get(LongTy, SelectorCount));
2444 llvm::GlobalVariable *SelectorList =
2445 MakeGlobalArray(SelStructTy, Selectors,
".objc_selector_list");
2446 Elements.push_back(llvm::ConstantExpr::getBitCast(SelectorList,
2450 for (
unsigned int i=0 ; i<SelectorCount ; i++) {
2452 llvm::Constant *Idxs[] = {Zeros[0],
2453 llvm::ConstantInt::get(Int32Ty, i), Zeros[0]};
2455 llvm::Constant *SelPtr = llvm::ConstantExpr::getGetElementPtr(
2456 SelectorList->getValueType(), SelectorList, makeArrayRef(Idxs, 2));
2459 SelPtr = llvm::ConstantExpr::getBitCast(SelPtr, SelectorTy);
2460 SelectorAliases[i]->replaceAllUsesWith(SelPtr);
2461 SelectorAliases[i]->eraseFromParent();
2465 Elements.push_back(llvm::ConstantInt::get(llvm::Type::getInt16Ty(VMContext),
2468 Elements.push_back(llvm::ConstantInt::get(llvm::Type::getInt16Ty(VMContext),
2469 Categories.size()));
2471 Classes.insert(Classes.end(), Categories.begin(), Categories.end());
2473 Classes.push_back(Statics);
2474 Classes.push_back(NULLPtr);
2475 llvm::Constant *ClassList = llvm::ConstantArray::get(ClassListTy, Classes);
2476 Elements.push_back(ClassList);
2478 llvm::Constant *SymTab= MakeGlobal(SymTabTy, Elements);
2482 llvm::StructType * ModuleTy = llvm::StructType::get(LongTy, LongTy,
2483 PtrToInt8Ty, llvm::PointerType::getUnqual(SymTabTy),
2484 (RuntimeVersion >= 10) ? IntTy :
nullptr,
nullptr);
2487 Elements.push_back(llvm::ConstantInt::get(LongTy, RuntimeVersion));
2489 llvm::DataLayout td(&TheModule);
2491 llvm::ConstantInt::get(LongTy,
2492 td.getTypeSizeInBits(ModuleTy) /
2493 CGM.getContext().getCharWidth()));
2500 Elements.push_back(MakeConstantString(path,
".objc_source_file_name"));
2501 Elements.push_back(SymTab);
2503 if (RuntimeVersion >= 10)
2504 switch (CGM.getLangOpts().getGC()) {
2505 case LangOptions::GCOnly:
2506 Elements.push_back(llvm::ConstantInt::get(IntTy, 2));
2508 case LangOptions::NonGC:
2509 if (CGM.getLangOpts().ObjCAutoRefCount)
2510 Elements.push_back(llvm::ConstantInt::get(IntTy, 1));
2512 Elements.push_back(llvm::ConstantInt::get(IntTy, 0));
2514 case LangOptions::HybridGC:
2515 Elements.push_back(llvm::ConstantInt::get(IntTy, 1));
2524 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
2527 llvm::BasicBlock *EntryBB =
2530 Builder.SetInsertPoint(EntryBB);
2532 llvm::FunctionType *FT =
2533 llvm::FunctionType::get(Builder.getVoidTy(),
2534 llvm::PointerType::getUnqual(ModuleTy),
true);
2535 llvm::Value *Register = CGM.CreateRuntimeFunction(FT,
"__objc_exec_class");
2536 Builder.CreateCall(Register, Module);
2538 if (!ClassAliases.empty()) {
2539 llvm::Type *ArgTypes[2] = {PtrTy, PtrToInt8Ty};
2540 llvm::FunctionType *RegisterAliasTy =
2541 llvm::FunctionType::get(Builder.getVoidTy(),
2545 llvm::GlobalValue::ExternalWeakLinkage,
"class_registerAlias_np",
2547 llvm::BasicBlock *AliasBB =
2549 llvm::BasicBlock *NoAliasBB =
2553 llvm::Value *HasRegisterAlias = Builder.CreateICmpNE(RegisterAlias,
2554 llvm::Constant::getNullValue(RegisterAlias->getType()));
2555 Builder.CreateCondBr(HasRegisterAlias, AliasBB, NoAliasBB);
2558 Builder.SetInsertPoint(AliasBB);
2560 for (std::vector<ClassAliasPair>::iterator iter = ClassAliases.begin();
2561 iter != ClassAliases.end(); ++iter) {
2562 llvm::Constant *TheClass =
2563 TheModule.getGlobalVariable((
"_OBJC_CLASS_" + iter->first).c_str(),
2566 TheClass = llvm::ConstantExpr::getBitCast(TheClass, PtrTy);
2567 Builder.CreateCall(RegisterAlias,
2568 {TheClass, MakeConstantString(iter->second)});
2572 Builder.CreateBr(NoAliasBB);
2575 Builder.SetInsertPoint(NoAliasBB);
2577 Builder.CreateRetVoid();
2579 return LoadFunction;
2582 llvm::Function *CGObjCGNU::GenerateMethod(
const ObjCMethodDecl *OMD,
2586 StringRef CategoryName = OCD ? OCD->
getName() :
"";
2587 StringRef ClassName = CD->
getName();
2592 llvm::FunctionType *MethodTy =
2595 MethodName, isClassMethod);
2597 llvm::Function *Method
2605 llvm::Constant *CGObjCGNU::GetPropertyGetFunction() {
2606 return GetPropertyFn;
2609 llvm::Constant *CGObjCGNU::GetPropertySetFunction() {
2610 return SetPropertyFn;
2613 llvm::Constant *CGObjCGNU::GetOptimizedPropertySetFunction(
bool atomic,
2618 llvm::Constant *CGObjCGNU::GetGetStructFunction() {
2619 return GetStructPropertyFn;
2621 llvm::Constant *CGObjCGNU::GetSetStructFunction() {
2622 return SetStructPropertyFn;
2624 llvm::Constant *CGObjCGNU::GetCppAtomicObjectGetFunction() {
2627 llvm::Constant *CGObjCGNU::GetCppAtomicObjectSetFunction() {
2631 llvm::Constant *CGObjCGNU::EnumerationMutationFunction() {
2632 return EnumerationMutationFn;
2637 EmitAtSynchronizedStmt(CGF, S, SyncEnterFn, SyncExitFn);
2654 EmitTryCatchStmt(CGF, S, EnterCatchFn, ExitCatchFn, ExceptionReThrowFn);
2660 bool ClearInsertionPoint) {
2665 ExceptionAsObject = Exception;
2668 "Unexpected rethrow outside @catch block.");
2671 ExceptionAsObject = CGF.
Builder.CreateBitCast(ExceptionAsObject, IdTy);
2672 llvm::CallSite Throw =
2674 Throw.setDoesNotReturn();
2675 CGF.
Builder.CreateUnreachable();
2676 if (ClearInsertionPoint)
2677 CGF.
Builder.ClearInsertionPoint();
2683 AddrWeakObj = EnforceType(B, AddrWeakObj, PtrToIdTy);
2684 return B.CreateCall(WeakReadFn.getType(), WeakReadFn, AddrWeakObj);
2690 src = EnforceType(B, src, IdTy);
2691 dst = EnforceType(B, dst, PtrToIdTy);
2692 B.CreateCall(WeakAssignFn.getType(), WeakAssignFn, {src, dst});
2699 src = EnforceType(B, src, IdTy);
2700 dst = EnforceType(B, dst, PtrToIdTy);
2702 assert(!threadlocal &&
"EmitObjCGlobalAssign - Threal Local API NYI");
2703 B.CreateCall(GlobalAssignFn.getType(), GlobalAssignFn, {src, dst});
2710 src = EnforceType(B, src, IdTy);
2711 dst = EnforceType(B, dst, IdTy);
2712 B.CreateCall(IvarAssignFn.getType(), IvarAssignFn, {src, dst, ivarOffset});
2718 src = EnforceType(B, src, IdTy);
2719 dst = EnforceType(B, dst, PtrToIdTy);
2720 B.CreateCall(StrongCastAssignFn.getType(), StrongCastAssignFn, {src, dst});
2728 DestPtr = EnforceType(B, DestPtr, PtrTy);
2729 SrcPtr = EnforceType(B, SrcPtr, PtrTy);
2731 B.CreateCall(MemMoveFn.getType(), MemMoveFn, {DestPtr, SrcPtr, Size});
2734 llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
2737 const std::string Name =
"__objc_ivar_offset_" + ID->
getNameAsString()
2742 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
2743 if (!IvarOffsetPointer) {
2747 uint64_t Offset = -1;
2754 if (!CGM.getContext().getObjCImplementation(
2755 const_cast<ObjCInterfaceDecl *>(ID)))
2756 Offset = ComputeIvarBaseOffset(CGM, ID, Ivar);
2758 llvm::ConstantInt *OffsetGuess = llvm::ConstantInt::get(Int32Ty, Offset,
2764 if (CGM.getLangOpts().PICLevel || CGM.getLangOpts().PIELevel) {
2765 llvm::GlobalVariable *IvarOffsetGV =
new llvm::GlobalVariable(TheModule,
2767 llvm::GlobalValue::PrivateLinkage, OffsetGuess, Name+
".guess");
2768 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule,
2769 IvarOffsetGV->getType(),
false, llvm::GlobalValue::LinkOnceAnyLinkage,
2770 IvarOffsetGV, Name);
2772 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule,
2773 llvm::Type::getInt32PtrTy(VMContext),
false,
2777 return IvarOffsetPointer;
2784 unsigned CVRQualifiers) {
2787 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
2788 EmitIvarOffset(CGF, ID, Ivar));
2810 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
2812 if (RuntimeVersion < 10)
2813 return CGF.
Builder.CreateZExtOrBitCast(
2815 ObjCIvarOffsetVariable(Interface, Ivar),
false,
"ivar")),
2817 std::string name =
"__objc_ivar_offset_value_" +
2819 llvm::Value *Offset = TheModule.getGlobalVariable(name);
2821 Offset =
new llvm::GlobalVariable(TheModule, IntTy,
2822 false, llvm::GlobalValue::LinkOnceAnyLinkage,
2823 llvm::Constant::getNullValue(IntTy), name);
2824 Offset = CGF.
Builder.CreateLoad(Offset);
2825 if (Offset->getType() != PtrDiffTy)
2826 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
2829 uint64_t Offset = ComputeIvarBaseOffset(CGF.
CGM, Interface, Ivar);
2830 return llvm::ConstantInt::get(PtrDiffTy, Offset,
true);
2836 case ObjCRuntime::GNUstep:
2837 return new CGObjCGNUstep(CGM);
2839 case ObjCRuntime::GCC:
2840 return new CGObjCGCC(CGM);
2842 case ObjCRuntime::ObjFW:
2843 return new CGObjCObjFW(CGM);
2845 case ObjCRuntime::FragileMacOSX:
2846 case ObjCRuntime::MacOSX:
2847 case ObjCRuntime::iOS:
2848 llvm_unreachable(
"these runtimes are not GNU runtimes");
2850 llvm_unreachable(
"bad runtime");
Defines the clang::ASTContext interface.
static std::string SymbolNameForMethod(StringRef ClassName, StringRef CategoryName, const Selector MethodName, bool isClassMethod)
ObjCInterfaceDecl * getDecl() const
getDecl - 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
protocol_range protocols() const
Smart pointer class that efficiently represents Objective-C method names.
Represents a version number in the form major[.minor[.subminor[.build]]].
Defines the clang::FileManager interface and associated types.
IdentifierInfo * getIdentifier() const
PropertyControl getPropertyImplementation() const
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
Implements runtime-specific code generation functions.
Defines the SourceManager interface.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
Represents Objective-C's @throw statement.
const ObjCObjectType * getObjectType() const
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
const ASTRecordLayout & getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const
Get or compute information about the layout of the specified Objective-C implementation.
Defines the Objective-C statement AST node classes.
llvm::Value * EmitObjCThrowOperand(const Expr *expr)
This table allows us to fully hide how we implement multi-keyword caching.
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)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Describes a module or submodule.
RValue EmitCall(const CGFunctionInfo &FnInfo, llvm::Value *Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, const Decl *TargetDecl=nullptr, llvm::Instruction **callOrInvoke=nullptr)
llvm::Value * getAggregateAddr() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
ObjCInterfaceDecl * getInterface() const
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep)
Creates clause with a list of variables VL and a linear step Step.
ObjCRuntime()
A bogus initialization of the runtime.
std::string getNameAsString() const
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
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.
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.
ID
Defines the set of possible language-specific address spaces.
void InitTempAlloca(llvm::AllocaInst *Alloca, llvm::Value *Value)
InitTempAlloca - Provide an initial value for the given alloca.
StringRef getName() const
Return the actual identifier string.
DeclContext * getDeclContext()
Represents Objective-C's @synchronized statement.
void add(RValue rvalue, QualType type, bool needscopy=false)
bool isObjCIdType() const
bool isInstanceMethod() const
clang::ObjCRuntime ObjCRuntime
'gnustep' is the modern non-fragile GNUstep runtime.
llvm::IRBuilder< PreserveNames, llvm::ConstantFolder, CGBuilderInserterTy > CGBuilderTy
ObjCCategoryDecl * getCategoryDecl() const
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
const char * getName() const
ASTContext & getContext() const
CharUnits getSize() const
getSize - Get the record size in characters.
const ObjCInterfaceDecl * getClassInterface() const
SmallVector< llvm::Value *, 8 > ObjCEHValueStack
Cached information about one file (either on disk or in the virtual file system). ...
const CGFunctionInfo & arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD)
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. "foo:bar:") and return it as an std::string.
Represents one property declaration in an Objective-C interface.
const VersionTuple & getVersion() const
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()
instmeth_range instance_methods() const
prop_range properties() const
return(x >> y)|(x<< (32-y))
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.
__builtin_va_list va_list
const ObjCInterfaceType * getInterfaceType() const
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
StringRef getString() const
Selector getSelector() const
ObjCMethodDecl * getGetterMethodDecl() const
ObjCMethodDecl * getSetterMethodDecl() const
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)
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
Represents Objective-C's @try ... @catch ... @finally statement.
const Expr * getThrowExpr() const
ObjCInterfaceDecl * getSuperClass() const
llvm::Value * LoadObjCSelf()
virtual bool isDynamic(OpenMPScheduleClauseKind ScheduleKind) const
Check if the specified ScheduleKind is dynamic. This kind of worksharing directive is emitted without...
ObjCIvarDecl * all_declared_ivar_begin()
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.
This class handles loading and caching of source files into memory.
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.