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) {}
67 std::vector<llvm::Type *> ArgTys;
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=
"") {
170 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(),
192 llvm::GlobalVariable *MakeGlobal(llvm::StructType *Ty,
196 llvm::GlobalValue::LinkageTypes linkage
198 llvm::Constant *
C = llvm::ConstantStruct::get(Ty, V);
199 auto GV =
new llvm::GlobalVariable(TheModule, Ty,
false,
207 llvm::GlobalVariable *MakeGlobal(llvm::ArrayType *Ty,
211 llvm::GlobalValue::LinkageTypes linkage
213 llvm::Constant *C = llvm::ConstantArray::get(Ty, V);
214 auto GV =
new llvm::GlobalVariable(TheModule, Ty,
false,
221 llvm::GlobalVariable *MakeGlobalArray(
llvm::Type *Ty,
225 llvm::GlobalValue::LinkageTypes linkage
227 llvm::ArrayType *ArrayTy = llvm::ArrayType::get(Ty, V.size());
228 return MakeGlobal(ArrayTy, V, Align,
Name, linkage);
232 const Decl *Container) {
236 std::string NameAndAttributes;
238 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr);
239 NameAndAttributes +=
'\0';
240 NameAndAttributes += TypeStr.length() + 3;
241 NameAndAttributes += TypeStr;
242 NameAndAttributes +=
'\0';
244 return MakeConstantString(NameAndAttributes);
249 void PushPropertyAttributes(std::vector<llvm::Constant*> &Fields,
252 int attrs =
property->getPropertyAttributes();
261 Fields.push_back(llvm::ConstantInt::get(Int8Ty, attrs & 0xff));
267 attrs |= isSynthesized ? (1<<0) : 0;
271 Fields.push_back(llvm::ConstantInt::get(Int8Ty, attrs & 0xff));
273 Fields.push_back(llvm::ConstantInt::get(Int8Ty, 0));
274 Fields.push_back(llvm::ConstantInt::get(Int8Ty, 0));
280 if (V->getType() == Ty)
return V;
284 if (V.
getType() == Ty)
return V;
288 llvm::Constant *Zeros[2];
290 llvm::Constant *NULLPtr;
292 llvm::LLVMContext &VMContext;
298 llvm::GlobalAlias *ClassPtrAlias;
303 llvm::GlobalAlias *MetaClassPtrAlias;
305 std::vector<llvm::Constant*> Classes;
307 std::vector<llvm::Constant*> Categories;
310 std::vector<llvm::Constant*> ConstantStrings;
314 llvm::StringMap<llvm::Constant*> ObjCStrings;
316 llvm::StringMap<llvm::Constant*> ExistingProtocols;
322 typedef std::pair<std::string, llvm::GlobalAlias*> TypedSelector;
326 typedef llvm::DenseMap<Selector, SmallVector<TypedSelector, 2> >
334 Selector RetainSel, ReleaseSel, AutoreleaseSel;
338 LazyRuntimeFunction IvarAssignFn, StrongCastAssignFn, MemMoveFn, WeakReadFn,
339 WeakAssignFn, GlobalAssignFn;
341 typedef std::pair<std::string, std::string> ClassAliasPair;
343 std::vector<ClassAliasPair> ClassAliases;
347 LazyRuntimeFunction ExceptionThrowFn;
350 LazyRuntimeFunction ExceptionReThrowFn;
353 LazyRuntimeFunction EnterCatchFn;
356 LazyRuntimeFunction ExitCatchFn;
358 LazyRuntimeFunction SyncEnterFn;
360 LazyRuntimeFunction SyncExitFn;
366 LazyRuntimeFunction EnumerationMutationFn;
369 LazyRuntimeFunction GetPropertyFn;
372 LazyRuntimeFunction SetPropertyFn;
374 LazyRuntimeFunction GetStructPropertyFn;
376 LazyRuntimeFunction SetStructPropertyFn;
387 const int ProtocolVersion;
401 llvm::Constant *GenerateMethodList(StringRef ClassName,
402 StringRef CategoryName,
405 bool isClassMethodList);
409 llvm::Constant *GenerateEmptyProtocol(
const std::string &ProtocolName);
422 void GenerateProtocolHolderCategory();
424 llvm::Constant *GenerateClassStructure(
425 llvm::Constant *MetaClass,
426 llvm::Constant *SuperClass,
429 llvm::Constant *Version,
430 llvm::Constant *InstanceSize,
431 llvm::Constant *IVars,
432 llvm::Constant *Methods,
433 llvm::Constant *Protocols,
434 llvm::Constant *IvarOffsets,
435 llvm::Constant *Properties,
436 llvm::Constant *StrongIvarBitmap,
437 llvm::Constant *WeakIvarBitmap,
441 llvm::Constant *GenerateProtocolMethodList(
447 const std::string &TypeEncoding);
454 void EmitClassRef(
const std::string &className);
457 const std::string &
Name,
bool isWeak);
465 MessageSendInfo &MSI) = 0;
472 MessageSendInfo &MSI) = 0;
487 unsigned protocolClassVersion);
510 llvm::Constant *GetEHType(
QualType T)
override;
520 llvm::Function *ModuleInitFunction()
override;
521 llvm::Constant *GetPropertyGetFunction()
override;
522 llvm::Constant *GetPropertySetFunction()
override;
523 llvm::Constant *GetOptimizedPropertySetFunction(
bool atomic,
525 llvm::Constant *GetSetStructFunction()
override;
526 llvm::Constant *GetGetStructFunction()
override;
527 llvm::Constant *GetCppAtomicObjectGetFunction()
override;
528 llvm::Constant *GetCppAtomicObjectSetFunction()
override;
529 llvm::Constant *EnumerationMutationFunction()
override;
537 bool ClearInsertionPoint=
true)
override;
544 bool threadlocal=
false)
override;
554 unsigned CVRQualifiers)
override;
572 llvm::GlobalVariable *GetClassGlobal(
const std::string &
Name,
573 bool Weak =
false)
override {
585 class CGObjCGCC :
public CGObjCGNU {
588 LazyRuntimeFunction MsgLookupFn;
592 LazyRuntimeFunction MsgLookupSuperFn;
596 MessageSendInfo &MSI)
override {
599 EnforceType(Builder, Receiver, IdTy),
600 EnforceType(Builder, cmd, SelectorTy) };
602 imp->setMetadata(msgSendMDKind, node);
603 return imp.getInstruction();
608 llvm::Value *lookupArgs[] = {EnforceType(Builder, ObjCSuper,
609 PtrToObjCSuperTy).getPointer(), cmd};
615 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy,
618 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
619 PtrToObjCSuperTy, SelectorTy,
nullptr);
623 class CGObjCGNUstep :
public CGObjCGNU {
626 LazyRuntimeFunction SlotLookupFn;
631 LazyRuntimeFunction SlotLookupSuperFn;
633 LazyRuntimeFunction SetPropertyAtomic;
635 LazyRuntimeFunction SetPropertyAtomicCopy;
637 LazyRuntimeFunction SetPropertyNonAtomic;
639 LazyRuntimeFunction SetPropertyNonAtomicCopy;
642 LazyRuntimeFunction CxxAtomicObjectGetFn;
645 LazyRuntimeFunction CxxAtomicObjectSetFn;
650 llvm::Constant *GetEHType(
QualType T)
override;
654 MessageSendInfo &MSI)
override {
656 llvm::Function *LookupFn = SlotLookupFn;
668 self = llvm::ConstantPointerNull::get(IdTy);
672 LookupFn->setDoesNotCapture(1);
675 EnforceType(Builder, ReceiverPtr.
getPointer(), PtrToIdTy),
676 EnforceType(Builder, cmd, SelectorTy),
677 EnforceType(Builder,
self, IdTy) };
679 slot.setOnlyReadsMemory();
680 slot->setMetadata(msgSendMDKind, node);
689 Receiver = Builder.
CreateLoad(ReceiverPtr,
true);
694 MessageSendInfo &MSI)
override {
698 llvm::CallInst *slot =
700 slot->setOnlyReadsMemory();
709 llvm::StructType *SlotStructTy = llvm::StructType::get(PtrTy,
710 PtrTy, PtrTy, IntTy, IMPTy,
nullptr);
711 SlotTy = llvm::PointerType::getUnqual(SlotStructTy);
713 SlotLookupFn.init(&CGM,
"objc_msg_lookup_sender", SlotTy, PtrToIdTy,
714 SelectorTy, IdTy,
nullptr);
716 SlotLookupSuperFn.init(&CGM,
"objc_slot_lookup_super", SlotTy,
717 PtrToObjCSuperTy, SelectorTy,
nullptr);
719 if (CGM.getLangOpts().CPlusPlus) {
720 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
722 EnterCatchFn.init(&CGM,
"__cxa_begin_catch", PtrTy, PtrTy,
nullptr);
724 ExitCatchFn.init(&CGM,
"__cxa_end_catch", VoidTy,
nullptr);
726 ExceptionReThrowFn.init(&CGM,
"_Unwind_Resume_or_Rethrow", VoidTy,
729 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
731 EnterCatchFn.init(&CGM,
"objc_begin_catch", IdTy, PtrTy,
nullptr);
733 ExitCatchFn.init(&CGM,
"objc_end_catch", VoidTy,
nullptr);
735 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy,
738 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
739 SetPropertyAtomic.init(&CGM,
"objc_setProperty_atomic", VoidTy, IdTy,
740 SelectorTy, IdTy, PtrDiffTy,
nullptr);
741 SetPropertyAtomicCopy.init(&CGM,
"objc_setProperty_atomic_copy", VoidTy,
742 IdTy, SelectorTy, IdTy, PtrDiffTy,
nullptr);
743 SetPropertyNonAtomic.init(&CGM,
"objc_setProperty_nonatomic", VoidTy,
744 IdTy, SelectorTy, IdTy, PtrDiffTy,
nullptr);
745 SetPropertyNonAtomicCopy.init(&CGM,
"objc_setProperty_nonatomic_copy",
746 VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy,
nullptr);
749 CxxAtomicObjectSetFn.init(&CGM,
"objc_setCppObjectAtomic", VoidTy, PtrTy,
750 PtrTy, PtrTy,
nullptr);
753 CxxAtomicObjectGetFn.init(&CGM,
"objc_getCppObjectAtomic", VoidTy, PtrTy,
754 PtrTy, PtrTy,
nullptr);
756 llvm::Constant *GetCppAtomicObjectGetFunction()
override {
759 assert (CGM.getLangOpts().ObjCRuntime.getVersion() >=
761 return CxxAtomicObjectGetFn;
763 llvm::Constant *GetCppAtomicObjectSetFunction()
override {
766 assert (CGM.getLangOpts().ObjCRuntime.getVersion() >=
768 return CxxAtomicObjectSetFn;
770 llvm::Constant *GetOptimizedPropertySetFunction(
bool atomic,
771 bool copy)
override {
778 assert (CGM.getLangOpts().ObjCRuntime.getVersion() >=
782 if (copy)
return SetPropertyAtomicCopy;
783 return SetPropertyAtomic;
786 return copy ? SetPropertyNonAtomicCopy : SetPropertyNonAtomic;
791 class CGObjCObjFW:
public CGObjCGNU {
795 LazyRuntimeFunction MsgLookupFn;
798 LazyRuntimeFunction MsgLookupFnSRet;
802 LazyRuntimeFunction MsgLookupSuperFn, MsgLookupSuperFnSRet;
806 MessageSendInfo &MSI)
override {
809 EnforceType(Builder, Receiver, IdTy),
810 EnforceType(Builder, cmd, SelectorTy) };
813 if (CGM.ReturnTypeUsesSRet(MSI.CallInfo))
818 imp->setMetadata(msgSendMDKind, node);
819 return imp.getInstruction();
826 PtrToObjCSuperTy), cmd};
828 if (CGM.ReturnTypeUsesSRet(MSI.CallInfo))
835 const std::string &
Name,
bool isWeak)
override {
837 return CGObjCGNU::GetClassNamed(CGF, Name, isWeak);
841 std::string SymbolName =
"_OBJC_CLASS_" +
Name;
843 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(SymbolName);
846 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
848 nullptr, SymbolName);
856 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy,
nullptr);
857 MsgLookupFnSRet.init(&CGM,
"objc_msg_lookup_stret", IMPTy, IdTy,
858 SelectorTy,
nullptr);
860 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
861 PtrToObjCSuperTy, SelectorTy,
nullptr);
862 MsgLookupSuperFnSRet.init(&CGM,
"objc_msg_lookup_super_stret", IMPTy,
863 PtrToObjCSuperTy, SelectorTy,
nullptr);
872 void CGObjCGNU::EmitClassRef(
const std::string &className) {
873 std::string symbolRef =
"__objc_class_ref_" + className;
875 if (TheModule.getGlobalVariable(symbolRef))
877 std::string symbolName =
"__objc_class_name_" + className;
878 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
880 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
882 nullptr, symbolName);
884 new llvm::GlobalVariable(TheModule, ClassSymbol->getType(),
true,
885 llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef);
889 StringRef CategoryName,
const Selector MethodName,
890 bool isClassMethod) {
891 std::string MethodNameColonStripped = MethodName.
getAsString();
892 std::replace(MethodNameColonStripped.begin(), MethodNameColonStripped.end(),
894 return (Twine(isClassMethod ?
"_c_" :
"_i_") + ClassName +
"_" +
895 CategoryName +
"_" + MethodNameColonStripped).str();
898 CGObjCGNU::CGObjCGNU(
CodeGenModule &cgm,
unsigned runtimeABIVersion,
899 unsigned protocolClassVersion)
901 VMContext(cgm.getLLVMContext()), ClassPtrAlias(nullptr),
902 MetaClassPtrAlias(nullptr), RuntimeVersion(runtimeABIVersion),
903 ProtocolVersion(protocolClassVersion) {
905 msgSendMDKind = VMContext.getMDKindID(
"GNUObjCMessageSend");
908 IntTy = cast<llvm::IntegerType>(
910 LongTy = cast<llvm::IntegerType>(
912 SizeTy = cast<llvm::IntegerType>(
913 Types.
ConvertType(CGM.getContext().getSizeType()));
914 PtrDiffTy = cast<llvm::IntegerType>(
915 Types.
ConvertType(CGM.getContext().getPointerDiffType()));
916 BoolTy = CGM.getTypes().ConvertType(CGM.getContext().BoolTy);
918 Int8Ty = llvm::Type::getInt8Ty(VMContext);
920 PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
922 Zeros[0] = llvm::ConstantInt::get(LongTy, 0);
924 NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty);
926 QualType selTy = CGM.getContext().getObjCSelType();
928 SelectorTy = PtrToInt8Ty;
930 SelectorTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(selTy));
933 PtrToIntTy = llvm::PointerType::getUnqual(IntTy);
936 Int32Ty = llvm::Type::getInt32Ty(VMContext);
937 Int64Ty = llvm::Type::getInt64Ty(VMContext);
940 CGM.getDataLayout().getPointerSizeInBits() == 32 ? Int32Ty : Int64Ty;
943 QualType UnqualIdTy = CGM.getContext().getObjCIdType();
946 ASTIdTy = CGM.getContext().getCanonicalType(UnqualIdTy);
947 IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy));
951 PtrToIdTy = llvm::PointerType::getUnqual(IdTy);
953 ObjCSuperTy = llvm::StructType::get(IdTy, IdTy,
nullptr);
954 PtrToObjCSuperTy = llvm::PointerType::getUnqual(ObjCSuperTy);
956 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
959 ExceptionThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy,
nullptr);
960 ExceptionReThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy,
nullptr);
962 SyncEnterFn.init(&CGM,
"objc_sync_enter", IntTy, IdTy,
nullptr);
964 SyncExitFn.init(&CGM,
"objc_sync_exit", IntTy, IdTy,
nullptr);
967 EnumerationMutationFn.init(&CGM,
"objc_enumerationMutation", VoidTy,
971 GetPropertyFn.init(&CGM,
"objc_getProperty", IdTy, IdTy, SelectorTy,
972 PtrDiffTy, BoolTy,
nullptr);
974 SetPropertyFn.init(&CGM,
"objc_setProperty", VoidTy, IdTy, SelectorTy,
975 PtrDiffTy, IdTy, BoolTy, BoolTy,
nullptr);
977 GetStructPropertyFn.init(&CGM,
"objc_getPropertyStruct", VoidTy, PtrTy, PtrTy,
978 PtrDiffTy, BoolTy, BoolTy,
nullptr);
980 SetStructPropertyFn.init(&CGM,
"objc_setPropertyStruct", VoidTy, PtrTy, PtrTy,
981 PtrDiffTy, BoolTy, BoolTy,
nullptr);
984 llvm::Type *IMPArgs[] = { IdTy, SelectorTy };
985 IMPTy = llvm::PointerType::getUnqual(llvm::FunctionType::get(IdTy, IMPArgs,
989 if ((Opts.getGC() != LangOptions::NonGC) || Opts.ObjCAutoRefCount)
993 if (Opts.getGC() != LangOptions::NonGC) {
1005 IvarAssignFn.init(&CGM,
"objc_assign_ivar", IdTy, IdTy, IdTy, PtrDiffTy,
1008 StrongCastAssignFn.init(&CGM,
"objc_assign_strongCast", IdTy, IdTy,
1009 PtrToIdTy,
nullptr);
1011 GlobalAssignFn.init(&CGM,
"objc_assign_global", IdTy, IdTy, PtrToIdTy,
1014 WeakAssignFn.init(&CGM,
"objc_assign_weak", IdTy, IdTy, PtrToIdTy,
nullptr);
1016 WeakReadFn.init(&CGM,
"objc_read_weak", IdTy, PtrToIdTy,
nullptr);
1018 MemMoveFn.init(&CGM,
"objc_memmove_collectable", PtrTy, PtrTy, PtrTy,
1024 const std::string &Name,
1026 llvm::Constant *ClassName = MakeConstantString(Name);
1037 llvm::Constant *ClassLookupFn =
1038 CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, PtrToInt8Ty,
true),
1039 "objc_lookup_class");
1050 return GetClassNamed(CGF,
"NSAutoreleasePool",
false);
1054 const std::string &TypeEncoding) {
1057 llvm::GlobalAlias *SelValue =
nullptr;
1060 e = Types.end() ; i!=e ; i++) {
1061 if (i->first == TypeEncoding) {
1062 SelValue = i->second;
1068 SelectorTy->getElementType(), 0, llvm::GlobalValue::PrivateLinkage,
1069 ".objc_selector_" + Sel.
getAsString(), &TheModule);
1070 Types.emplace_back(TypeEncoding, SelValue);
1088 return GetSelector(CGF, Sel, std::string());
1093 std::string SelTypes;
1094 CGM.getContext().getObjCEncodingForMethodDecl(Method, SelTypes);
1095 return GetSelector(CGF, Method->
getSelector(), SelTypes);
1098 llvm::Constant *CGObjCGNU::GetEHType(
QualType T) {
1104 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
1105 return MakeConstantString(
"@id");
1113 assert(OPT &&
"Invalid @catch type.");
1115 assert(IDecl &&
"Invalid @catch type.");
1119 llvm::Constant *CGObjCGNUstep::GetEHType(
QualType T) {
1120 if (!CGM.getLangOpts().CPlusPlus)
1121 return CGObjCGNU::GetEHType(T);
1129 llvm::Constant *IDEHType =
1130 CGM.getModule().getGlobalVariable(
"__objc_id_type_info");
1133 new llvm::GlobalVariable(CGM.getModule(), PtrToInt8Ty,
1136 nullptr,
"__objc_id_type_info");
1137 return llvm::ConstantExpr::getBitCast(IDEHType, PtrToInt8Ty);
1142 assert(PT &&
"Invalid @catch type.");
1144 assert(IT &&
"Invalid @catch type.");
1147 std::string typeinfoName =
"__objc_eh_typeinfo_" + className;
1150 llvm::Constant *typeinfo = TheModule.getGlobalVariable(typeinfoName);
1152 return llvm::ConstantExpr::getBitCast(typeinfo, PtrToInt8Ty);
1159 const char *vtableName =
"_ZTVN7gnustep7libobjc22__objc_class_type_infoE";
1160 auto *Vtable = TheModule.getGlobalVariable(vtableName);
1162 Vtable =
new llvm::GlobalVariable(TheModule, PtrToInt8Ty,
true,
1164 nullptr, vtableName);
1166 llvm::Constant *Two = llvm::ConstantInt::get(IntTy, 2);
1167 auto *BVtable = llvm::ConstantExpr::getBitCast(
1168 llvm::ConstantExpr::getGetElementPtr(Vtable->getValueType(), Vtable, Two),
1171 llvm::Constant *typeName =
1172 ExportUniqueString(className,
"__objc_eh_typename_");
1174 std::vector<llvm::Constant*> fields;
1175 fields.push_back(BVtable);
1176 fields.push_back(typeName);
1177 llvm::Constant *TI =
1178 MakeGlobal(llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty,
nullptr),
1179 fields, CGM.getPointerAlign(),
1180 "__objc_eh_typeinfo_" + className,
1181 llvm::GlobalValue::LinkOnceODRLinkage);
1182 return llvm::ConstantExpr::getBitCast(TI, PtrToInt8Ty);
1188 std::string Str = SL->
getString().str();
1189 CharUnits Align = CGM.getPointerAlign();
1193 if (old != ObjCStrings.end())
1196 StringRef StringClass = CGM.getLangOpts().ObjCConstantStringClass;
1198 if (StringClass.empty()) StringClass =
"NXConstantString";
1200 std::string Sym =
"_OBJC_CLASS_";
1203 llvm::Constant *
isa = TheModule.getNamedGlobal(Sym);
1206 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
1207 llvm::GlobalValue::ExternalWeakLinkage,
nullptr, Sym);
1208 else if (isa->getType() != PtrToIdTy)
1209 isa = llvm::ConstantExpr::getBitCast(isa, PtrToIdTy);
1211 std::vector<llvm::Constant*> Ivars;
1212 Ivars.push_back(isa);
1213 Ivars.push_back(MakeConstantString(Str));
1214 Ivars.push_back(llvm::ConstantInt::get(IntTy, Str.size()));
1215 llvm::Constant *ObjCStr = MakeGlobal(
1216 llvm::StructType::get(PtrToIdTy, PtrToInt8Ty, IntTy,
nullptr),
1217 Ivars, Align,
".objc_str");
1218 ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStr, PtrToInt8Ty);
1219 ObjCStrings[Str] = ObjCStr;
1220 ConstantStrings.push_back(ObjCStr);
1233 bool isCategoryImpl,
1235 bool IsClassMessage,
1239 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
1240 if (Sel == RetainSel || Sel == AutoreleaseSel) {
1241 return RValue::get(EnforceType(Builder, Receiver,
1242 CGM.getTypes().ConvertType(ResultType)));
1244 if (Sel == ReleaseSel) {
1245 return RValue::get(
nullptr);
1254 ActualArgs.
add(RValue::get(EnforceType(Builder, Receiver, IdTy)), ASTIdTy);
1258 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
1261 if (isCategoryImpl) {
1262 llvm::Constant *classLookupFunction =
nullptr;
1263 if (IsClassMessage) {
1264 classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
1265 IdTy, PtrTy,
true),
"objc_get_meta_class");
1267 classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
1268 IdTy, PtrTy,
true),
"objc_get_class");
1270 ReceiverClass = Builder.CreateCall(classLookupFunction,
1278 if (IsClassMessage) {
1279 if (!MetaClassPtrAlias) {
1284 ReceiverClass = MetaClassPtrAlias;
1286 if (!ClassPtrAlias) {
1291 ReceiverClass = ClassPtrAlias;
1295 llvm::Type *CastTy = llvm::StructType::get(IdTy, IdTy,
nullptr);
1297 llvm::PointerType::getUnqual(CastTy));
1304 llvm::StructType *ObjCSuperTy = llvm::StructType::get(
1305 Receiver->getType(), IdTy,
nullptr);
1316 ObjCSuper = EnforceType(Builder, ObjCSuper, PtrToObjCSuperTy);
1319 llvm::Value *imp = LookupIMPSuper(CGF, ObjCSuper, cmd, MSI);
1320 imp = EnforceType(Builder, imp, MSI.MessengerType);
1322 llvm::Metadata *impMD[] = {
1323 llvm::MDString::get(VMContext, Sel.
getAsString()),
1325 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
1326 llvm::Type::getInt1Ty(VMContext), IsClassMessage))};
1327 llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD);
1329 llvm::Instruction *call;
1330 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, imp, Return, ActualArgs,
1332 call->setMetadata(msgSendMDKind, node);
1349 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
1350 if (Sel == RetainSel || Sel == AutoreleaseSel) {
1351 return RValue::get(EnforceType(Builder, Receiver,
1352 CGM.getTypes().ConvertType(ResultType)));
1354 if (Sel == ReleaseSel) {
1355 return RValue::get(
nullptr);
1373 llvm::BasicBlock *startBB =
nullptr;
1374 llvm::BasicBlock *messageBB =
nullptr;
1375 llvm::BasicBlock *continueBB =
nullptr;
1377 if (!isPointerSizedReturn) {
1378 startBB = Builder.GetInsertBlock();
1382 llvm::Value *isNil = Builder.CreateICmpEQ(Receiver,
1383 llvm::Constant::getNullValue(Receiver->getType()));
1384 Builder.CreateCondBr(isNil, continueBB, messageBB);
1388 IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy));
1391 cmd = GetSelector(CGF, Method);
1393 cmd = GetSelector(CGF, Sel);
1394 cmd = EnforceType(Builder, cmd, SelectorTy);
1395 Receiver = EnforceType(Builder, Receiver, IdTy);
1397 llvm::Metadata *impMD[] = {
1398 llvm::MDString::get(VMContext, Sel.
getAsString()),
1399 llvm::MDString::get(VMContext, Class ? Class->
getNameAsString() :
""),
1400 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
1401 llvm::Type::getInt1Ty(VMContext), Class !=
nullptr))};
1402 llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD);
1405 ActualArgs.
add(RValue::get(Receiver), ASTIdTy);
1409 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
1417 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
1418 case CodeGenOptions::Legacy:
1419 imp = LookupIMP(CGF, Receiver, cmd, node, MSI);
1421 case CodeGenOptions::Mixed:
1422 case CodeGenOptions::NonLegacy:
1423 if (CGM.ReturnTypeUsesFPRet(ResultType)) {
1424 imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy,
true),
1425 "objc_msgSend_fpret");
1426 }
else if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) {
1429 imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy,
true),
1430 "objc_msgSend_stret");
1432 imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy,
true),
1438 ActualArgs[0] =
CallArg(RValue::get(Receiver), ASTIdTy,
false);
1440 imp = EnforceType(Builder, imp, MSI.MessengerType);
1442 llvm::Instruction *call;
1443 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, imp, Return, ActualArgs,
1445 call->setMetadata(msgSendMDKind, node);
1448 if (!isPointerSizedReturn) {
1449 messageBB = CGF.
Builder.GetInsertBlock();
1450 CGF.
Builder.CreateBr(continueBB);
1454 llvm::PHINode *phi = Builder.CreatePHI(v->getType(), 2);
1455 phi->addIncoming(v, messageBB);
1456 phi->addIncoming(llvm::Constant::getNullValue(v->getType()), startBB);
1457 msgRet = RValue::get(phi);
1460 llvm::PHINode *phi = Builder.CreatePHI(v.
getType(), 2);
1463 CGF.
InitTempAlloca(NullVal, llvm::Constant::getNullValue(RetTy));
1465 phi->addIncoming(NullVal.
getPointer(), startBB);
1468 std::pair<llvm::Value*,llvm::Value*> v = msgRet.
getComplexVal();
1469 llvm::PHINode *phi = Builder.CreatePHI(v.first->getType(), 2);
1470 phi->addIncoming(v.first, messageBB);
1471 phi->addIncoming(llvm::Constant::getNullValue(v.first->getType()),
1473 llvm::PHINode *phi2 = Builder.CreatePHI(v.second->getType(), 2);
1474 phi2->addIncoming(v.second, messageBB);
1475 phi2->addIncoming(llvm::Constant::getNullValue(v.second->getType()),
1477 msgRet = RValue::getComplex(phi, phi2);
1485 llvm::Constant *CGObjCGNU::
1486 GenerateMethodList(StringRef ClassName,
1487 StringRef CategoryName,
1490 bool isClassMethodList) {
1491 if (MethodSels.empty())
1494 llvm::StructType *ObjCMethodTy = llvm::StructType::get(
1499 std::vector<llvm::Constant*> Methods;
1500 std::vector<llvm::Constant*> Elements;
1501 for (
unsigned int i = 0, e = MethodTypes.size(); i < e; ++i) {
1503 llvm::Constant *Method =
1506 isClassMethodList));
1507 assert(Method &&
"Can't generate metadata for method that doesn't exist");
1508 llvm::Constant *C = MakeConstantString(MethodSels[i].getAsString());
1509 Elements.push_back(C);
1510 Elements.push_back(MethodTypes[i]);
1511 Method = llvm::ConstantExpr::getBitCast(Method,
1513 Elements.push_back(Method);
1514 Methods.push_back(llvm::ConstantStruct::get(ObjCMethodTy, Elements));
1518 llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodTy,
1520 llvm::Constant *MethodArray = llvm::ConstantArray::get(ObjCMethodArrayTy,
1525 llvm::Type *NextPtrTy = llvm::PointerType::getUnqual(ObjCMethodListTy);
1526 ObjCMethodListTy->setBody(
1533 Methods.push_back(llvm::ConstantPointerNull::get(
1534 llvm::PointerType::getUnqual(ObjCMethodListTy)));
1535 Methods.push_back(llvm::ConstantInt::get(Int32Ty, MethodTypes.size()));
1536 Methods.push_back(MethodArray);
1539 return MakeGlobal(ObjCMethodListTy, Methods, CGM.getPointerAlign(),
1540 ".objc_method_list");
1544 llvm::Constant *CGObjCGNU::
1548 if (IvarNames.size() == 0)
1551 llvm::StructType *ObjCIvarTy = llvm::StructType::get(
1556 std::vector<llvm::Constant*> Ivars;
1557 std::vector<llvm::Constant*> Elements;
1558 for (
unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {
1560 Elements.push_back(IvarNames[i]);
1561 Elements.push_back(IvarTypes[i]);
1562 Elements.push_back(IvarOffsets[i]);
1563 Ivars.push_back(llvm::ConstantStruct::get(ObjCIvarTy, Elements));
1567 llvm::ArrayType *ObjCIvarArrayTy = llvm::ArrayType::get(ObjCIvarTy,
1572 Elements.push_back(llvm::ConstantInt::get(IntTy, (
int)IvarNames.size()));
1573 Elements.push_back(llvm::ConstantArray::get(ObjCIvarArrayTy, Ivars));
1575 llvm::StructType *ObjCIvarListTy = llvm::StructType::get(IntTy,
1580 return MakeGlobal(ObjCIvarListTy, Elements, CGM.getPointerAlign(),
1585 llvm::Constant *CGObjCGNU::GenerateClassStructure(
1586 llvm::Constant *MetaClass,
1587 llvm::Constant *SuperClass,
1590 llvm::Constant *Version,
1591 llvm::Constant *InstanceSize,
1592 llvm::Constant *IVars,
1593 llvm::Constant *Methods,
1594 llvm::Constant *Protocols,
1595 llvm::Constant *IvarOffsets,
1596 llvm::Constant *Properties,
1597 llvm::Constant *StrongIvarBitmap,
1598 llvm::Constant *WeakIvarBitmap,
1607 llvm::StructType *ClassTy = llvm::StructType::get(
1624 IvarOffsets->getType(),
1625 Properties->getType(),
1629 llvm::Constant *Zero = llvm::ConstantInt::get(LongTy, 0);
1631 std::vector<llvm::Constant*> Elements;
1632 Elements.push_back(llvm::ConstantExpr::getBitCast(MetaClass, PtrToInt8Ty));
1633 Elements.push_back(SuperClass);
1634 Elements.push_back(MakeConstantString(Name,
".class_name"));
1635 Elements.push_back(Zero);
1636 Elements.push_back(llvm::ConstantInt::get(LongTy, info));
1638 llvm::DataLayout td(&TheModule);
1640 llvm::ConstantInt::get(LongTy,
1641 td.getTypeSizeInBits(ClassTy) /
1642 CGM.getContext().getCharWidth()));
1644 Elements.push_back(InstanceSize);
1645 Elements.push_back(IVars);
1646 Elements.push_back(Methods);
1647 Elements.push_back(NULLPtr);
1648 Elements.push_back(NULLPtr);
1649 Elements.push_back(NULLPtr);
1650 Elements.push_back(llvm::ConstantExpr::getBitCast(Protocols, PtrTy));
1651 Elements.push_back(NULLPtr);
1652 Elements.push_back(llvm::ConstantInt::get(LongTy, 1));
1653 Elements.push_back(IvarOffsets);
1654 Elements.push_back(Properties);
1655 Elements.push_back(StrongIvarBitmap);
1656 Elements.push_back(WeakIvarBitmap);
1661 std::string ClassSym((isMeta ?
"_OBJC_METACLASS_":
"_OBJC_CLASS_") +
1663 llvm::GlobalVariable *ClassRef = TheModule.getNamedGlobal(ClassSym);
1664 llvm::Constant *Class =
1665 MakeGlobal(ClassTy, Elements, CGM.getPointerAlign(), ClassSym,
1668 ClassRef->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(Class,
1669 ClassRef->getType()));
1670 ClassRef->removeFromParent();
1671 Class->setName(ClassSym);
1676 llvm::Constant *CGObjCGNU::
1680 llvm::StructType *ObjCMethodDescTy = llvm::StructType::get(
1684 std::vector<llvm::Constant*> Methods;
1685 std::vector<llvm::Constant*> Elements;
1686 for (
unsigned int i = 0, e = MethodTypes.size() ; i < e ; i++) {
1688 Elements.push_back(MethodNames[i]);
1689 Elements.push_back(MethodTypes[i]);
1690 Methods.push_back(llvm::ConstantStruct::get(ObjCMethodDescTy, Elements));
1692 llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodDescTy,
1693 MethodNames.size());
1694 llvm::Constant *Array = llvm::ConstantArray::get(ObjCMethodArrayTy,
1696 llvm::StructType *ObjCMethodDescListTy = llvm::StructType::get(
1697 IntTy, ObjCMethodArrayTy,
nullptr);
1699 Methods.push_back(llvm::ConstantInt::get(IntTy, MethodNames.size()));
1700 Methods.push_back(Array);
1701 return MakeGlobal(ObjCMethodDescListTy, Methods, CGM.getPointerAlign(),
1702 ".objc_method_list");
1707 llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrToInt8Ty,
1709 llvm::StructType *ProtocolListTy = llvm::StructType::get(
1714 std::vector<llvm::Constant*> Elements;
1715 for (
const std::string *iter = Protocols.begin(), *endIter = Protocols.end();
1716 iter != endIter ; iter++) {
1717 llvm::Constant *protocol =
nullptr;
1719 ExistingProtocols.find(*iter);
1720 if (value == ExistingProtocols.end()) {
1721 protocol = GenerateEmptyProtocol(*iter);
1723 protocol = value->getValue();
1725 llvm::Constant *Ptr = llvm::ConstantExpr::getBitCast(protocol,
1727 Elements.push_back(Ptr);
1729 llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
1732 Elements.push_back(NULLPtr);
1733 Elements.push_back(llvm::ConstantInt::get(LongTy, Protocols.size()));
1734 Elements.push_back(ProtocolArray);
1735 return MakeGlobal(ProtocolListTy, Elements, CGM.getPointerAlign(),
1736 ".objc_protocol_list");
1743 CGM.getTypes().ConvertType(CGM.getContext().getObjCProtoType());
1747 llvm::Constant *CGObjCGNU::GenerateEmptyProtocol(
1748 const std::string &ProtocolName) {
1752 llvm::Constant *ProtocolList = GenerateProtocolList(EmptyStringVector);
1753 llvm::Constant *MethodList =
1754 GenerateProtocolMethodList(EmptyConstantVector, EmptyConstantVector);
1757 llvm::StructType *ProtocolTy = llvm::StructType::get(IdTy,
1759 ProtocolList->getType(),
1760 MethodList->getType(),
1761 MethodList->getType(),
1762 MethodList->getType(),
1763 MethodList->getType(),
1765 std::vector<llvm::Constant*> Elements;
1768 Elements.push_back(llvm::ConstantExpr::getIntToPtr(
1769 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
1770 Elements.push_back(MakeConstantString(ProtocolName,
".objc_protocol_name"));
1771 Elements.push_back(ProtocolList);
1772 Elements.push_back(MethodList);
1773 Elements.push_back(MethodList);
1774 Elements.push_back(MethodList);
1775 Elements.push_back(MethodList);
1776 return MakeGlobal(ProtocolTy, Elements, CGM.getPointerAlign(),
1790 Protocols.push_back(PI->getNameAsString());
1796 std::string TypeStr;
1798 if (
I->getImplementationControl() == ObjCMethodDecl::Optional) {
1799 OptionalInstanceMethodNames.push_back(
1800 MakeConstantString(
I->getSelector().getAsString()));
1801 OptionalInstanceMethodTypes.push_back(MakeConstantString(TypeStr));
1803 InstanceMethodNames.push_back(
1804 MakeConstantString(
I->getSelector().getAsString()));
1805 InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
1814 std::string TypeStr;
1816 if (
I->getImplementationControl() == ObjCMethodDecl::Optional) {
1817 OptionalClassMethodNames.push_back(
1818 MakeConstantString(
I->getSelector().getAsString()));
1819 OptionalClassMethodTypes.push_back(MakeConstantString(TypeStr));
1821 ClassMethodNames.push_back(
1822 MakeConstantString(
I->getSelector().getAsString()));
1823 ClassMethodTypes.push_back(MakeConstantString(TypeStr));
1827 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
1828 llvm::Constant *InstanceMethodList =
1829 GenerateProtocolMethodList(InstanceMethodNames, InstanceMethodTypes);
1830 llvm::Constant *ClassMethodList =
1831 GenerateProtocolMethodList(ClassMethodNames, ClassMethodTypes);
1832 llvm::Constant *OptionalInstanceMethodList =
1833 GenerateProtocolMethodList(OptionalInstanceMethodNames,
1834 OptionalInstanceMethodTypes);
1835 llvm::Constant *OptionalClassMethodList =
1836 GenerateProtocolMethodList(OptionalClassMethodNames,
1837 OptionalClassMethodTypes);
1844 llvm::StructType *PropertyMetadataTy = llvm::StructType::get(
1845 PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty,
1846 PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty,
nullptr);
1847 std::vector<llvm::Constant*> Properties;
1848 std::vector<llvm::Constant*> OptionalProperties;
1853 std::vector<llvm::Constant*> Fields;
1855 Fields.push_back(MakePropertyEncodingString(property,
nullptr));
1856 PushPropertyAttributes(Fields, property);
1859 std::string TypeStr;
1861 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
1862 InstanceMethodTypes.push_back(TypeEncoding);
1863 Fields.push_back(MakeConstantString(getter->getSelector().getAsString()));
1864 Fields.push_back(TypeEncoding);
1866 Fields.push_back(NULLPtr);
1867 Fields.push_back(NULLPtr);
1870 std::string TypeStr;
1872 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
1873 InstanceMethodTypes.push_back(TypeEncoding);
1874 Fields.push_back(MakeConstantString(setter->getSelector().getAsString()));
1875 Fields.push_back(TypeEncoding);
1877 Fields.push_back(NULLPtr);
1878 Fields.push_back(NULLPtr);
1881 OptionalProperties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
1883 Properties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
1886 llvm::Constant *PropertyArray = llvm::ConstantArray::get(
1887 llvm::ArrayType::get(PropertyMetadataTy, Properties.size()), Properties);
1888 llvm::Constant* PropertyListInitFields[] =
1889 {llvm::ConstantInt::get(IntTy, Properties.size()), NULLPtr, PropertyArray};
1891 llvm::Constant *PropertyListInit =
1892 llvm::ConstantStruct::getAnon(PropertyListInitFields);
1893 llvm::Constant *PropertyList =
new llvm::GlobalVariable(TheModule,
1895 PropertyListInit,
".objc_property_list");
1897 llvm::Constant *OptionalPropertyArray =
1898 llvm::ConstantArray::get(llvm::ArrayType::get(PropertyMetadataTy,
1899 OptionalProperties.size()) , OptionalProperties);
1900 llvm::Constant* OptionalPropertyListInitFields[] = {
1901 llvm::ConstantInt::get(IntTy, OptionalProperties.size()), NULLPtr,
1902 OptionalPropertyArray };
1904 llvm::Constant *OptionalPropertyListInit =
1905 llvm::ConstantStruct::getAnon(OptionalPropertyListInitFields);
1906 llvm::Constant *OptionalPropertyList =
new llvm::GlobalVariable(TheModule,
1907 OptionalPropertyListInit->getType(),
false,
1909 ".objc_property_list");
1913 llvm::StructType *ProtocolTy = llvm::StructType::get(IdTy,
1915 ProtocolList->getType(),
1916 InstanceMethodList->getType(),
1917 ClassMethodList->getType(),
1918 OptionalInstanceMethodList->getType(),
1919 OptionalClassMethodList->getType(),
1920 PropertyList->getType(),
1921 OptionalPropertyList->getType(),
1923 std::vector<llvm::Constant*> Elements;
1926 Elements.push_back(llvm::ConstantExpr::getIntToPtr(
1927 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
1928 Elements.push_back(MakeConstantString(ProtocolName,
".objc_protocol_name"));
1929 Elements.push_back(ProtocolList);
1930 Elements.push_back(InstanceMethodList);
1931 Elements.push_back(ClassMethodList);
1932 Elements.push_back(OptionalInstanceMethodList);
1933 Elements.push_back(OptionalClassMethodList);
1934 Elements.push_back(PropertyList);
1935 Elements.push_back(OptionalPropertyList);
1936 ExistingProtocols[ProtocolName] =
1937 llvm::ConstantExpr::getBitCast(MakeGlobal(ProtocolTy, Elements,
1938 CGM.getPointerAlign(),
".objc_protocol"), IdTy);
1940 void CGObjCGNU::GenerateProtocolHolderCategory() {
1945 std::vector<llvm::Constant*> Elements;
1946 const std::string ClassName =
"__ObjC_Protocol_Holder_Ugly_Hack";
1947 const std::string CategoryName =
"AnotherHack";
1948 Elements.push_back(MakeConstantString(CategoryName));
1949 Elements.push_back(MakeConstantString(ClassName));
1951 Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
1952 ClassName, CategoryName, MethodSels, MethodTypes,
false), PtrTy));
1954 Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
1955 ClassName, CategoryName, MethodSels, MethodTypes,
true), PtrTy));
1957 llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrTy,
1958 ExistingProtocols.size());
1959 llvm::StructType *ProtocolListTy = llvm::StructType::get(
1964 std::vector<llvm::Constant*> ProtocolElements;
1965 for (llvm::StringMapIterator<llvm::Constant*> iter =
1966 ExistingProtocols.begin(), endIter = ExistingProtocols.end();
1967 iter != endIter ; iter++) {
1968 llvm::Constant *Ptr = llvm::ConstantExpr::getBitCast(iter->getValue(),
1970 ProtocolElements.push_back(Ptr);
1972 llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
1974 ProtocolElements.clear();
1975 ProtocolElements.push_back(NULLPtr);
1976 ProtocolElements.push_back(llvm::ConstantInt::get(LongTy,
1977 ExistingProtocols.size()));
1978 ProtocolElements.push_back(ProtocolArray);
1979 Elements.push_back(llvm::ConstantExpr::getBitCast(MakeGlobal(ProtocolListTy,
1980 ProtocolElements, CGM.getPointerAlign(),
1981 ".objc_protocol_list"), PtrTy));
1982 Categories.push_back(llvm::ConstantExpr::getBitCast(
1983 MakeGlobal(llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty,
1984 PtrTy, PtrTy, PtrTy,
nullptr), Elements, CGM.getPointerAlign()),
2000 int bitCount = bits.size();
2001 int ptrBits = CGM.getDataLayout().getPointerSizeInBits();
2002 if (bitCount < ptrBits) {
2004 for (
int i=0 ; i<bitCount ; ++i) {
2005 if (bits[i]) val |= 1ULL<<(i+1);
2007 return llvm::ConstantInt::get(IntPtrTy, val);
2011 while (v < bitCount) {
2013 for (
int i=0 ; (i<32) && (v<bitCount) ; ++i) {
2014 if (bits[v]) word |= 1<<i;
2017 values.push_back(llvm::ConstantInt::get(Int32Ty, word));
2019 llvm::ArrayType *arrayTy = llvm::ArrayType::get(Int32Ty, values.size());
2020 llvm::Constant *array = llvm::ConstantArray::get(arrayTy, values);
2021 llvm::Constant *fields[2] = {
2022 llvm::ConstantInt::get(Int32Ty, values.size()),
2024 llvm::Constant *GS = MakeGlobal(llvm::StructType::get(Int32Ty, arrayTy,
2025 nullptr), fields, CharUnits::fromQuantity(4));
2026 llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy);
2037 InstanceMethodSels.push_back(
I->getSelector());
2038 std::string TypeStr;
2039 CGM.getContext().getObjCEncodingForMethodDecl(
I,TypeStr);
2040 InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
2047 ClassMethodSels.push_back(
I->getSelector());
2048 std::string TypeStr;
2049 CGM.getContext().getObjCEncodingForMethodDecl(
I,TypeStr);
2050 ClassMethodTypes.push_back(MakeConstantString(TypeStr));
2058 E = Protos.
end();
I !=
E; ++
I)
2059 Protocols.push_back((*I)->getNameAsString());
2061 std::vector<llvm::Constant*> Elements;
2062 Elements.push_back(MakeConstantString(CategoryName));
2063 Elements.push_back(MakeConstantString(ClassName));
2065 Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
2066 ClassName, CategoryName, InstanceMethodSels, InstanceMethodTypes,
2069 Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
2070 ClassName, CategoryName, ClassMethodSels, ClassMethodTypes,
true),
2073 Elements.push_back(llvm::ConstantExpr::getBitCast(
2074 GenerateProtocolList(Protocols), PtrTy));
2075 Categories.push_back(llvm::ConstantExpr::getBitCast(
2076 MakeGlobal(llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty,
2077 PtrTy, PtrTy, PtrTy,
nullptr), Elements, CGM.getPointerAlign()),
2087 llvm::StructType *PropertyMetadataTy = llvm::StructType::get(
2088 PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty,
2089 PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty,
nullptr);
2090 std::vector<llvm::Constant*> Properties;
2095 std::vector<llvm::Constant*> Fields;
2097 bool isSynthesized = (propertyImpl->getPropertyImplementation() ==
2098 ObjCPropertyImplDecl::Synthesize);
2099 bool isDynamic = (propertyImpl->getPropertyImplementation() ==
2100 ObjCPropertyImplDecl::Dynamic);
2102 Fields.push_back(MakePropertyEncodingString(property, OID));
2103 PushPropertyAttributes(Fields, property, isSynthesized, isDynamic);
2105 std::string TypeStr;
2107 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
2108 if (isSynthesized) {
2109 InstanceMethodTypes.push_back(TypeEncoding);
2110 InstanceMethodSels.push_back(getter->getSelector());
2112 Fields.push_back(MakeConstantString(getter->getSelector().getAsString()));
2113 Fields.push_back(TypeEncoding);
2115 Fields.push_back(NULLPtr);
2116 Fields.push_back(NULLPtr);
2119 std::string TypeStr;
2121 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
2122 if (isSynthesized) {
2123 InstanceMethodTypes.push_back(TypeEncoding);
2124 InstanceMethodSels.push_back(setter->getSelector());
2126 Fields.push_back(MakeConstantString(setter->getSelector().getAsString()));
2127 Fields.push_back(TypeEncoding);
2129 Fields.push_back(NULLPtr);
2130 Fields.push_back(NULLPtr);
2132 Properties.push_back(llvm::ConstantStruct::get(PropertyMetadataTy, Fields));
2134 llvm::ArrayType *PropertyArrayTy =
2135 llvm::ArrayType::get(PropertyMetadataTy, Properties.size());
2136 llvm::Constant *PropertyArray = llvm::ConstantArray::get(PropertyArrayTy,
2138 llvm::Constant* PropertyListInitFields[] =
2139 {llvm::ConstantInt::get(IntTy, Properties.size()), NULLPtr, PropertyArray};
2141 llvm::Constant *PropertyListInit =
2142 llvm::ConstantStruct::getAnon(PropertyListInitFields);
2143 return new llvm::GlobalVariable(TheModule, PropertyListInit->getType(),
false,
2145 ".objc_property_list");
2162 std::string SuperClassName;
2163 if (SuperClassDecl) {
2165 EmitClassRef(SuperClassName);
2174 std::string classSymbolName =
"__objc_class_name_" + ClassName;
2175 if (llvm::GlobalVariable *symbol =
2176 TheModule.getGlobalVariable(classSymbolName)) {
2177 symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0));
2179 new llvm::GlobalVariable(TheModule, LongTy,
false,
2193 std::vector<llvm::Constant*> IvarOffsetValues;
2197 int superInstanceSize = !SuperClassDecl ? 0 :
2201 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
2202 instanceSize = 0 - (instanceSize - superInstanceSize);
2208 IvarNames.push_back(MakeConstantString(IVD->getNameAsString()));
2210 std::string TypeStr;
2212 IvarTypes.push_back(MakeConstantString(TypeStr));
2214 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
2215 uint64_t
Offset = BaseOffset;
2216 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
2217 Offset = BaseOffset - superInstanceSize;
2219 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
2221 std::string OffsetName =
"__objc_ivar_offset_value_" + ClassName +
"." +
2222 IVD->getNameAsString();
2223 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
2225 OffsetVar->setInitializer(OffsetValue);
2231 OffsetVar =
new llvm::GlobalVariable(TheModule, IntTy,
2234 "__objc_ivar_offset_value_" + ClassName +
"." +
2235 IVD->getNameAsString());
2236 IvarOffsets.push_back(OffsetValue);
2237 IvarOffsetValues.push_back(OffsetVar);
2240 case Qualifiers::OCL_Strong:
2241 StrongIvars.push_back(
true);
2242 WeakIvars.push_back(
false);
2244 case Qualifiers::OCL_Weak:
2245 StrongIvars.push_back(
false);
2246 WeakIvars.push_back(
true);
2249 StrongIvars.push_back(
false);
2250 WeakIvars.push_back(
false);
2253 llvm::Constant *StrongIvarBitmap = MakeBitField(StrongIvars);
2254 llvm::Constant *WeakIvarBitmap = MakeBitField(WeakIvars);
2255 llvm::GlobalVariable *IvarOffsetArray =
2256 MakeGlobalArray(PtrToIntTy, IvarOffsetValues, CGM.getPointerAlign(),
2264 InstanceMethodSels.push_back(
I->getSelector());
2265 std::string TypeStr;
2267 InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
2270 llvm::Constant *Properties = GeneratePropertyList(OID, InstanceMethodSels,
2271 InstanceMethodTypes);
2278 ClassMethodSels.push_back(
I->getSelector());
2279 std::string TypeStr;
2281 ClassMethodTypes.push_back(MakeConstantString(TypeStr));
2286 Protocols.push_back(
I->getNameAsString());
2289 llvm::Constant *SuperClass;
2290 if (!SuperClassName.empty()) {
2291 SuperClass = MakeConstantString(SuperClassName,
".super_class_name");
2293 SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty);
2298 llvm::Constant *MethodList = GenerateMethodList(ClassName,
"",
2299 InstanceMethodSels, InstanceMethodTypes,
false);
2300 llvm::Constant *ClassMethodList = GenerateMethodList(ClassName,
"",
2301 ClassMethodSels, ClassMethodTypes,
true);
2302 llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
2314 llvm::Type *IndexTy = Int32Ty;
2315 llvm::Constant *offsetPointerIndexes[] = {Zeros[0],
2316 llvm::ConstantInt::get(IndexTy, 1),
nullptr,
2317 llvm::ConstantInt::get(IndexTy, 2) };
2319 unsigned ivarIndex = 0;
2322 const std::string Name =
"__objc_ivar_offset_" + ClassName +
'.'
2323 + IVD->getNameAsString();
2324 offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, ivarIndex);
2326 llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr(
2327 cast<llvm::GlobalVariable>(IvarList)->getValueType(), IvarList,
2328 offsetPointerIndexes);
2330 llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name);
2332 offset->setInitializer(offsetValue);
2339 offset =
new llvm::GlobalVariable(TheModule, offsetValue->getType(),
2345 llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0);
2347 llvm::Constant *MetaClassStruct = GenerateClassStructure(NULLPtr,
2348 NULLPtr, 0x12L, ClassName.c_str(),
nullptr, Zeros[0], GenerateIvarList(
2349 empty, empty, empty), ClassMethodList, NULLPtr,
2350 NULLPtr, NULLPtr, ZeroPtr, ZeroPtr,
true);
2353 llvm::Constant *ClassStruct =
2354 GenerateClassStructure(MetaClassStruct, SuperClass, 0x11L,
2355 ClassName.c_str(),
nullptr,
2356 llvm::ConstantInt::get(LongTy, instanceSize), IvarList,
2357 MethodList, GenerateProtocolList(Protocols), IvarOffsetArray,
2358 Properties, StrongIvarBitmap, WeakIvarBitmap);
2361 if (ClassPtrAlias) {
2362 ClassPtrAlias->replaceAllUsesWith(
2363 llvm::ConstantExpr::getBitCast(ClassStruct, IdTy));
2364 ClassPtrAlias->eraseFromParent();
2365 ClassPtrAlias =
nullptr;
2367 if (MetaClassPtrAlias) {
2368 MetaClassPtrAlias->replaceAllUsesWith(
2369 llvm::ConstantExpr::getBitCast(MetaClassStruct, IdTy));
2370 MetaClassPtrAlias->eraseFromParent();
2371 MetaClassPtrAlias =
nullptr;
2375 ClassStruct = llvm::ConstantExpr::getBitCast(ClassStruct, PtrToInt8Ty);
2376 Classes.push_back(ClassStruct);
2380 llvm::Function *CGObjCGNU::ModuleInitFunction() {
2382 if (Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
2387 GenerateProtocolHolderCategory();
2389 llvm::StructType *SelStructTy = dyn_cast<llvm::StructType>(
2390 SelectorTy->getElementType());
2391 llvm::Type *SelStructPtrTy = SelectorTy;
2393 SelStructTy = llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty,
nullptr);
2394 SelStructPtrTy = llvm::PointerType::getUnqual(SelStructTy);
2397 std::vector<llvm::Constant*> Elements;
2398 llvm::Constant *Statics = NULLPtr;
2400 if (!ConstantStrings.empty()) {
2401 llvm::ArrayType *StaticsArrayTy = llvm::ArrayType::get(PtrToInt8Ty,
2402 ConstantStrings.size() + 1);
2403 ConstantStrings.push_back(NULLPtr);
2405 StringRef StringClass = CGM.getLangOpts().ObjCConstantStringClass;
2407 if (StringClass.empty()) StringClass =
"NXConstantString";
2409 Elements.push_back(MakeConstantString(StringClass,
2410 ".objc_static_class_name"));
2411 Elements.push_back(llvm::ConstantArray::get(StaticsArrayTy,
2413 llvm::StructType *StaticsListTy =
2414 llvm::StructType::get(PtrToInt8Ty, StaticsArrayTy,
nullptr);
2415 llvm::Type *StaticsListPtrTy =
2416 llvm::PointerType::getUnqual(StaticsListTy);
2417 Statics = MakeGlobal(StaticsListTy, Elements, CGM.getPointerAlign(),
2419 llvm::ArrayType *StaticsListArrayTy =
2420 llvm::ArrayType::get(StaticsListPtrTy, 2);
2422 Elements.push_back(Statics);
2423 Elements.push_back(llvm::Constant::getNullValue(StaticsListPtrTy));
2424 Statics = MakeGlobal(StaticsListArrayTy, Elements,
2425 CGM.getPointerAlign(),
".objc_statics_ptr");
2426 Statics = llvm::ConstantExpr::getBitCast(Statics, PtrTy);
2429 llvm::ArrayType *ClassListTy = llvm::ArrayType::get(PtrToInt8Ty,
2430 Classes.size() + Categories.size() + 2);
2431 llvm::StructType *SymTabTy = llvm::StructType::get(LongTy, SelStructPtrTy,
2432 llvm::Type::getInt16Ty(VMContext),
2433 llvm::Type::getInt16Ty(VMContext),
2434 ClassListTy,
nullptr);
2438 std::vector<llvm::Constant*> Selectors;
2439 std::vector<llvm::GlobalAlias*> SelectorAliases;
2443 std::string SelNameStr = iter->first.getAsString();
2444 llvm::Constant *SelName = ExportUniqueString(SelNameStr,
".objc_sel_name");
2448 e = Types.end() ; i!=e ; i++) {
2450 llvm::Constant *SelectorTypeEncoding = NULLPtr;
2451 if (!i->first.empty())
2452 SelectorTypeEncoding = MakeConstantString(i->first,
".objc_sel_types");
2454 Elements.push_back(SelName);
2455 Elements.push_back(SelectorTypeEncoding);
2456 Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements));
2460 SelectorAliases.push_back(i->second);
2463 unsigned SelectorCount = Selectors.size();
2468 Elements.push_back(NULLPtr);
2469 Elements.push_back(NULLPtr);
2470 Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements));
2474 Elements.push_back(llvm::ConstantInt::get(LongTy, SelectorCount));
2475 llvm::GlobalVariable *SelectorList =
2476 MakeGlobalArray(SelStructTy, Selectors, CGM.getPointerAlign(),
2477 ".objc_selector_list");
2478 Elements.push_back(llvm::ConstantExpr::getBitCast(SelectorList,
2482 for (
unsigned int i=0 ; i<SelectorCount ; i++) {
2484 llvm::Constant *Idxs[] = {Zeros[0],
2485 llvm::ConstantInt::get(Int32Ty, i), Zeros[0]};
2487 llvm::Constant *SelPtr = llvm::ConstantExpr::getGetElementPtr(
2488 SelectorList->getValueType(), SelectorList, makeArrayRef(Idxs, 2));
2491 SelPtr = llvm::ConstantExpr::getBitCast(SelPtr, SelectorTy);
2492 SelectorAliases[i]->replaceAllUsesWith(SelPtr);
2493 SelectorAliases[i]->eraseFromParent();
2497 Elements.push_back(llvm::ConstantInt::get(llvm::Type::getInt16Ty(VMContext),
2500 Elements.push_back(llvm::ConstantInt::get(llvm::Type::getInt16Ty(VMContext),
2501 Categories.size()));
2503 Classes.insert(Classes.end(), Categories.begin(), Categories.end());
2505 Classes.push_back(Statics);
2506 Classes.push_back(NULLPtr);
2507 llvm::Constant *ClassList = llvm::ConstantArray::get(ClassListTy, Classes);
2508 Elements.push_back(ClassList);
2510 llvm::Constant *SymTab =
2511 MakeGlobal(SymTabTy, Elements, CGM.getPointerAlign());
2515 llvm::StructType * ModuleTy = llvm::StructType::get(LongTy, LongTy,
2516 PtrToInt8Ty, llvm::PointerType::getUnqual(SymTabTy),
2517 (RuntimeVersion >= 10) ? IntTy :
nullptr,
nullptr);
2520 Elements.push_back(llvm::ConstantInt::get(LongTy, RuntimeVersion));
2522 llvm::DataLayout td(&TheModule);
2524 llvm::ConstantInt::get(LongTy,
2525 td.getTypeSizeInBits(ModuleTy) /
2526 CGM.getContext().getCharWidth()));
2533 Elements.push_back(MakeConstantString(path,
".objc_source_file_name"));
2534 Elements.push_back(SymTab);
2536 if (RuntimeVersion >= 10)
2537 switch (CGM.getLangOpts().getGC()) {
2538 case LangOptions::GCOnly:
2539 Elements.push_back(llvm::ConstantInt::get(IntTy, 2));
2541 case LangOptions::NonGC:
2542 if (CGM.getLangOpts().ObjCAutoRefCount)
2543 Elements.push_back(llvm::ConstantInt::get(IntTy, 1));
2545 Elements.push_back(llvm::ConstantInt::get(IntTy, 0));
2547 case LangOptions::HybridGC:
2548 Elements.push_back(llvm::ConstantInt::get(IntTy, 1));
2557 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
2560 llvm::BasicBlock *EntryBB =
2563 Builder.SetInsertPoint(EntryBB);
2565 llvm::FunctionType *FT =
2566 llvm::FunctionType::get(Builder.getVoidTy(),
2567 llvm::PointerType::getUnqual(ModuleTy),
true);
2568 llvm::Value *Register = CGM.CreateRuntimeFunction(FT,
"__objc_exec_class");
2569 Builder.CreateCall(Register, Module);
2571 if (!ClassAliases.empty()) {
2572 llvm::Type *ArgTypes[2] = {PtrTy, PtrToInt8Ty};
2573 llvm::FunctionType *RegisterAliasTy =
2574 llvm::FunctionType::get(Builder.getVoidTy(),
2578 llvm::GlobalValue::ExternalWeakLinkage,
"class_registerAlias_np",
2580 llvm::BasicBlock *AliasBB =
2582 llvm::BasicBlock *NoAliasBB =
2586 llvm::Value *HasRegisterAlias = Builder.CreateICmpNE(RegisterAlias,
2587 llvm::Constant::getNullValue(RegisterAlias->getType()));
2588 Builder.CreateCondBr(HasRegisterAlias, AliasBB, NoAliasBB);
2591 Builder.SetInsertPoint(AliasBB);
2594 iter != ClassAliases.end(); ++iter) {
2595 llvm::Constant *TheClass =
2596 TheModule.getGlobalVariable((
"_OBJC_CLASS_" + iter->first).c_str(),
2599 TheClass = llvm::ConstantExpr::getBitCast(TheClass, PtrTy);
2600 Builder.CreateCall(RegisterAlias,
2601 {TheClass, MakeConstantString(iter->second)});
2605 Builder.CreateBr(NoAliasBB);
2608 Builder.SetInsertPoint(NoAliasBB);
2610 Builder.CreateRetVoid();
2612 return LoadFunction;
2615 llvm::Function *CGObjCGNU::GenerateMethod(
const ObjCMethodDecl *OMD,
2619 StringRef CategoryName = OCD ? OCD->
getName() :
"";
2620 StringRef ClassName = CD->
getName();
2625 llvm::FunctionType *MethodTy =
2628 MethodName, isClassMethod);
2630 llvm::Function *Method
2638 llvm::Constant *CGObjCGNU::GetPropertyGetFunction() {
2639 return GetPropertyFn;
2642 llvm::Constant *CGObjCGNU::GetPropertySetFunction() {
2643 return SetPropertyFn;
2646 llvm::Constant *CGObjCGNU::GetOptimizedPropertySetFunction(
bool atomic,
2651 llvm::Constant *CGObjCGNU::GetGetStructFunction() {
2652 return GetStructPropertyFn;
2654 llvm::Constant *CGObjCGNU::GetSetStructFunction() {
2655 return SetStructPropertyFn;
2657 llvm::Constant *CGObjCGNU::GetCppAtomicObjectGetFunction() {
2660 llvm::Constant *CGObjCGNU::GetCppAtomicObjectSetFunction() {
2664 llvm::Constant *CGObjCGNU::EnumerationMutationFunction() {
2665 return EnumerationMutationFn;
2670 EmitAtSynchronizedStmt(CGF, S, SyncEnterFn, SyncExitFn);
2687 EmitTryCatchStmt(CGF, S, EnterCatchFn, ExitCatchFn, ExceptionReThrowFn);
2693 bool ClearInsertionPoint) {
2698 ExceptionAsObject = Exception;
2701 "Unexpected rethrow outside @catch block.");
2705 llvm::CallSite Throw =
2707 Throw.setDoesNotReturn();
2708 CGF.
Builder.CreateUnreachable();
2709 if (ClearInsertionPoint)
2710 CGF.
Builder.ClearInsertionPoint();
2716 AddrWeakObj = EnforceType(B, AddrWeakObj, PtrToIdTy);
2717 return B.CreateCall(WeakReadFn.getType(), WeakReadFn,
2724 src = EnforceType(B, src, IdTy);
2725 dst = EnforceType(B, dst, PtrToIdTy);
2726 B.CreateCall(WeakAssignFn.getType(), WeakAssignFn,
2734 src = EnforceType(B, src, IdTy);
2735 dst = EnforceType(B, dst, PtrToIdTy);
2737 assert(!threadlocal &&
"EmitObjCGlobalAssign - Threal Local API NYI");
2738 B.CreateCall(GlobalAssignFn.getType(), GlobalAssignFn,
2746 src = EnforceType(B, src, IdTy);
2747 dst = EnforceType(B, dst, IdTy);
2748 B.CreateCall(IvarAssignFn.getType(), IvarAssignFn,
2755 src = EnforceType(B, src, IdTy);
2756 dst = EnforceType(B, dst, PtrToIdTy);
2757 B.CreateCall(StrongCastAssignFn.getType(), StrongCastAssignFn,
2766 DestPtr = EnforceType(B, DestPtr, PtrTy);
2767 SrcPtr = EnforceType(B, SrcPtr, PtrTy);
2769 B.CreateCall(MemMoveFn.getType(), MemMoveFn,
2773 llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
2776 const std::string Name =
"__objc_ivar_offset_" + ID->
getNameAsString()
2781 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
2782 if (!IvarOffsetPointer) {
2786 uint64_t Offset = -1;
2793 if (!CGM.getContext().getObjCImplementation(
2794 const_cast<ObjCInterfaceDecl *>(ID)))
2795 Offset = ComputeIvarBaseOffset(CGM, ID, Ivar);
2797 llvm::ConstantInt *OffsetGuess = llvm::ConstantInt::get(Int32Ty, Offset,
2803 if (CGM.getLangOpts().PICLevel || CGM.getLangOpts().PIELevel) {
2804 llvm::GlobalVariable *IvarOffsetGV =
new llvm::GlobalVariable(TheModule,
2806 llvm::GlobalValue::PrivateLinkage, OffsetGuess, Name+
".guess");
2807 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule,
2808 IvarOffsetGV->getType(),
false, llvm::GlobalValue::LinkOnceAnyLinkage,
2809 IvarOffsetGV,
Name);
2811 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule,
2812 llvm::Type::getInt32PtrTy(VMContext),
false,
2816 return IvarOffsetPointer;
2823 unsigned CVRQualifiers) {
2826 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
2827 EmitIvarOffset(CGF, ID, Ivar));
2849 if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
2851 if (RuntimeVersion < 10)
2852 return CGF.
Builder.CreateZExtOrBitCast(
2854 ObjCIvarOffsetVariable(Interface, Ivar),
2857 std::string name =
"__objc_ivar_offset_value_" +
2860 llvm::Value *Offset = TheModule.getGlobalVariable(name);
2862 auto GV =
new llvm::GlobalVariable(TheModule, IntTy,
2863 false, llvm::GlobalValue::LinkOnceAnyLinkage,
2864 llvm::Constant::getNullValue(IntTy), name);
2869 if (Offset->getType() != PtrDiffTy)
2870 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
2873 uint64_t Offset = ComputeIvarBaseOffset(CGF.
CGM, Interface, Ivar);
2874 return llvm::ConstantInt::get(PtrDiffTy, Offset,
true);
2880 case ObjCRuntime::GNUstep:
2881 return new CGObjCGNUstep(CGM);
2883 case ObjCRuntime::GCC:
2884 return new CGObjCGCC(CGM);
2886 case ObjCRuntime::ObjFW:
2887 return new CGObjCObjFW(CGM);
2889 case ObjCRuntime::FragileMacOSX:
2890 case ObjCRuntime::MacOSX:
2891 case ObjCRuntime::iOS:
2892 case ObjCRuntime::WatchOS:
2893 llvm_unreachable(
"these runtimes are not GNU runtimes");
2895 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="")
Decl - This represents one declaration (or definition), e.g.
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.
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.
llvm::Type * getElementType() const
Return the type of the values stored in this address.
ObjCMethodDecl - Represents an instance or class method declaration.
Defines the Objective-C statement AST node classes.
llvm::Constant * getPointer() const
llvm::Value * EmitObjCThrowOperand(const Expr *expr)
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.
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.
ID
Defines the set of possible language-specific address spaces.
llvm::Value * getPointer() const
Expr - This represents one expression.
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
bool isa(CodeGen::Address addr)
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)
Creates clause with a list of variables VL and a linear step Step.
'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
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.
Cached information about one file (either on disk or in the virtual file system). ...
const CGFunctionInfo & arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD)
Arrange the argument and result information for the declaration or definition of an Objective-C metho...
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
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.
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.
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
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
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
llvm::Value * LoadObjCSelf()
LoadObjCSelf - Load the value of self.
virtual bool isDynamic(OpenMPScheduleClauseKind ScheduleKind) const
Check if the specified ScheduleKind is dynamic.
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.