29 #include "llvm/ADT/SmallVector.h" 30 #include "llvm/ADT/StringMap.h" 31 #include "llvm/IR/CallSite.h" 32 #include "llvm/IR/DataLayout.h" 33 #include "llvm/IR/Intrinsics.h" 34 #include "llvm/IR/LLVMContext.h" 35 #include "llvm/IR/Module.h" 36 #include "llvm/Support/Compiler.h" 38 using namespace clang;
39 using namespace CodeGen;
45 class LazyRuntimeFunction {
47 llvm::FunctionType *FTy;
48 const char *FunctionName;
56 : CGM(nullptr), FunctionName(nullptr), Function(nullptr) {}
60 template <
typename... Tys>
68 FTy = llvm::FunctionType::get(RetTy, ArgTys,
false);
71 FTy = llvm::FunctionType::get(RetTy, None,
false);
75 llvm::FunctionType *getType() {
return FTy; }
79 operator llvm::Constant *() {
88 operator llvm::Function *() {
89 return cast<llvm::Function>((llvm::Constant *)*
this);
100 llvm::Module &TheModule;
103 llvm::StructType *ObjCSuperTy;
106 llvm::PointerType *PtrToObjCSuperTy;
110 llvm::PointerType *SelectorTy;
113 llvm::IntegerType *Int8Ty;
116 llvm::PointerType *PtrToInt8Ty;
122 llvm::PointerType *IMPTy;
127 llvm::PointerType *IdTy;
130 llvm::PointerType *PtrToIdTy;
135 llvm::IntegerType *IntTy;
139 llvm::PointerType *PtrTy;
143 llvm::IntegerType *LongTy;
145 llvm::IntegerType *SizeTy;
147 llvm::IntegerType *IntPtrTy;
149 llvm::IntegerType *PtrDiffTy;
152 llvm::PointerType *PtrToIntTy;
156 llvm::IntegerType *Int32Ty;
158 llvm::IntegerType *Int64Ty;
162 unsigned msgSendMDKind;
167 llvm::Constant *MakeConstantString(StringRef Str,
const char *Name =
"") {
169 return llvm::ConstantExpr::getGetElementPtr(Array.
getElementType(),
177 llvm::Constant *ExportUniqueString(
const std::string &Str, StringRef Prefix) {
178 std::string Name = Prefix.str() + Str;
179 auto *ConstStr = TheModule.getGlobalVariable(Name);
181 llvm::Constant *value = llvm::ConstantDataArray::getString(VMContext,Str);
182 ConstStr =
new llvm::GlobalVariable(TheModule, value->getType(),
true,
183 llvm::GlobalValue::LinkOnceODRLinkage,
186 return llvm::ConstantExpr::getGetElementPtr(ConstStr->getValueType(),
193 llvm::GlobalVariable *MakeGlobal(llvm::Constant *C,
196 llvm::GlobalValue::LinkageTypes linkage
198 auto GV =
new llvm::GlobalVariable(TheModule, C->getType(),
false,
206 const Decl *Container) {
210 std::string NameAndAttributes;
211 std::string TypeStr =
213 NameAndAttributes +=
'\0';
214 NameAndAttributes += TypeStr.length() + 3;
215 NameAndAttributes += TypeStr;
216 NameAndAttributes +=
'\0';
218 return MakeConstantString(NameAndAttributes);
227 int attrs =
property->getPropertyAttributes();
236 Fields.addInt(Int8Ty, attrs & 0xff);
242 attrs |= isSynthesized ? (1<<0) : 0;
246 Fields.addInt(Int8Ty, attrs & 0xff);
248 Fields.addInt(Int8Ty, 0);
249 Fields.addInt(Int8Ty, 0);
256 if (V->getType() == Ty)
return V;
260 if (V.
getType() == Ty)
return V;
265 llvm::Constant *Zeros[2];
267 llvm::Constant *NULLPtr;
269 llvm::LLVMContext &VMContext;
276 llvm::GlobalAlias *ClassPtrAlias;
281 llvm::GlobalAlias *MetaClassPtrAlias;
283 std::vector<llvm::Constant*> Classes;
285 std::vector<llvm::Constant*> Categories;
288 std::vector<llvm::Constant*> ConstantStrings;
292 llvm::StringMap<llvm::Constant*> ObjCStrings;
294 llvm::StringMap<llvm::Constant*> ExistingProtocols;
300 typedef std::pair<std::string, llvm::GlobalAlias*> TypedSelector;
304 typedef llvm::DenseMap<Selector, SmallVector<TypedSelector, 2> >
312 Selector RetainSel, ReleaseSel, AutoreleaseSel;
316 LazyRuntimeFunction IvarAssignFn, StrongCastAssignFn, MemMoveFn, WeakReadFn,
317 WeakAssignFn, GlobalAssignFn;
319 typedef std::pair<std::string, std::string> ClassAliasPair;
321 std::vector<ClassAliasPair> ClassAliases;
325 LazyRuntimeFunction ExceptionThrowFn;
328 LazyRuntimeFunction ExceptionReThrowFn;
331 LazyRuntimeFunction EnterCatchFn;
334 LazyRuntimeFunction ExitCatchFn;
336 LazyRuntimeFunction SyncEnterFn;
338 LazyRuntimeFunction SyncExitFn;
343 LazyRuntimeFunction EnumerationMutationFn;
346 LazyRuntimeFunction GetPropertyFn;
349 LazyRuntimeFunction SetPropertyFn;
351 LazyRuntimeFunction GetStructPropertyFn;
353 LazyRuntimeFunction SetStructPropertyFn;
364 const int ProtocolVersion;
379 llvm::Constant *GenerateMethodList(StringRef ClassName,
380 StringRef CategoryName,
383 bool isClassMethodList);
388 llvm::Constant *GenerateEmptyProtocol(
const std::string &ProtocolName);
404 void GenerateProtocolHolderCategory();
407 llvm::Constant *GenerateClassStructure(
408 llvm::Constant *MetaClass,
409 llvm::Constant *SuperClass,
412 llvm::Constant *Version,
413 llvm::Constant *InstanceSize,
414 llvm::Constant *IVars,
415 llvm::Constant *Methods,
416 llvm::Constant *Protocols,
417 llvm::Constant *IvarOffsets,
418 llvm::Constant *Properties,
419 llvm::Constant *StrongIvarBitmap,
420 llvm::Constant *WeakIvarBitmap,
425 llvm::Constant *GenerateProtocolMethodList(
432 const std::string &TypeEncoding);
441 void EmitClassRef(
const std::string &className);
445 const std::string &Name,
bool isWeak);
454 MessageSendInfo &MSI) = 0;
462 MessageSendInfo &MSI) = 0;
479 unsigned protocolClassVersion);
502 llvm::Constant *GetEHType(
QualType T)
override;
512 llvm::Function *ModuleInitFunction()
override;
513 llvm::Constant *GetPropertyGetFunction()
override;
514 llvm::Constant *GetPropertySetFunction()
override;
515 llvm::Constant *GetOptimizedPropertySetFunction(
bool atomic,
517 llvm::Constant *GetSetStructFunction()
override;
518 llvm::Constant *GetGetStructFunction()
override;
519 llvm::Constant *GetCppAtomicObjectGetFunction()
override;
520 llvm::Constant *GetCppAtomicObjectSetFunction()
override;
521 llvm::Constant *EnumerationMutationFunction()
override;
529 bool ClearInsertionPoint=
true)
override;
536 bool threadlocal=
false)
override;
546 unsigned CVRQualifiers)
override;
573 class CGObjCGCC :
public CGObjCGNU {
576 LazyRuntimeFunction MsgLookupFn;
580 LazyRuntimeFunction MsgLookupSuperFn;
585 MessageSendInfo &MSI)
override {
588 EnforceType(Builder, Receiver, IdTy),
589 EnforceType(Builder, cmd, SelectorTy) };
591 imp->setMetadata(msgSendMDKind, node);
592 return imp.getInstruction();
598 llvm::Value *lookupArgs[] = {EnforceType(Builder, ObjCSuper,
599 PtrToObjCSuperTy).getPointer(), cmd};
606 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
608 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
609 PtrToObjCSuperTy, SelectorTy);
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;
642 llvm::Constant *GetEHType(
QualType T)
override;
647 MessageSendInfo &MSI)
override {
649 llvm::Function *LookupFn = SlotLookupFn;
661 self = llvm::ConstantPointerNull::get(IdTy);
665 LookupFn->addParamAttr(0, llvm::Attribute::NoCapture);
668 EnforceType(Builder, ReceiverPtr.
getPointer(), PtrToIdTy),
669 EnforceType(Builder, cmd, SelectorTy),
670 EnforceType(Builder,
self, IdTy) };
672 slot.setOnlyReadsMemory();
673 slot->setMetadata(msgSendMDKind, node);
682 Receiver = Builder.
CreateLoad(ReceiverPtr,
true);
688 MessageSendInfo &MSI)
override {
692 llvm::CallInst *slot =
694 slot->setOnlyReadsMemory();
704 llvm::StructType *SlotStructTy =
705 llvm::StructType::get(PtrTy, PtrTy, PtrTy, IntTy, IMPTy);
706 SlotTy = llvm::PointerType::getUnqual(SlotStructTy);
708 SlotLookupFn.init(&CGM,
"objc_msg_lookup_sender", SlotTy, PtrToIdTy,
711 SlotLookupSuperFn.init(&CGM,
"objc_slot_lookup_super", SlotTy,
712 PtrToObjCSuperTy, SelectorTy);
715 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
717 EnterCatchFn.init(&CGM,
"__cxa_begin_catch", PtrTy, PtrTy);
719 ExitCatchFn.init(&CGM,
"__cxa_end_catch", VoidTy);
721 ExceptionReThrowFn.init(&CGM,
"_Unwind_Resume_or_Rethrow", VoidTy,
724 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
726 EnterCatchFn.init(&CGM,
"objc_begin_catch", IdTy, PtrTy);
728 ExitCatchFn.init(&CGM,
"objc_end_catch", VoidTy);
730 ExceptionReThrowFn.init(&CGM,
"objc_exception_rethrow", VoidTy, PtrTy);
732 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
733 SetPropertyAtomic.init(&CGM,
"objc_setProperty_atomic", VoidTy, IdTy,
734 SelectorTy, IdTy, PtrDiffTy);
735 SetPropertyAtomicCopy.init(&CGM,
"objc_setProperty_atomic_copy", VoidTy,
736 IdTy, SelectorTy, IdTy, PtrDiffTy);
737 SetPropertyNonAtomic.init(&CGM,
"objc_setProperty_nonatomic", VoidTy,
738 IdTy, SelectorTy, IdTy, PtrDiffTy);
739 SetPropertyNonAtomicCopy.init(&CGM,
"objc_setProperty_nonatomic_copy",
740 VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy);
743 CxxAtomicObjectSetFn.init(&CGM,
"objc_setCppObjectAtomic", VoidTy, PtrTy,
747 CxxAtomicObjectGetFn.init(&CGM,
"objc_getCppObjectAtomic", VoidTy, PtrTy,
751 llvm::Constant *GetCppAtomicObjectGetFunction()
override {
756 return CxxAtomicObjectGetFn;
759 llvm::Constant *GetCppAtomicObjectSetFunction()
override {
764 return CxxAtomicObjectSetFn;
767 llvm::Constant *GetOptimizedPropertySetFunction(
bool atomic,
768 bool copy)
override {
779 if (copy)
return SetPropertyAtomicCopy;
780 return SetPropertyAtomic;
783 return copy ? SetPropertyNonAtomicCopy : SetPropertyNonAtomic;
788 class CGObjCObjFW:
public CGObjCGNU {
792 LazyRuntimeFunction MsgLookupFn;
795 LazyRuntimeFunction MsgLookupFnSRet;
799 LazyRuntimeFunction MsgLookupSuperFn, MsgLookupSuperFnSRet;
803 MessageSendInfo &MSI)
override {
806 EnforceType(Builder, Receiver, IdTy),
807 EnforceType(Builder, cmd, SelectorTy) };
815 imp->setMetadata(msgSendMDKind, node);
816 return imp.getInstruction();
823 EnforceType(Builder, ObjCSuper.
getPointer(), PtrToObjCSuperTy), cmd,
833 bool isWeak)
override {
835 return CGObjCGNU::GetClassNamed(CGF, Name, isWeak);
838 std::string SymbolName =
"_OBJC_CLASS_" + Name;
839 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(SymbolName);
841 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
843 nullptr, SymbolName);
850 MsgLookupFn.init(&CGM,
"objc_msg_lookup", IMPTy, IdTy, SelectorTy);
851 MsgLookupFnSRet.init(&CGM,
"objc_msg_lookup_stret", IMPTy, IdTy,
854 MsgLookupSuperFn.init(&CGM,
"objc_msg_lookup_super", IMPTy,
855 PtrToObjCSuperTy, SelectorTy);
856 MsgLookupSuperFnSRet.init(&CGM,
"objc_msg_lookup_super_stret", IMPTy,
857 PtrToObjCSuperTy, SelectorTy);
865 void CGObjCGNU::EmitClassRef(
const std::string &className) {
866 std::string symbolRef =
"__objc_class_ref_" + className;
868 if (TheModule.getGlobalVariable(symbolRef))
870 std::string symbolName =
"__objc_class_name_" + className;
871 llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
873 ClassSymbol =
new llvm::GlobalVariable(TheModule, LongTy,
false,
875 nullptr, symbolName);
877 new llvm::GlobalVariable(TheModule, ClassSymbol->getType(),
true,
878 llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef);
882 StringRef CategoryName,
const Selector MethodName,
883 bool isClassMethod) {
884 std::string MethodNameColonStripped = MethodName.
getAsString();
885 std::replace(MethodNameColonStripped.begin(), MethodNameColonStripped.end(),
887 return (Twine(isClassMethod ?
"_c_" :
"_i_") + ClassName +
"_" +
888 CategoryName +
"_" + MethodNameColonStripped).str();
891 CGObjCGNU::CGObjCGNU(
CodeGenModule &cgm,
unsigned runtimeABIVersion,
892 unsigned protocolClassVersion)
895 MetaClassPtrAlias(
nullptr), RuntimeVersion(runtimeABIVersion),
896 ProtocolVersion(protocolClassVersion) {
898 msgSendMDKind = VMContext.getMDKindID(
"GNUObjCMessageSend");
901 IntTy = cast<llvm::IntegerType>(
903 LongTy = cast<llvm::IntegerType>(
905 SizeTy = cast<llvm::IntegerType>(
907 PtrDiffTy = cast<llvm::IntegerType>(
911 Int8Ty = llvm::Type::getInt8Ty(VMContext);
913 PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
915 Zeros[0] = llvm::ConstantInt::get(LongTy, 0);
917 NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty);
921 SelectorTy = PtrToInt8Ty;
926 PtrToIntTy = llvm::PointerType::getUnqual(IntTy);
929 Int32Ty = llvm::Type::getInt32Ty(VMContext);
930 Int64Ty = llvm::Type::getInt64Ty(VMContext);
933 CGM.
getDataLayout().getPointerSizeInBits() == 32 ? Int32Ty : Int64Ty;
944 PtrToIdTy = llvm::PointerType::getUnqual(IdTy);
946 ObjCSuperTy = llvm::StructType::get(IdTy, IdTy);
947 PtrToObjCSuperTy = llvm::PointerType::getUnqual(ObjCSuperTy);
949 llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
952 ExceptionThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy);
953 ExceptionReThrowFn.init(&CGM,
"objc_exception_throw", VoidTy, IdTy);
955 SyncEnterFn.init(&CGM,
"objc_sync_enter", IntTy, IdTy);
957 SyncExitFn.init(&CGM,
"objc_sync_exit", IntTy, IdTy);
960 EnumerationMutationFn.init(&CGM,
"objc_enumerationMutation", VoidTy, IdTy);
963 GetPropertyFn.init(&CGM,
"objc_getProperty", IdTy, IdTy, SelectorTy,
966 SetPropertyFn.init(&CGM,
"objc_setProperty", VoidTy, IdTy, SelectorTy,
967 PtrDiffTy, IdTy, BoolTy, BoolTy);
969 GetStructPropertyFn.init(&CGM,
"objc_getPropertyStruct", VoidTy, PtrTy, PtrTy,
970 PtrDiffTy, BoolTy, BoolTy);
972 SetStructPropertyFn.init(&CGM,
"objc_setPropertyStruct", VoidTy, PtrTy, PtrTy,
973 PtrDiffTy, BoolTy, BoolTy);
977 IMPTy = llvm::PointerType::getUnqual(llvm::FunctionType::get(IdTy, IMPArgs,
997 IvarAssignFn.init(&CGM,
"objc_assign_ivar", IdTy, IdTy, IdTy, PtrDiffTy);
999 StrongCastAssignFn.init(&CGM,
"objc_assign_strongCast", IdTy, IdTy,
1002 GlobalAssignFn.init(&CGM,
"objc_assign_global", IdTy, IdTy, PtrToIdTy);
1004 WeakAssignFn.init(&CGM,
"objc_assign_weak", IdTy, IdTy, PtrToIdTy);
1006 WeakReadFn.init(&CGM,
"objc_read_weak", IdTy, PtrToIdTy);
1008 MemMoveFn.init(&CGM,
"objc_memmove_collectable", PtrTy, PtrTy, PtrTy,
1014 const std::string &Name,
bool isWeak) {
1015 llvm::Constant *ClassName = MakeConstantString(Name);
1026 llvm::Constant *ClassLookupFn =
1028 "objc_lookup_class");
1038 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1039 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value)) {
1040 auto DLLStorage = llvm::GlobalValue::DefaultStorageClass;
1041 if (OID->
hasAttr<DLLExportAttr>())
1042 DLLStorage = llvm::GlobalValue::DLLExportStorageClass;
1043 else if (OID->
hasAttr<DLLImportAttr>())
1044 DLLStorage = llvm::GlobalValue::DLLImportStorageClass;
1045 ClassSymbol->setDLLStorageClass(DLLStorage);
1052 auto *
Value = GetClassNamed(CGF,
"NSAutoreleasePool",
false);
1053 if (CGM.
getTriple().isOSBinFormatCOFF()) {
1054 if (
auto *ClassSymbol = dyn_cast<llvm::GlobalVariable>(
Value)) {
1060 for (
const auto &Result : DC->
lookup(&II))
1061 if ((VD = dyn_cast<VarDecl>(Result)))
1064 auto DLLStorage = llvm::GlobalValue::DefaultStorageClass;
1065 if (!VD || VD->
hasAttr<DLLImportAttr>())
1066 DLLStorage = llvm::GlobalValue::DLLImportStorageClass;
1067 else if (VD->
hasAttr<DLLExportAttr>())
1068 DLLStorage = llvm::GlobalValue::DLLExportStorageClass;
1070 ClassSymbol->setDLLStorageClass(DLLStorage);
1077 const std::string &TypeEncoding) {
1079 llvm::GlobalAlias *SelValue =
nullptr;
1082 e = Types.end() ; i!=e ; i++) {
1083 if (i->first == TypeEncoding) {
1084 SelValue = i->second;
1090 SelectorTy->getElementType(), 0, llvm::GlobalValue::PrivateLinkage,
1091 ".objc_selector_" + Sel.
getAsString(), &TheModule);
1092 Types.emplace_back(TypeEncoding, SelValue);
1110 return GetSelector(CGF, Sel, std::string());
1116 return GetSelector(CGF, Method->
getSelector(), SelTypes);
1119 llvm::Constant *CGObjCGNU::GetEHType(
QualType T) {
1126 return MakeConstantString(
"@id");
1134 assert(OPT &&
"Invalid @catch type.");
1136 assert(IDecl &&
"Invalid @catch type.");
1140 llvm::Constant *CGObjCGNUstep::GetEHType(
QualType T) {
1142 return CGObjCGNU::GetEHType(T);
1150 llvm::Constant *IDEHType =
1151 CGM.
getModule().getGlobalVariable(
"__objc_id_type_info");
1154 new llvm::GlobalVariable(CGM.
getModule(), PtrToInt8Ty,
1157 nullptr,
"__objc_id_type_info");
1158 return llvm::ConstantExpr::getBitCast(IDEHType, PtrToInt8Ty);
1163 assert(PT &&
"Invalid @catch type.");
1165 assert(IT &&
"Invalid @catch type.");
1168 std::string typeinfoName =
"__objc_eh_typeinfo_" + className;
1171 llvm::Constant *typeinfo = TheModule.getGlobalVariable(typeinfoName);
1173 return llvm::ConstantExpr::getBitCast(typeinfo, PtrToInt8Ty);
1180 const char *vtableName =
"_ZTVN7gnustep7libobjc22__objc_class_type_infoE";
1181 auto *Vtable = TheModule.getGlobalVariable(vtableName);
1183 Vtable =
new llvm::GlobalVariable(TheModule, PtrToInt8Ty,
true,
1185 nullptr, vtableName);
1187 llvm::Constant *Two = llvm::ConstantInt::get(IntTy, 2);
1188 auto *BVtable = llvm::ConstantExpr::getBitCast(
1189 llvm::ConstantExpr::getGetElementPtr(Vtable->getValueType(), Vtable, Two),
1192 llvm::Constant *typeName =
1193 ExportUniqueString(className,
"__objc_eh_typename_");
1197 fields.add(BVtable);
1198 fields.add(typeName);
1199 llvm::Constant *TI =
1200 fields.finishAndCreateGlobal(
"__objc_eh_typeinfo_" + className,
1203 llvm::GlobalValue::LinkOnceODRLinkage);
1204 return llvm::ConstantExpr::getBitCast(TI, PtrToInt8Ty);
1210 std::string Str = SL->
getString().str();
1214 llvm::StringMap<llvm::Constant*>::iterator old = ObjCStrings.find(Str);
1215 if (old != ObjCStrings.end())
1220 if (StringClass.empty()) StringClass =
"NXConstantString";
1222 std::string Sym =
"_OBJC_CLASS_";
1225 llvm::Constant *
isa = TheModule.getNamedGlobal(Sym);
1228 isa =
new llvm::GlobalVariable(TheModule, IdTy,
false,
1229 llvm::GlobalValue::ExternalWeakLinkage,
nullptr, Sym);
1230 else if (isa->getType() != PtrToIdTy)
1231 isa = llvm::ConstantExpr::getBitCast(isa, PtrToIdTy);
1236 Fields.add(MakeConstantString(Str));
1237 Fields.addInt(IntTy, Str.size());
1238 llvm::Constant *ObjCStr =
1240 ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStr, PtrToInt8Ty);
1241 ObjCStrings[Str] = ObjCStr;
1242 ConstantStrings.push_back(ObjCStr);
1255 bool isCategoryImpl,
1257 bool IsClassMessage,
1262 if (Sel == RetainSel || Sel == AutoreleaseSel) {
1266 if (Sel == ReleaseSel) {
1274 ActualArgs.
add(
RValue::get(EnforceType(Builder, Receiver, IdTy)), ASTIdTy);
1278 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
1281 if (isCategoryImpl) {
1282 llvm::Constant *classLookupFunction =
nullptr;
1283 if (IsClassMessage) {
1285 IdTy, PtrTy,
true),
"objc_get_meta_class");
1288 IdTy, PtrTy,
true),
"objc_get_class");
1290 ReceiverClass = Builder.CreateCall(classLookupFunction,
1298 if (IsClassMessage) {
1299 if (!MetaClassPtrAlias) {
1304 ReceiverClass = MetaClassPtrAlias;
1306 if (!ClassPtrAlias) {
1311 ReceiverClass = ClassPtrAlias;
1315 llvm::Type *CastTy = llvm::StructType::get(IdTy, IdTy);
1317 llvm::PointerType::getUnqual(CastTy));
1324 llvm::StructType *ObjCSuperTy =
1325 llvm::StructType::get(Receiver->getType(), IdTy);
1336 ObjCSuper = EnforceType(Builder, ObjCSuper, PtrToObjCSuperTy);
1339 llvm::Value *imp = LookupIMPSuper(CGF, ObjCSuper, cmd, MSI);
1340 imp = EnforceType(Builder, imp, MSI.MessengerType);
1342 llvm::Metadata *impMD[] = {
1343 llvm::MDString::get(VMContext, Sel.
getAsString()),
1345 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
1346 llvm::Type::getInt1Ty(VMContext), IsClassMessage))};
1347 llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD);
1351 llvm::Instruction *call;
1352 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
1353 call->setMetadata(msgSendMDKind, node);
1371 if (Sel == RetainSel || Sel == AutoreleaseSel) {
1375 if (Sel == ReleaseSel) {
1394 llvm::BasicBlock *startBB =
nullptr;
1395 llvm::BasicBlock *messageBB =
nullptr;
1396 llvm::BasicBlock *continueBB =
nullptr;
1398 if (!isPointerSizedReturn) {
1399 startBB = Builder.GetInsertBlock();
1403 llvm::Value *isNil = Builder.CreateICmpEQ(Receiver,
1404 llvm::Constant::getNullValue(Receiver->getType()));
1405 Builder.CreateCondBr(isNil, continueBB, messageBB);
1412 cmd = GetSelector(CGF, Method);
1414 cmd = GetSelector(CGF, Sel);
1415 cmd = EnforceType(Builder, cmd, SelectorTy);
1416 Receiver = EnforceType(Builder, Receiver, IdTy);
1418 llvm::Metadata *impMD[] = {
1419 llvm::MDString::get(VMContext, Sel.
getAsString()),
1420 llvm::MDString::get(VMContext, Class ? Class->
getNameAsString() :
""),
1421 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
1422 llvm::Type::getInt1Ty(VMContext), Class !=
nullptr))};
1423 llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD);
1430 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
1440 imp = LookupIMP(CGF, Receiver, cmd, node, MSI);
1446 "objc_msgSend_fpret");
1451 "objc_msgSend_stret");
1461 imp = EnforceType(Builder, imp, MSI.MessengerType);
1463 llvm::Instruction *call;
1465 RValue msgRet = CGF.
EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
1466 call->setMetadata(msgSendMDKind, node);
1469 if (!isPointerSizedReturn) {
1470 messageBB = CGF.
Builder.GetInsertBlock();
1471 CGF.
Builder.CreateBr(continueBB);
1475 llvm::PHINode *phi = Builder.CreatePHI(v->getType(), 2);
1476 phi->addIncoming(v, messageBB);
1477 phi->addIncoming(llvm::Constant::getNullValue(v->getType()), startBB);
1481 llvm::PHINode *phi = Builder.CreatePHI(v.
getType(), 2);
1484 CGF.
InitTempAlloca(NullVal, llvm::Constant::getNullValue(RetTy));
1486 phi->addIncoming(NullVal.
getPointer(), startBB);
1490 llvm::PHINode *phi = Builder.CreatePHI(v.first->getType(), 2);
1491 phi->addIncoming(v.first, messageBB);
1492 phi->addIncoming(llvm::Constant::getNullValue(v.first->getType()),
1494 llvm::PHINode *phi2 = Builder.CreatePHI(v.second->getType(), 2);
1495 phi2->addIncoming(v.second, messageBB);
1496 phi2->addIncoming(llvm::Constant::getNullValue(v.second->getType()),
1506 llvm::Constant *CGObjCGNU::
1507 GenerateMethodList(StringRef ClassName,
1508 StringRef CategoryName,
1511 bool isClassMethodList) {
1512 if (MethodSels.empty())
1518 MethodList.addNullPointer(CGM.
Int8PtrTy);
1519 MethodList.addInt(Int32Ty, MethodTypes.size());
1522 llvm::StructType *ObjCMethodTy =
1528 auto Methods = MethodList.beginArray();
1529 for (
unsigned int i = 0, e = MethodTypes.size(); i < e; ++i) {
1530 llvm::Constant *FnPtr =
1533 isClassMethodList));
1534 assert(FnPtr &&
"Can't generate metadata for method that doesn't exist");
1535 auto Method = Methods.beginStruct(ObjCMethodTy);
1537 Method.
add(MethodTypes[i]);
1538 Method.addBitCast(FnPtr, IMPTy);
1539 Method.finishAndAddTo(Methods);
1541 Methods.finishAndAddTo(MethodList);
1544 return MethodList.finishAndCreateGlobal(
".objc_method_list",
1549 llvm::Constant *CGObjCGNU::
1553 if (IvarNames.empty())
1560 IvarList.addInt(IntTy, (
int)IvarNames.size());
1563 llvm::StructType *ObjCIvarTy =
1564 llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, IntTy);
1567 auto Ivars = IvarList.beginArray(ObjCIvarTy);
1568 for (
unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {
1569 auto Ivar = Ivars.beginStruct(ObjCIvarTy);
1570 Ivar.add(IvarNames[i]);
1571 Ivar.add(IvarTypes[i]);
1572 Ivar.add(IvarOffsets[i]);
1573 Ivar.finishAndAddTo(Ivars);
1575 Ivars.finishAndAddTo(IvarList);
1578 return IvarList.finishAndCreateGlobal(
".objc_ivar_list",
1583 llvm::Constant *CGObjCGNU::GenerateClassStructure(
1584 llvm::Constant *MetaClass,
1585 llvm::Constant *SuperClass,
1588 llvm::Constant *Version,
1589 llvm::Constant *InstanceSize,
1590 llvm::Constant *IVars,
1591 llvm::Constant *Methods,
1592 llvm::Constant *Protocols,
1593 llvm::Constant *IvarOffsets,
1594 llvm::Constant *Properties,
1595 llvm::Constant *StrongIvarBitmap,
1596 llvm::Constant *WeakIvarBitmap,
1605 llvm::StructType *ClassTy = llvm::StructType::get(
1622 IvarOffsets->getType(),
1623 Properties->getType(),
1629 auto Elements = Builder.beginStruct(ClassTy);
1634 Elements.addBitCast(MetaClass, PtrToInt8Ty);
1636 Elements.add(SuperClass);
1638 Elements.add(MakeConstantString(Name,
".class_name"));
1640 Elements.addInt(LongTy, 0);
1642 Elements.addInt(LongTy, info);
1645 llvm::DataLayout td(&TheModule);
1646 Elements.addInt(LongTy,
1647 td.getTypeSizeInBits(ClassTy) /
1650 Elements.add(InstanceSize);
1652 Elements.add(IVars);
1654 Elements.add(Methods);
1657 Elements.add(NULLPtr);
1659 Elements.add(NULLPtr);
1661 Elements.add(NULLPtr);
1663 Elements.addBitCast(Protocols, PtrTy);
1665 Elements.add(NULLPtr);
1667 Elements.addInt(LongTy, 1);
1669 Elements.add(IvarOffsets);
1671 Elements.add(Properties);
1673 Elements.add(StrongIvarBitmap);
1675 Elements.add(WeakIvarBitmap);
1680 std::string ClassSym((isMeta ?
"_OBJC_METACLASS_":
"_OBJC_CLASS_") +
1682 llvm::GlobalVariable *ClassRef = TheModule.getNamedGlobal(ClassSym);
1683 llvm::Constant *Class =
1684 Elements.finishAndCreateGlobal(ClassSym, CGM.
getPointerAlign(),
false,
1687 ClassRef->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(Class,
1688 ClassRef->getType()));
1689 ClassRef->removeFromParent();
1690 Class->setName(ClassSym);
1695 llvm::Constant *CGObjCGNU::
1699 llvm::StructType *ObjCMethodDescTy =
1700 llvm::StructType::get(CGM.
getLLVMContext(), { PtrToInt8Ty, PtrToInt8Ty });
1702 auto MethodList = Builder.beginStruct();
1703 MethodList.addInt(IntTy, MethodNames.size());
1704 auto Methods = MethodList.beginArray(ObjCMethodDescTy);
1705 for (
unsigned int i = 0, e = MethodTypes.size() ; i < e ; i++) {
1706 auto Method = Methods.beginStruct(ObjCMethodDescTy);
1707 Method.
add(MethodNames[i]);
1708 Method.
add(MethodTypes[i]);
1709 Method.finishAndAddTo(Methods);
1711 Methods.finishAndAddTo(MethodList);
1712 return MethodList.finishAndCreateGlobal(
".objc_method_list",
1722 ProtocolList.add(NULLPtr);
1723 ProtocolList.addInt(LongTy, Protocols.size());
1725 auto Elements = ProtocolList.beginArray(PtrToInt8Ty);
1726 for (
const std::string *iter = Protocols.begin(), *endIter = Protocols.end();
1727 iter != endIter ; iter++) {
1728 llvm::Constant *protocol =
nullptr;
1729 llvm::StringMap<llvm::Constant*>::iterator value =
1730 ExistingProtocols.find(*iter);
1731 if (value == ExistingProtocols.end()) {
1732 protocol = GenerateEmptyProtocol(*iter);
1734 protocol = value->getValue();
1736 Elements.addBitCast(protocol, PtrToInt8Ty);
1738 Elements.finishAndAddTo(ProtocolList);
1739 return ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
1752 CGObjCGNU::GenerateEmptyProtocol(
const std::string &ProtocolName) {
1753 llvm::Constant *ProtocolList = GenerateProtocolList({});
1754 llvm::Constant *MethodList = GenerateProtocolMethodList({}, {});
1758 auto Elements = Builder.beginStruct();
1762 Elements.add(llvm::ConstantExpr::getIntToPtr(
1763 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
1765 Elements.add(MakeConstantString(ProtocolName,
".objc_protocol_name"));
1766 Elements.add(ProtocolList);
1767 Elements.add(MethodList);
1768 Elements.add(MethodList);
1769 Elements.add(MethodList);
1770 Elements.add(MethodList);
1771 return Elements.finishAndCreateGlobal(
".objc_protocol",
1785 Protocols.push_back(PI->getNameAsString());
1793 OptionalInstanceMethodNames.push_back(
1794 MakeConstantString(I->getSelector().getAsString()));
1795 OptionalInstanceMethodTypes.push_back(MakeConstantString(TypeStr));
1797 InstanceMethodNames.push_back(
1798 MakeConstantString(I->getSelector().getAsString()));
1799 InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
1810 OptionalClassMethodNames.push_back(
1811 MakeConstantString(I->getSelector().getAsString()));
1812 OptionalClassMethodTypes.push_back(MakeConstantString(TypeStr));
1814 ClassMethodNames.push_back(
1815 MakeConstantString(I->getSelector().getAsString()));
1816 ClassMethodTypes.push_back(MakeConstantString(TypeStr));
1820 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
1821 llvm::Constant *InstanceMethodList =
1822 GenerateProtocolMethodList(InstanceMethodNames, InstanceMethodTypes);
1823 llvm::Constant *ClassMethodList =
1824 GenerateProtocolMethodList(ClassMethodNames, ClassMethodTypes);
1825 llvm::Constant *OptionalInstanceMethodList =
1826 GenerateProtocolMethodList(OptionalInstanceMethodNames,
1827 OptionalInstanceMethodTypes);
1828 llvm::Constant *OptionalClassMethodList =
1829 GenerateProtocolMethodList(OptionalClassMethodNames,
1830 OptionalClassMethodTypes);
1838 llvm::Constant *PropertyList;
1839 llvm::Constant *OptionalPropertyList;
1841 llvm::StructType *propertyMetadataTy =
1843 { PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty,
1844 PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty });
1846 unsigned numReqProperties = 0, numOptProperties = 0;
1855 auto reqPropertiesList = reqPropertyListBuilder.
beginStruct();
1856 reqPropertiesList.addInt(IntTy, numReqProperties);
1857 reqPropertiesList.add(NULLPtr);
1858 auto reqPropertiesArray = reqPropertiesList.beginArray(propertyMetadataTy);
1861 auto optPropertiesList = optPropertyListBuilder.
beginStruct();
1862 optPropertiesList.addInt(IntTy, numOptProperties);
1863 optPropertiesList.add(NULLPtr);
1864 auto optPropertiesArray = optPropertiesList.beginArray(propertyMetadataTy);
1869 auto &propertiesArray =
1870 (
property->isOptional() ? optPropertiesArray : reqPropertiesArray);
1871 auto fields = propertiesArray.beginStruct(propertyMetadataTy);
1873 fields.add(MakePropertyEncodingString(property,
nullptr));
1874 PushPropertyAttributes(fields, property);
1878 llvm::Constant *typeEncoding = MakeConstantString(typeStr);
1879 InstanceMethodTypes.push_back(typeEncoding);
1880 fields.add(MakeConstantString(getter->getSelector().getAsString()));
1881 fields.add(typeEncoding);
1883 fields.add(NULLPtr);
1884 fields.add(NULLPtr);
1888 llvm::Constant *typeEncoding = MakeConstantString(typeStr);
1889 InstanceMethodTypes.push_back(typeEncoding);
1890 fields.add(MakeConstantString(setter->getSelector().getAsString()));
1891 fields.add(typeEncoding);
1893 fields.add(NULLPtr);
1894 fields.add(NULLPtr);
1897 fields.finishAndAddTo(propertiesArray);
1900 reqPropertiesArray.finishAndAddTo(reqPropertiesList);
1902 reqPropertiesList.finishAndCreateGlobal(
".objc_property_list",
1905 optPropertiesArray.finishAndAddTo(optPropertiesList);
1906 OptionalPropertyList =
1907 optPropertiesList.finishAndCreateGlobal(
".objc_property_list",
1918 llvm::ConstantExpr::getIntToPtr(
1919 llvm::ConstantInt::get(Int32Ty, ProtocolVersion), IdTy));
1921 MakeConstantString(ProtocolName,
".objc_protocol_name"));
1922 Elements.add(ProtocolList);
1923 Elements.add(InstanceMethodList);
1924 Elements.add(ClassMethodList);
1925 Elements.add(OptionalInstanceMethodList);
1926 Elements.add(OptionalClassMethodList);
1927 Elements.add(PropertyList);
1928 Elements.add(OptionalPropertyList);
1929 ExistingProtocols[ProtocolName] =
1930 llvm::ConstantExpr::getBitCast(
1931 Elements.finishAndCreateGlobal(
".objc_protocol", CGM.
getPointerAlign()),
1934 void CGObjCGNU::GenerateProtocolHolderCategory() {
1942 const std::string ClassName =
"__ObjC_Protocol_Holder_Ugly_Hack";
1943 const std::string CategoryName =
"AnotherHack";
1944 Elements.add(MakeConstantString(CategoryName));
1945 Elements.add(MakeConstantString(ClassName));
1947 Elements.addBitCast(GenerateMethodList(
1948 ClassName, CategoryName, MethodSels, MethodTypes,
false), PtrTy);
1950 Elements.addBitCast(GenerateMethodList(
1951 ClassName, CategoryName, MethodSels, MethodTypes,
true), PtrTy);
1955 auto ProtocolList = ProtocolListBuilder.
beginStruct();
1956 ProtocolList.add(NULLPtr);
1957 ProtocolList.addInt(LongTy, ExistingProtocols.size());
1958 auto ProtocolElements = ProtocolList.beginArray(PtrTy);
1959 for (
auto iter = ExistingProtocols.begin(), endIter = ExistingProtocols.end();
1960 iter != endIter ; iter++) {
1961 ProtocolElements.addBitCast(iter->getValue(), PtrTy);
1963 ProtocolElements.finishAndAddTo(ProtocolList);
1964 Elements.addBitCast(
1965 ProtocolList.finishAndCreateGlobal(
".objc_protocol_list",
1968 Categories.push_back(llvm::ConstantExpr::getBitCast(
1985 int bitCount = bits.size();
1987 if (bitCount < ptrBits) {
1989 for (
int i=0 ; i<bitCount ; ++i) {
1990 if (bits[i]) val |= 1ULL<<(i+1);
1992 return llvm::ConstantInt::get(IntPtrTy, val);
1996 while (v < bitCount) {
1998 for (
int i=0 ; (i<32) && (v<bitCount) ; ++i) {
1999 if (bits[v]) word |= 1<<i;
2002 values.push_back(llvm::ConstantInt::get(Int32Ty, word));
2007 fields.addInt(Int32Ty, values.size());
2008 auto array = fields.beginArray();
2009 for (
auto v : values) array.add(v);
2010 array.finishAndAddTo(fields);
2012 llvm::Constant *GS =
2014 llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy);
2025 InstanceMethodSels.push_back(I->getSelector());
2027 InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
2034 ClassMethodSels.push_back(I->getSelector());
2036 ClassMethodTypes.push_back(MakeConstantString(TypeStr));
2044 E = Protos.
end(); I != E; ++I)
2045 Protocols.push_back((*I)->getNameAsString());
2049 Elements.add(MakeConstantString(CategoryName));
2050 Elements.add(MakeConstantString(ClassName));
2052 Elements.addBitCast(
2053 GenerateMethodList(ClassName, CategoryName, InstanceMethodSels,
2054 InstanceMethodTypes,
false),
2057 Elements.addBitCast(
2058 GenerateMethodList(ClassName, CategoryName, ClassMethodSels,
2059 ClassMethodTypes,
true),
2062 Elements.addBitCast(GenerateProtocolList(Protocols), PtrTy);
2063 Categories.push_back(llvm::ConstantExpr::getBitCast(
2074 llvm::StructType *propertyMetadataTy =
2076 { PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty,
2077 PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty });
2079 unsigned numProperties = 0;
2081 (void) propertyImpl;
2087 propertyList.addInt(IntTy, numProperties);
2088 propertyList.add(NULLPtr);
2089 auto properties = propertyList.beginArray(propertyMetadataTy);
2094 auto fields = properties.beginStruct(propertyMetadataTy);
2096 bool isSynthesized = (propertyImpl->getPropertyImplementation() ==
2098 bool isDynamic = (propertyImpl->getPropertyImplementation() ==
2101 fields.add(MakePropertyEncodingString(property, OID));
2102 PushPropertyAttributes(fields, property, isSynthesized, isDynamic);
2105 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
2106 if (isSynthesized) {
2107 InstanceMethodTypes.push_back(TypeEncoding);
2108 InstanceMethodSels.push_back(getter->getSelector());
2110 fields.add(MakeConstantString(getter->getSelector().getAsString()));
2111 fields.add(TypeEncoding);
2113 fields.add(NULLPtr);
2114 fields.add(NULLPtr);
2118 llvm::Constant *TypeEncoding = MakeConstantString(TypeStr);
2119 if (isSynthesized) {
2120 InstanceMethodTypes.push_back(TypeEncoding);
2121 InstanceMethodSels.push_back(setter->getSelector());
2123 fields.add(MakeConstantString(setter->getSelector().getAsString()));
2124 fields.add(TypeEncoding);
2126 fields.add(NULLPtr);
2127 fields.add(NULLPtr);
2129 fields.finishAndAddTo(properties);
2131 properties.finishAndAddTo(propertyList);
2133 return propertyList.finishAndCreateGlobal(
".objc_property_list",
2151 std::string SuperClassName;
2152 if (SuperClassDecl) {
2154 EmitClassRef(SuperClassName);
2164 std::string classSymbolName =
"__objc_class_name_" + ClassName;
2165 if (
auto *symbol = TheModule.getGlobalVariable(classSymbolName)) {
2166 symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0));
2168 new llvm::GlobalVariable(TheModule, LongTy,
false,
2170 llvm::ConstantInt::get(LongTy, 0),
2184 auto IvarOffsetValues = IvarOffsetBuilder.
beginArray(PtrToIntTy);
2188 int superInstanceSize = !SuperClassDecl ? 0 :
2193 instanceSize = 0 - (instanceSize - superInstanceSize);
2199 IvarNames.push_back(MakeConstantString(IVD->getNameAsString()));
2201 std::string TypeStr;
2203 IvarTypes.push_back(MakeConstantString(TypeStr));
2205 uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
2206 uint64_t
Offset = BaseOffset;
2208 Offset = BaseOffset - superInstanceSize;
2210 llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
2212 std::string OffsetName =
"__objc_ivar_offset_value_" + ClassName +
"." +
2213 IVD->getNameAsString();
2214 llvm::GlobalVariable *OffsetVar = TheModule.getGlobalVariable(OffsetName);
2216 OffsetVar->setInitializer(OffsetValue);
2222 OffsetVar =
new llvm::GlobalVariable(TheModule, IntTy,
2225 "__objc_ivar_offset_value_" + ClassName +
"." +
2226 IVD->getNameAsString());
2227 IvarOffsets.push_back(OffsetValue);
2228 IvarOffsetValues.add(OffsetVar);
2232 StrongIvars.push_back(
true);
2233 WeakIvars.push_back(
false);
2236 StrongIvars.push_back(
false);
2237 WeakIvars.push_back(
true);
2240 StrongIvars.push_back(
false);
2241 WeakIvars.push_back(
false);
2244 llvm::Constant *StrongIvarBitmap = MakeBitField(StrongIvars);
2245 llvm::Constant *WeakIvarBitmap = MakeBitField(WeakIvars);
2246 llvm::GlobalVariable *IvarOffsetArray =
2247 IvarOffsetValues.finishAndCreateGlobal(
".ivar.offsets",
2254 InstanceMethodSels.push_back(I->getSelector());
2256 InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
2259 llvm::Constant *Properties = GeneratePropertyList(OID, InstanceMethodSels,
2260 InstanceMethodTypes);
2266 ClassMethodSels.push_back(I->getSelector());
2268 ClassMethodTypes.push_back(MakeConstantString(TypeStr));
2272 for (
const auto *I : ClassDecl->
protocols())
2273 Protocols.push_back(I->getNameAsString());
2276 llvm::Constant *SuperClass;
2277 if (!SuperClassName.empty()) {
2278 SuperClass = MakeConstantString(SuperClassName,
".super_class_name");
2280 SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty);
2285 llvm::Constant *MethodList = GenerateMethodList(ClassName,
"",
2286 InstanceMethodSels, InstanceMethodTypes,
false);
2287 llvm::Constant *ClassMethodList = GenerateMethodList(ClassName,
"",
2288 ClassMethodSels, ClassMethodTypes,
true);
2289 llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
2302 llvm::Constant *offsetPointerIndexes[] = {Zeros[0],
2303 llvm::ConstantInt::get(IndexTy, 1),
nullptr,
2304 llvm::ConstantInt::get(IndexTy, 2) };
2306 unsigned ivarIndex = 0;
2309 const std::string Name =
"__objc_ivar_offset_" + ClassName +
'.' 2310 + IVD->getNameAsString();
2311 offsetPointerIndexes[2] = llvm::ConstantInt::get(IndexTy, ivarIndex);
2313 llvm::Constant *offsetValue = llvm::ConstantExpr::getGetElementPtr(
2314 cast<llvm::GlobalVariable>(IvarList)->getValueType(), IvarList,
2315 offsetPointerIndexes);
2317 llvm::GlobalVariable *offset = TheModule.getNamedGlobal(Name);
2319 offset->setInitializer(offsetValue);
2326 offset =
new llvm::GlobalVariable(TheModule, offsetValue->getType(),
2332 llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0);
2335 llvm::Constant *MetaClassStruct = GenerateClassStructure(
2336 NULLPtr, NULLPtr, 0x12L, ClassName.c_str(),
nullptr, Zeros[0],
2337 GenerateIvarList(empty, empty, empty), ClassMethodList, NULLPtr, NULLPtr,
2338 NULLPtr, ZeroPtr, ZeroPtr,
true);
2339 if (CGM.
getTriple().isOSBinFormatCOFF()) {
2340 auto Storage = llvm::GlobalValue::DefaultStorageClass;
2342 Storage = llvm::GlobalValue::DLLImportStorageClass;
2344 Storage = llvm::GlobalValue::DLLExportStorageClass;
2345 cast<llvm::GlobalValue>(MetaClassStruct)->setDLLStorageClass(Storage);
2349 llvm::Constant *ClassStruct = GenerateClassStructure(
2350 MetaClassStruct, SuperClass, 0x11L, ClassName.c_str(),
nullptr,
2351 llvm::ConstantInt::get(LongTy, instanceSize), IvarList, MethodList,
2352 GenerateProtocolList(Protocols), IvarOffsetArray, Properties,
2353 StrongIvarBitmap, WeakIvarBitmap);
2354 if (CGM.
getTriple().isOSBinFormatCOFF()) {
2355 auto Storage = llvm::GlobalValue::DefaultStorageClass;
2357 Storage = llvm::GlobalValue::DLLImportStorageClass;
2359 Storage = llvm::GlobalValue::DLLExportStorageClass;
2360 cast<llvm::GlobalValue>(ClassStruct)->setDLLStorageClass(Storage);
2364 if (ClassPtrAlias) {
2365 ClassPtrAlias->replaceAllUsesWith(
2366 llvm::ConstantExpr::getBitCast(ClassStruct, IdTy));
2367 ClassPtrAlias->eraseFromParent();
2368 ClassPtrAlias =
nullptr;
2370 if (MetaClassPtrAlias) {
2371 MetaClassPtrAlias->replaceAllUsesWith(
2372 llvm::ConstantExpr::getBitCast(MetaClassStruct, IdTy));
2373 MetaClassPtrAlias->eraseFromParent();
2374 MetaClassPtrAlias =
nullptr;
2378 ClassStruct = llvm::ConstantExpr::getBitCast(ClassStruct, PtrToInt8Ty);
2379 Classes.push_back(ClassStruct);
2382 llvm::Function *CGObjCGNU::ModuleInitFunction() {
2384 if (Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
2389 GenerateProtocolHolderCategory();
2391 llvm::StructType *selStructTy =
2392 dyn_cast<llvm::StructType>(SelectorTy->getElementType());
2396 { PtrToInt8Ty, PtrToInt8Ty });
2397 selStructPtrTy = llvm::PointerType::getUnqual(selStructTy);
2401 llvm::Constant *statics = NULLPtr;
2402 if (!ConstantStrings.empty()) {
2403 llvm::GlobalVariable *fileStatics = [&] {
2408 if (stringClass.empty()) stringClass =
"NXConstantString";
2409 staticsStruct.add(MakeConstantString(stringClass,
2410 ".objc_static_class_name"));
2412 auto array = staticsStruct.beginArray();
2413 array.addAll(ConstantStrings);
2415 array.finishAndAddTo(staticsStruct);
2417 return staticsStruct.finishAndCreateGlobal(
".objc_statics",
2422 auto allStaticsArray = builder.
beginArray(fileStatics->getType());
2423 allStaticsArray.add(fileStatics);
2424 allStaticsArray.addNullPointer(fileStatics->getType());
2426 statics = allStaticsArray.finishAndCreateGlobal(
".objc_statics_ptr",
2428 statics = llvm::ConstantExpr::getBitCast(statics, PtrTy);
2434 unsigned selectorCount;
2437 llvm::GlobalVariable *selectorList = [&] {
2439 auto selectors = builder.
beginArray(selStructTy);
2441 for (
auto &entry : table) {
2443 std::string selNameStr = entry.first.getAsString();
2444 llvm::Constant *selName = ExportUniqueString(selNameStr,
".objc_sel_name");
2446 for (TypedSelector &sel : entry.second) {
2447 llvm::Constant *selectorTypeEncoding = NULLPtr;
2448 if (!sel.first.empty())
2449 selectorTypeEncoding =
2450 MakeConstantString(sel.first,
".objc_sel_types");
2452 auto selStruct = selectors.beginStruct(selStructTy);
2453 selStruct.add(selName);
2454 selStruct.add(selectorTypeEncoding);
2455 selStruct.finishAndAddTo(selectors);
2458 selectorAliases.push_back(sel.second);
2463 selectorCount = selectors.size();
2469 auto selStruct = selectors.beginStruct(selStructTy);
2470 selStruct.add(NULLPtr);
2471 selStruct.add(NULLPtr);
2472 selStruct.finishAndAddTo(selectors);
2474 return selectors.finishAndCreateGlobal(
".objc_selector_list",
2479 for (
unsigned i = 0; i < selectorCount; ++i) {
2480 llvm::Constant *idxs[] = {
2482 llvm::ConstantInt::get(Int32Ty, i)
2485 llvm::Constant *selPtr = llvm::ConstantExpr::getGetElementPtr(
2486 selectorList->getValueType(), selectorList, idxs);
2489 selPtr = llvm::ConstantExpr::getBitCast(selPtr, SelectorTy);
2490 selectorAliases[i]->replaceAllUsesWith(selPtr);
2491 selectorAliases[i]->eraseFromParent();
2494 llvm::GlobalVariable *symtab = [&] {
2499 symtab.addInt(LongTy, selectorCount);
2501 symtab.addBitCast(selectorList, selStructPtrTy);
2504 symtab.addInt(CGM.
Int16Ty, Classes.size());
2506 symtab.addInt(CGM.
Int16Ty, Categories.size());
2509 auto classList = symtab.beginArray(PtrToInt8Ty);
2510 classList.addAll(Classes);
2511 classList.addAll(Categories);
2513 classList.add(statics);
2514 classList.add(NULLPtr);
2515 classList.finishAndAddTo(symtab);
2523 llvm::Constant *module = [&] {
2525 LongTy, LongTy, PtrToInt8Ty, symtab->getType(), IntTy
2527 llvm::StructType *moduleTy =
2529 makeArrayRef(moduleEltTys).drop_back(
unsigned(RuntimeVersion < 10)));
2532 auto module = builder.beginStruct(moduleTy);
2534 module.addInt(LongTy, RuntimeVersion);
2536 module.addInt(LongTy, CGM.
getDataLayout().getTypeStoreSize(moduleTy));
2543 module.add(MakeConstantString(path,
".objc_source_file_name"));
2546 if (RuntimeVersion >= 10) {
2549 module.addInt(IntTy, 2);
2553 module.addInt(IntTy, 1);
2555 module.addInt(IntTy, 0);
2558 module.addInt(IntTy, 1);
2569 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false),
2572 llvm::BasicBlock *EntryBB =
2575 Builder.SetInsertPoint(EntryBB);
2577 llvm::FunctionType *FT =
2578 llvm::FunctionType::get(Builder.getVoidTy(), module->getType(),
true);
2580 Builder.CreateCall(Register, module);
2582 if (!ClassAliases.empty()) {
2583 llvm::Type *ArgTypes[2] = {PtrTy, PtrToInt8Ty};
2584 llvm::FunctionType *RegisterAliasTy =
2585 llvm::FunctionType::get(Builder.getVoidTy(),
2589 llvm::GlobalValue::ExternalWeakLinkage,
"class_registerAlias_np",
2591 llvm::BasicBlock *AliasBB =
2593 llvm::BasicBlock *NoAliasBB =
2597 llvm::Value *HasRegisterAlias = Builder.CreateICmpNE(RegisterAlias,
2598 llvm::Constant::getNullValue(RegisterAlias->getType()));
2599 Builder.CreateCondBr(HasRegisterAlias, AliasBB, NoAliasBB);
2602 Builder.SetInsertPoint(AliasBB);
2604 for (std::vector<ClassAliasPair>::iterator iter = ClassAliases.begin();
2605 iter != ClassAliases.end(); ++iter) {
2606 llvm::Constant *TheClass =
2607 TheModule.getGlobalVariable(
"_OBJC_CLASS_" + iter->first,
true);
2609 TheClass = llvm::ConstantExpr::getBitCast(TheClass, PtrTy);
2610 Builder.CreateCall(RegisterAlias,
2611 {TheClass, MakeConstantString(iter->second)});
2615 Builder.CreateBr(NoAliasBB);
2618 Builder.SetInsertPoint(NoAliasBB);
2620 Builder.CreateRetVoid();
2622 return LoadFunction;
2625 llvm::Function *CGObjCGNU::GenerateMethod(
const ObjCMethodDecl *OMD,
2629 StringRef CategoryName = OCD ? OCD->
getName() :
"";
2630 StringRef ClassName = CD->
getName();
2635 llvm::FunctionType *MethodTy =
2638 MethodName, isClassMethod);
2640 llvm::Function *Method
2648 llvm::Constant *CGObjCGNU::GetPropertyGetFunction() {
2649 return GetPropertyFn;
2652 llvm::Constant *CGObjCGNU::GetPropertySetFunction() {
2653 return SetPropertyFn;
2656 llvm::Constant *CGObjCGNU::GetOptimizedPropertySetFunction(
bool atomic,
2661 llvm::Constant *CGObjCGNU::GetGetStructFunction() {
2662 return GetStructPropertyFn;
2665 llvm::Constant *CGObjCGNU::GetSetStructFunction() {
2666 return SetStructPropertyFn;
2669 llvm::Constant *CGObjCGNU::GetCppAtomicObjectGetFunction() {
2673 llvm::Constant *CGObjCGNU::GetCppAtomicObjectSetFunction() {
2677 llvm::Constant *CGObjCGNU::EnumerationMutationFunction() {
2678 return EnumerationMutationFn;
2683 EmitAtSynchronizedStmt(CGF, S, SyncEnterFn, SyncExitFn);
2700 EmitTryCatchStmt(CGF, S, EnterCatchFn, ExitCatchFn, ExceptionReThrowFn);
2705 bool ClearInsertionPoint) {
2710 ExceptionAsObject = Exception;
2713 "Unexpected rethrow outside @catch block.");
2717 llvm::CallSite Throw =
2719 Throw.setDoesNotReturn();
2720 CGF.
Builder.CreateUnreachable();
2721 if (ClearInsertionPoint)
2722 CGF.
Builder.ClearInsertionPoint();
2728 AddrWeakObj = EnforceType(B, AddrWeakObj, PtrToIdTy);
2729 return B.CreateCall(WeakReadFn.getType(), WeakReadFn,
2736 src = EnforceType(B, src, IdTy);
2737 dst = EnforceType(B, dst, PtrToIdTy);
2738 B.CreateCall(WeakAssignFn.getType(), WeakAssignFn,
2746 src = EnforceType(B, src, IdTy);
2747 dst = EnforceType(B, dst, PtrToIdTy);
2749 assert(!threadlocal &&
"EmitObjCGlobalAssign - Threal Local API NYI");
2750 B.CreateCall(GlobalAssignFn.getType(), GlobalAssignFn,
2758 src = EnforceType(B, src, IdTy);
2759 dst = EnforceType(B, dst, IdTy);
2760 B.CreateCall(IvarAssignFn.getType(), IvarAssignFn,
2767 src = EnforceType(B, src, IdTy);
2768 dst = EnforceType(B, dst, PtrToIdTy);
2769 B.CreateCall(StrongCastAssignFn.getType(), StrongCastAssignFn,
2778 DestPtr = EnforceType(B, DestPtr, PtrTy);
2779 SrcPtr = EnforceType(B, SrcPtr, PtrTy);
2781 B.CreateCall(MemMoveFn.getType(), MemMoveFn,
2785 llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
2788 const std::string Name =
"__objc_ivar_offset_" + ID->
getNameAsString()
2793 llvm::GlobalVariable *IvarOffsetPointer = TheModule.getNamedGlobal(Name);
2794 if (!IvarOffsetPointer) {
2806 const_cast<ObjCInterfaceDecl *>(ID)))
2807 Offset = ComputeIvarBaseOffset(CGM, ID, Ivar);
2809 llvm::ConstantInt *OffsetGuess = llvm::ConstantInt::get(Int32Ty, Offset,
2816 llvm::GlobalVariable *IvarOffsetGV =
new llvm::GlobalVariable(TheModule,
2818 llvm::GlobalValue::PrivateLinkage, OffsetGuess, Name+
".guess");
2819 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule,
2820 IvarOffsetGV->getType(),
false, llvm::GlobalValue::LinkOnceAnyLinkage,
2821 IvarOffsetGV, Name);
2823 IvarOffsetPointer =
new llvm::GlobalVariable(TheModule,
2824 llvm::Type::getInt32PtrTy(VMContext),
false,
2828 return IvarOffsetPointer;
2835 unsigned CVRQualifiers) {
2838 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
2839 EmitIvarOffset(CGF, ID, Ivar));
2867 if (RuntimeVersion < 10 ||
2869 return CGF.
Builder.CreateZExtOrBitCast(
2872 ObjCIvarOffsetVariable(Interface, Ivar),
2876 std::string name =
"__objc_ivar_offset_value_" +
2881 auto GV =
new llvm::GlobalVariable(TheModule, IntTy,
2882 false, llvm::GlobalValue::LinkOnceAnyLinkage,
2883 llvm::Constant::getNullValue(IntTy), name);
2888 if (Offset->getType() != PtrDiffTy)
2889 Offset = CGF.
Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
2892 uint64_t
Offset = ComputeIvarBaseOffset(CGF.
CGM, Interface, Ivar);
2893 return llvm::ConstantInt::get(PtrDiffTy, Offset,
true);
2900 return new CGObjCGNUstep(CGM);
2903 return new CGObjCGCC(CGM);
2906 return new CGObjCObjFW(CGM);
2912 llvm_unreachable(
"these runtimes are not GNU runtimes");
2914 llvm_unreachable(
"bad runtime");
const llvm::DataLayout & getDataLayout() const
ReturnValueSlot - Contains the address where the return value of a function can be stored...
const ObjCInterfaceType * getInterfaceType() const
If this pointer points to an Objective C @interface type, gets the type for that interface.
Defines the clang::ASTContext interface.
static std::string SymbolNameForMethod(StringRef ClassName, StringRef CategoryName, const Selector MethodName, bool isClassMethod)
CharUnits getIntAlign() const
External linkage, which indicates that the entity can be referred to from other translation units...
protocol_range protocols() const
Smart pointer class that efficiently represents Objective-C method names.
QualType getObjCIdType() const
Represents the Objective-CC id type.
A (possibly-)qualified type.
bool ReturnTypeUsesSRet(const CGFunctionInfo &FI)
Return true iff the given type uses 'sret' when used as a return type.
CodeGenTypes & getTypes()
Represents a version number in the form major[.minor[.subminor[.build]]].
const CodeGenOptions & getCodeGenOpts() const
Defines the clang::FileManager interface and associated types.
llvm::LLVMContext & getLLVMContext()
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
The standard implementation of ConstantInitBuilder used in Clang.
const ObjCProtocolList & getReferencedProtocols() const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Implements runtime-specific code generation functions.
Defines the SourceManager interface.
const ASTRecordLayout & getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const
Get or compute information about the layout of the specified Objective-C implementation.
Decl - This represents one declaration (or definition), e.g.
CharUnits getPointerSize() const
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
Represents Objective-C's @throw statement.
'gcc' is the Objective-C runtime shipped with GCC, implementing a fragile Objective-C ABI ...
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::Instruction **callOrInvoke, SourceLocation Loc)
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.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
const T * getAs() const
Member-template getAs<specific type>'.
llvm::GlobalVariable * finishAndCreateGlobal(As &&...args)
Given that this builder was created by beginning an array or struct directly on a ConstantInitBuilder...
ObjCMethodDecl - Represents an instance or class method declaration.
ObjCImplementationDecl * getObjCImplementation(ObjCInterfaceDecl *D)
Get the implementation of the ObjCInterfaceDecl D, or nullptr if none exists.
llvm::Value * getPointer() const
Defines the Objective-C statement AST node classes.
classmeth_range class_methods() const
protocol_range protocols() const
llvm::Value * EmitObjCThrowOperand(const Expr *expr)
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
instprop_range instance_properties() const
One of these records is kept for each identifier that is lexed.
'macosx-fragile' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the fragil...
This table allows us to fully hide how we implement multi-keyword caching.
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 isObjCIdType() const
static const ObjCInterfaceDecl * FindIvarInterface(ASTContext &Context, const ObjCInterfaceDecl *OID, const ObjCIvarDecl *OIVD)
instmeth_range instance_methods() const
ObjCMethodDecl * getSetterMethodDecl() const
virtual bool isDynamic(OpenMPScheduleClauseKind ScheduleKind) const
Check if the specified ScheduleKind is dynamic.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
const ASTRecordLayout & getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const
Get or compute information about the layout of the specified Objective-C interface.
void InitTempAlloca(Address Alloca, llvm::Value *Value)
InitTempAlloca - Provide an initial value for the given alloca which will be observable at all locati...
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
ObjCContainerDecl - Represents a container for method declarations.
const Expr * getThrowExpr() const
CharUnits - This is an opaque type for sizes expressed in character units.
CharUnits getAlignment() const
Return the alignment of this pointer.
Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
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.
CharUnits getPointerAlign() const
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
Represents an ObjC class declaration.
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface...
QualType getObjCProtoType() const
Retrieve the type of the Objective-C Protocol class.
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
std::string getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, bool Extended=false) const
Emit the encoded type for the method declaration Decl into S.
llvm::Constant * CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false)
Create a new runtime function with the specified type and name.
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
'watchos' is a variant of iOS for Apple's watchOS.
StringRef getString() const
void addFrom(const CallArgList &other)
Add all the arguments from another CallArgList to this one.
ASTContext & getContext() const
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...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Expr - This represents one expression.
'macosx' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the non-fragile AB...
llvm::StringRef getAsString(SyncScope S)
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
const FunctionProtoType * T
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
std::string getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD, const Decl *Container) const
getObjCEncodingForPropertyDecl - Return the encoded type for this method declaration.
llvm::PointerType * getType() const
Return the type of the pointer value.
DeclContext * getDeclContext()
Represents Objective-C's @synchronized statement.
ObjCInterfaceDecl * getSuperClass() const
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
void add(RValue rvalue, QualType type, bool needscopy=false)
clang::ObjCRuntime ObjCRuntime
propimpl_range property_impls() const
bool isa(CodeGen::Address addr)
bool isInstanceMethod() const
const TargetInfo & getTarget() const
Selector getSelector() const
'gnustep' is the modern non-fragile GNUstep runtime.
const LangOptions & getLangOpts() const
ASTContext & getContext() const
The l-value was considered opaque, so the alignment was determined from a type.
const DirectoryEntry * getDir() const
Return the directory the file lives in.
Address CreateBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
std::string getAsString() const
Derive the full selector name (e.g.
Assigning into this object requires the old value to be released and the new value to be retained...
bool ReturnTypeUsesFPRet(QualType ResultType)
Return true iff the given type uses 'fpret' when used as a return type.
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
static DeclContext * castToDeclContext(const TranslationUnitDecl *D)
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
StringRef getName() const
Interfaces are the core concept in Objective-C for object oriented design.
'objfw' is the Objective-C runtime included in ObjFW
SmallVector< llvm::Value *, 8 > ObjCEHValueStack
ObjCEHValueStack - Stack of Objective-C exception values, used for rethrows.
std::string getNameAsString() const
getNameAsString - Get a human-readable name for the declaration, even if it is one of the special kin...
llvm::CallSite EmitRuntimeCallOrInvoke(llvm::Value *callee, ArrayRef< llvm::Value *> args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
llvm::IntegerType * Int16Ty
ObjCCategoryDecl * getCategoryDecl() const
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
Cached information about one file (either on disk or in the virtual file system). ...
const CGFunctionInfo & arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD)
Objective-C methods are C functions with some implicit parameters.
ObjCCategoryDecl - Represents a category declaration.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isAnyPointerType() const
Represents one property declaration in an Objective-C interface.
All available information about a concrete callee.
const VersionTuple & getVersion() const
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
ConstantAddress GetAddrOfConstantCString(const std::string &Str, const char *GlobalName=nullptr)
Returns a pointer to a character array containing the literal and a terminating '\0' character...
StringRef getName() const
Return the actual identifier string.
ObjCIvarDecl * getNextIvar()
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
This class organizes the cross-function state that is used while generating LLVM code.
const ObjCInterfaceDecl * getClassInterface() const
Dataflow Directional Tag Classes.
CharUnits getSize() const
getSize - Get the record size in characters.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
The basic abstraction for the target Objective-C runtime.
Address CreateStructGEP(Address Addr, unsigned Index, CharUnits Offset, const llvm::Twine &Name="")
llvm::LoadInst * CreateAlignedLoad(llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
FileID getMainFileID() const
Returns the FileID of the main source file.
llvm::Constant * getPointer() const
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="")
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::Module & getModule() const
const ObjCInterfaceDecl * getClassInterface() const
'ios' is the Apple-provided NeXT-derived runtime on iOS or the iOS simulator; it is always non-fragil...
Represents a pointer to an Objective C object.
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
StructBuilder beginStruct(llvm::StructType *structTy=nullptr)
llvm::Type * getElementType() const
Return the type of the values stored in this address.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
This class organizes the cross-module state that is used while lowering AST types to LLVM types...
void getObjCEncodingForType(QualType T, std::string &S, const FieldDecl *Field=nullptr, QualType *NotEncodedT=nullptr) const
Emit the Objective-CC type encoding for the given type T into S.
llvm::PointerType * Int8PtrTy
bool isObjCQualifiedIdType() const
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
SourceManager & getSourceManager()
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
ArrayBuilder beginArray(llvm::Type *eltTy=nullptr)
Reading or writing from this object requires a barrier call.
TranslationUnitDecl * getTranslationUnitDecl() const
A specialization of Address that requires the address to be an LLVM Constant.
ObjCIvarDecl - Represents an ObjC instance variable.
A helper class of ConstantInitBuilder, used for building constant struct initializers.
Represents Objective-C's @try ... @catch ... @finally statement.
StringLiteral - This represents a string literal expression, e.g.
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
TranslationUnitDecl - The top declaration context.
static RValue get(llvm::Value *V)
llvm::Value * LoadObjCSelf()
LoadObjCSelf - Load the value of self.
std::string ObjCConstantStringClass
static RValue getAggregate(Address addr, bool isVolatile=false)
LValue - This represents an lvalue references.
ObjCMethodDecl * getGetterMethodDecl() const
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
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.
Abstract information about a function or function prototype.
ObjCCompatibleAliasDecl - Represents alias of a class.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PL, ArrayRef< Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
StringRef getName() const
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
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.
const llvm::Triple & getTriple() const