31#include "llvm/ADT/CachedHashString.h"
32#include "llvm/ADT/DenseSet.h"
33#include "llvm/ADT/SetVector.h"
34#include "llvm/ADT/SmallPtrSet.h"
35#include "llvm/ADT/SmallString.h"
36#include "llvm/IR/DataLayout.h"
37#include "llvm/IR/InlineAsm.h"
38#include "llvm/IR/IntrinsicInst.h"
39#include "llvm/IR/LLVMContext.h"
40#include "llvm/IR/Module.h"
41#include "llvm/Support/ScopedPrinter.h"
42#include "llvm/Support/raw_ostream.h"
54class ObjCCommonTypesHelper {
56 llvm::LLVMContext &VMContext;
66 llvm::FunctionCallee getMessageSendFn()
const {
69 llvm::Type *params[] = {ObjectPtrTy, SelectorPtrTy};
70 return CGM.CreateRuntimeFunction(
71 llvm::FunctionType::get(ObjectPtrTy, params,
true),
"objc_msgSend",
72 llvm::AttributeList::get(CGM.getLLVMContext(),
73 llvm::AttributeList::FunctionIndex,
74 llvm::Attribute::NonLazyBind));
82 llvm::FunctionCallee getMessageSendStretFn()
const {
83 llvm::Type *params[] = {ObjectPtrTy, SelectorPtrTy};
84 return CGM.CreateRuntimeFunction(
85 llvm::FunctionType::get(CGM.VoidTy, params,
true),
86 "objc_msgSend_stret");
94 llvm::FunctionCallee getMessageSendFpretFn()
const {
95 llvm::Type *params[] = {ObjectPtrTy, SelectorPtrTy};
96 return CGM.CreateRuntimeFunction(
97 llvm::FunctionType::get(CGM.DoubleTy, params,
true),
98 "objc_msgSend_fpret");
106 llvm::FunctionCallee getMessageSendFp2retFn()
const {
107 llvm::Type *params[] = {ObjectPtrTy, SelectorPtrTy};
108 llvm::Type *longDoubleType = llvm::Type::getX86_FP80Ty(VMContext);
109 llvm::Type *resultType =
110 llvm::StructType::get(longDoubleType, longDoubleType);
112 return CGM.CreateRuntimeFunction(
113 llvm::FunctionType::get(resultType, params,
true),
114 "objc_msgSend_fp2ret");
122 llvm::FunctionCallee getMessageSendSuperFn()
const {
123 llvm::Type *params[] = {SuperPtrTy, SelectorPtrTy};
124 return CGM.CreateRuntimeFunction(
125 llvm::FunctionType::get(ObjectPtrTy, params,
true),
126 "objc_msgSendSuper");
133 llvm::FunctionCallee getMessageSendSuperFn2()
const {
134 llvm::Type *params[] = {SuperPtrTy, SelectorPtrTy};
135 return CGM.CreateRuntimeFunction(
136 llvm::FunctionType::get(ObjectPtrTy, params,
true),
137 "objc_msgSendSuper2");
144 llvm::FunctionCallee getMessageSendSuperStretFn()
const {
145 llvm::Type *params[] = {Int8PtrTy, SuperPtrTy, SelectorPtrTy};
146 return CGM.CreateRuntimeFunction(
147 llvm::FunctionType::get(CGM.VoidTy, params,
true),
148 "objc_msgSendSuper_stret");
155 llvm::FunctionCallee getMessageSendSuperStretFn2()
const {
156 llvm::Type *params[] = {Int8PtrTy, SuperPtrTy, SelectorPtrTy};
157 return CGM.CreateRuntimeFunction(
158 llvm::FunctionType::get(CGM.VoidTy, params,
true),
159 "objc_msgSendSuper2_stret");
162 llvm::FunctionCallee getMessageSendSuperFpretFn()
const {
164 return getMessageSendSuperFn();
167 llvm::FunctionCallee getMessageSendSuperFpretFn2()
const {
169 return getMessageSendSuperFn2();
173 CodeGen::CodeGenModule &CGM;
176 llvm::IntegerType *ShortTy, *IntTy, *LongTy;
177 llvm::PointerType *Int8PtrTy, *Int8PtrPtrTy;
178 llvm::PointerType *Int8PtrProgramASTy;
179 llvm::Type *IvarOffsetVarTy;
182 llvm::PointerType *ObjectPtrTy;
185 llvm::PointerType *PtrObjectPtrTy;
188 llvm::PointerType *SelectorPtrTy;
193 QualType SuperPtrCTy;
196 llvm::StructType *SuperTy;
198 llvm::PointerType *SuperPtrTy;
202 llvm::StructType *PropertyTy;
206 llvm::StructType *PropertyListTy;
208 llvm::PointerType *PropertyListPtrTy;
211 llvm::StructType *MethodTy;
216 llvm::PointerType *CachePtrTy;
218 llvm::FunctionCallee getGetPropertyFn() {
219 CodeGen::CodeGenTypes &Types = CGM.getTypes();
220 ASTContext &Ctx = CGM.getContext();
229 return CGM.CreateRuntimeFunction(FTy,
"objc_getProperty");
232 llvm::FunctionCallee getSetPropertyFn() {
233 CodeGen::CodeGenTypes &Types = CGM.getTypes();
234 ASTContext &Ctx = CGM.getContext();
247 return CGM.CreateRuntimeFunction(FTy,
"objc_setProperty");
250 llvm::FunctionCallee getOptimizedSetPropertyFn(
bool atomic,
bool copy) {
251 CodeGen::CodeGenTypes &Types = CGM.getTypes();
252 ASTContext &Ctx = CGM.getContext();
262 SmallVector<CanQualType, 4> Params;
265 Params.push_back(IdType);
266 Params.push_back(SelType);
267 Params.push_back(IdType);
273 name =
"objc_setProperty_atomic_copy";
274 else if (atomic && !copy)
275 name =
"objc_setProperty_atomic";
276 else if (!atomic && copy)
277 name =
"objc_setProperty_nonatomic_copy";
279 name =
"objc_setProperty_nonatomic";
281 return CGM.CreateRuntimeFunction(FTy, name);
284 llvm::FunctionCallee getCopyStructFn() {
285 CodeGen::CodeGenTypes &Types = CGM.getTypes();
286 ASTContext &Ctx = CGM.getContext();
288 SmallVector<CanQualType, 5> Params;
292 Params.push_back(Ctx.
BoolTy);
293 Params.push_back(Ctx.
BoolTy);
296 return CGM.CreateRuntimeFunction(FTy,
"objc_copyStruct");
303 llvm::FunctionCallee getCppAtomicObjectFunction() {
304 CodeGen::CodeGenTypes &Types = CGM.getTypes();
305 ASTContext &Ctx = CGM.getContext();
308 SmallVector<CanQualType, 3> Params;
314 return CGM.CreateRuntimeFunction(FTy,
"objc_copyCppObjectAtomic");
317 llvm::FunctionCallee getEnumerationMutationFn() {
318 CodeGen::CodeGenTypes &Types = CGM.getTypes();
319 ASTContext &Ctx = CGM.getContext();
321 SmallVector<CanQualType, 1> Params;
325 return CGM.CreateRuntimeFunction(FTy,
"objc_enumerationMutation");
328 llvm::FunctionCallee getLookUpClassFn() {
329 CodeGen::CodeGenTypes &Types = CGM.getTypes();
330 ASTContext &Ctx = CGM.getContext();
332 SmallVector<CanQualType, 1> Params;
335 llvm::FunctionType *FTy =
338 return CGM.CreateRuntimeFunction(FTy,
"objc_lookUpClass");
342 llvm::FunctionCallee getGcReadWeakFn() {
344 llvm::Type *args[] = {CGM.DefaultPtrTy};
345 llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, args,
false);
346 return CGM.CreateRuntimeFunction(FTy,
"objc_read_weak");
350 llvm::FunctionCallee getGcAssignWeakFn() {
352 llvm::Type *args[] = {ObjectPtrTy, CGM.DefaultPtrTy};
353 llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, args,
false);
354 return CGM.CreateRuntimeFunction(FTy,
"objc_assign_weak");
358 llvm::FunctionCallee getGcAssignGlobalFn() {
360 llvm::Type *args[] = {ObjectPtrTy, CGM.DefaultPtrTy};
361 llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, args,
false);
362 return CGM.CreateRuntimeFunction(FTy,
"objc_assign_global");
366 llvm::FunctionCallee getGcAssignThreadLocalFn() {
368 llvm::Type *args[] = {ObjectPtrTy, CGM.DefaultPtrTy};
369 llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, args,
false);
370 return CGM.CreateRuntimeFunction(FTy,
"objc_assign_threadlocal");
374 llvm::FunctionCallee getGcAssignIvarFn() {
376 llvm::Type *args[] = {ObjectPtrTy, CGM.DefaultPtrTy, CGM.PtrDiffTy};
377 llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, args,
false);
378 return CGM.CreateRuntimeFunction(FTy,
"objc_assign_ivar");
382 llvm::FunctionCallee GcMemmoveCollectableFn() {
384 llvm::Type *args[] = {Int8PtrTy, Int8PtrTy, LongTy};
385 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, args,
false);
386 return CGM.CreateRuntimeFunction(FTy,
"objc_memmove_collectable");
390 llvm::FunctionCallee getGcAssignStrongCastFn() {
392 llvm::Type *args[] = {ObjectPtrTy, CGM.DefaultPtrTy};
393 llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, args,
false);
394 return CGM.CreateRuntimeFunction(FTy,
"objc_assign_strongCast");
398 llvm::FunctionCallee getExceptionThrowFn() {
400 llvm::Type *args[] = {ObjectPtrTy};
401 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy, args,
false);
402 return CGM.CreateRuntimeFunction(FTy,
"objc_exception_throw");
406 llvm::FunctionCallee getExceptionRethrowFn() {
408 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy,
false);
409 return CGM.CreateRuntimeFunction(FTy,
"objc_exception_rethrow");
413 llvm::FunctionCallee getSyncEnterFn() {
415 llvm::Type *args[] = {ObjectPtrTy};
416 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.IntTy, args,
false);
417 return CGM.CreateRuntimeFunction(FTy,
"objc_sync_enter");
421 llvm::FunctionCallee getSyncExitFn() {
423 llvm::Type *args[] = {ObjectPtrTy};
424 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.IntTy, args,
false);
425 return CGM.CreateRuntimeFunction(FTy,
"objc_sync_exit");
428 llvm::FunctionCallee getSendFn(
bool IsSuper)
const {
429 return IsSuper ? getMessageSendSuperFn() : getMessageSendFn();
432 llvm::FunctionCallee getSendFn2(
bool IsSuper)
const {
433 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();
436 llvm::FunctionCallee getSendStretFn(
bool IsSuper)
const {
437 return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();
440 llvm::FunctionCallee getSendStretFn2(
bool IsSuper)
const {
441 return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();
444 llvm::FunctionCallee getSendFpretFn(
bool IsSuper)
const {
445 return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();
448 llvm::FunctionCallee getSendFpretFn2(
bool IsSuper)
const {
449 return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();
452 llvm::FunctionCallee getSendFp2retFn(
bool IsSuper)
const {
453 return IsSuper ? getMessageSendSuperFn() : getMessageSendFp2retFn();
456 llvm::FunctionCallee getSendFp2RetFn2(
bool IsSuper)
const {
457 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFp2retFn();
460 ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm);
465class ObjCTypesHelper :
public ObjCCommonTypesHelper {
468 llvm::StructType *SymtabTy;
470 llvm::PointerType *SymtabPtrTy;
472 llvm::StructType *ModuleTy;
475 llvm::StructType *ProtocolTy;
477 llvm::PointerType *ProtocolPtrTy;
480 llvm::StructType *ProtocolExtensionTy;
483 llvm::PointerType *ProtocolExtensionPtrTy;
486 llvm::StructType *MethodDescriptionTy;
489 llvm::StructType *MethodDescriptionListTy;
492 llvm::PointerType *MethodDescriptionListPtrTy;
494 llvm::StructType *ProtocolListTy;
496 llvm::PointerType *ProtocolListPtrTy;
498 llvm::StructType *CategoryTy;
500 llvm::StructType *ClassTy;
502 llvm::PointerType *ClassPtrTy;
504 llvm::StructType *ClassExtensionTy;
506 llvm::PointerType *ClassExtensionPtrTy;
508 llvm::StructType *IvarTy;
510 llvm::StructType *IvarListTy;
512 llvm::PointerType *IvarListPtrTy;
514 llvm::StructType *MethodListTy;
516 llvm::PointerType *MethodListPtrTy;
519 llvm::StructType *ExceptionDataTy;
522 llvm::FunctionCallee getExceptionTryEnterFn() {
525 llvm::FunctionType::get(CGM.
VoidTy, params,
false),
526 "objc_exception_try_enter");
530 llvm::FunctionCallee getExceptionTryExitFn() {
533 llvm::FunctionType::get(CGM.
VoidTy, params,
false),
534 "objc_exception_try_exit");
538 llvm::FunctionCallee getExceptionExtractFn() {
541 llvm::FunctionType::get(ObjectPtrTy, params,
false),
542 "objc_exception_extract");
546 llvm::FunctionCallee getExceptionMatchFn() {
547 llvm::Type *params[] = {ClassPtrTy, ObjectPtrTy};
549 llvm::FunctionType::get(CGM.
Int32Ty, params,
false),
550 "objc_exception_match");
554 llvm::FunctionCallee getSetJmpFn() {
558 llvm::FunctionType::get(CGM.
Int32Ty, params,
false),
"_setjmp",
560 llvm::AttributeList::FunctionIndex,
561 llvm::Attribute::NonLazyBind));
565 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
570class ObjCNonFragileABITypesHelper :
public ObjCCommonTypesHelper {
573 llvm::StructType *MethodListnfABITy;
576 llvm::PointerType *MethodListnfABIPtrTy;
579 llvm::StructType *ProtocolnfABITy;
582 llvm::PointerType *ProtocolnfABIPtrTy;
585 llvm::StructType *ProtocolListnfABITy;
588 llvm::PointerType *ProtocolListnfABIPtrTy;
591 llvm::StructType *ClassnfABITy;
594 llvm::PointerType *ClassnfABIPtrTy;
597 llvm::StructType *IvarnfABITy;
600 llvm::StructType *IvarListnfABITy;
603 llvm::PointerType *IvarListnfABIPtrTy;
606 llvm::StructType *ClassRonfABITy;
609 llvm::PointerType *ImpnfABITy;
612 llvm::StructType *CategorynfABITy;
621 llvm::StructType *MessageRefTy;
623 QualType MessageRefCTy;
626 llvm::Type *MessageRefPtrTy;
628 QualType MessageRefCPtrTy;
635 llvm::StructType *SuperMessageRefTy;
638 llvm::PointerType *SuperMessageRefPtrTy;
640 llvm::FunctionCallee getMessageSendFixupFn() {
642 llvm::Type *params[] = {ObjectPtrTy, MessageRefPtrTy};
644 llvm::FunctionType::get(ObjectPtrTy, params,
true),
645 "objc_msgSend_fixup");
648 llvm::FunctionCallee getMessageSendFpretFixupFn() {
650 llvm::Type *params[] = {ObjectPtrTy, MessageRefPtrTy};
652 llvm::FunctionType::get(ObjectPtrTy, params,
true),
653 "objc_msgSend_fpret_fixup");
656 llvm::FunctionCallee getMessageSendStretFixupFn() {
658 llvm::Type *params[] = {ObjectPtrTy, MessageRefPtrTy};
660 llvm::FunctionType::get(ObjectPtrTy, params,
true),
661 "objc_msgSend_stret_fixup");
664 llvm::FunctionCallee getMessageSendSuper2FixupFn() {
667 llvm::Type *params[] = {SuperPtrTy, SuperMessageRefPtrTy};
669 llvm::FunctionType::get(ObjectPtrTy, params,
true),
670 "objc_msgSendSuper2_fixup");
673 llvm::FunctionCallee getMessageSendSuper2StretFixupFn() {
676 llvm::Type *params[] = {SuperPtrTy, SuperMessageRefPtrTy};
678 llvm::FunctionType::get(ObjectPtrTy, params,
true),
679 "objc_msgSendSuper2_stret_fixup");
682 llvm::FunctionCallee getObjCEndCatchFn() {
687 llvm::FunctionCallee getObjCBeginCatchFn() {
688 llvm::Type *params[] = {Int8PtrTy};
690 llvm::FunctionType::get(Int8PtrTy, params,
false),
"objc_begin_catch");
698 llvm::FunctionCallee getLoadClassrefFn()
const {
704 llvm::Type *params[] = {Int8PtrPtrTy};
706 llvm::AttributeSet AS = llvm::AttributeSet::get(
708 llvm::Attribute::get(
C, llvm::Attribute::NonLazyBind),
709 llvm::Attribute::getWithMemoryEffects(
710 C, llvm::MemoryEffects::none()),
711 llvm::Attribute::get(
C, llvm::Attribute::NoUnwind),
714 llvm::FunctionType::get(ClassnfABIPtrTy, params,
false),
717 llvm::AttributeList::FunctionIndex, AS));
718 if (!CGM.
getTriple().isOSBinFormatCOFF())
720 ->setLinkage(llvm::Function::ExternalWeakLinkage);
725 llvm::StructType *EHTypeTy;
726 llvm::Type *EHTypePtrTy;
728 ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm);
731enum class ObjCLabelType {
748 SKIP_SCAN(
unsigned _skip = 0,
unsigned _scan = 0)
749 : skip(_skip), scan(_scan) {}
757 enum BLOCK_LAYOUT_OPCODE {
764 BLOCK_LAYOUT_OPERATOR = 0,
770 BLOCK_LAYOUT_NON_OBJECT_BYTES = 1,
775 BLOCK_LAYOUT_NON_OBJECT_WORDS = 2,
779 BLOCK_LAYOUT_STRONG = 3,
782 BLOCK_LAYOUT_BYREF = 4,
786 BLOCK_LAYOUT_WEAK = 5,
790 BLOCK_LAYOUT_UNRETAINED = 6
808 enum BLOCK_LAYOUT_OPCODE opcode;
809 CharUnits block_var_bytepos;
810 CharUnits block_var_size;
811 RUN_SKIP(
enum BLOCK_LAYOUT_OPCODE Opcode = BLOCK_LAYOUT_OPERATOR,
814 : opcode(
Opcode), block_var_bytepos(BytePos), block_var_size(
Size) {}
817 bool operator<(
const RUN_SKIP &b)
const {
818 return block_var_bytepos < b.block_var_bytepos;
823 llvm::LLVMContext &VMContext;
828 SmallVector<RUN_SKIP, 16> RunSkipBlockVars;
832 llvm::SetVector<IdentifierInfo *> LazySymbols;
838 llvm::SetVector<IdentifierInfo *> DefinedSymbols;
841 llvm::StringMap<llvm::GlobalVariable *> ClassNames;
844 llvm::DenseMap<Selector, llvm::GlobalVariable *> MethodVarNames;
847 llvm::SmallSetVector<llvm::CachedHashString, 16> DefinedCategoryNames;
851 llvm::StringMap<llvm::GlobalVariable *> MethodVarTypes;
855 llvm::DenseMap<const ObjCMethodDecl *, llvm::Function *> MethodDefinitions;
858 struct DirectMethodInfo {
861 llvm::Function *Thunk;
863 DirectMethodInfo(llvm::Function *Impl, llvm::Function *Thunk =
nullptr)
864 : Implementation(Impl), Thunk(Thunk) {}
869 llvm::DenseMap<const ObjCMethodDecl *, DirectMethodInfo>
870 DirectMethodDefinitions;
873 llvm::DenseMap<std::pair<Selector, StringRef>, llvm::Function *>
877 llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> PropertyNames;
880 llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> ClassReferences;
883 llvm::DenseMap<Selector, llvm::GlobalVariable *> SelectorReferences;
888 llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> Protocols;
892 llvm::DenseSet<IdentifierInfo *> DefinedProtocols;
895 SmallVector<llvm::GlobalValue *, 16> DefinedClasses;
898 SmallVector<const ObjCInterfaceDecl *, 16> ImplementedClasses;
901 SmallVector<llvm::GlobalValue *, 16> DefinedNonLazyClasses;
904 SmallVector<llvm::GlobalValue *, 16> DefinedCategories;
907 SmallVector<llvm::GlobalValue *, 16> DefinedStubCategories;
910 SmallVector<llvm::GlobalValue *, 16> DefinedNonLazyCategories;
914 llvm::WeakTrackingVH ConstantStringClassRef;
915 llvm::WeakTrackingVH ConstantArrayClassRef;
916 llvm::WeakTrackingVH ConstantDictionaryClassRef;
918 llvm::WeakTrackingVH ConstantIntegerNumberClassRef;
919 llvm::WeakTrackingVH ConstantFloatNumberClassRef;
920 llvm::WeakTrackingVH ConstantDoubleNumberClassRef;
923 llvm::StructType *NSConstantStringType =
nullptr;
924 llvm::StructType *NSConstantArrayType =
nullptr;
925 llvm::StructType *NSConstantDictionaryType =
nullptr;
927 llvm::StructType *NSConstantIntegerNumberType =
nullptr;
928 llvm::StructType *NSConstantFloatNumberType =
nullptr;
929 llvm::StructType *NSConstantDoubleNumberType =
nullptr;
931 llvm::StringMap<llvm::GlobalVariable *> NSConstantStringMap;
934 llvm::GlobalVariable *DefinedCFBooleanTrue =
nullptr;
935 llvm::GlobalVariable *DefinedCFBooleanFalse =
nullptr;
938 llvm::DenseMap<NSConstantNumberMapInfo, llvm::GlobalVariable *>
942 llvm::GlobalVariable *DefinedEmptyNSDictionary =
nullptr;
943 llvm::GlobalVariable *DefinedEmptyNSArray =
nullptr;
947 llvm::Constant *GetMethodVarName(Selector Sel);
948 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
954 llvm::Constant *GetMethodVarType(
const ObjCMethodDecl *D,
955 bool Extended =
false);
956 llvm::Constant *GetMethodVarType(
const FieldDecl *D);
960 llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
963 llvm::Constant *GetPropertyTypeString(
const ObjCPropertyDecl *PD,
964 const Decl *Container);
969 llvm::Constant *GetClassName(StringRef RuntimeName);
971 llvm::Function *GetMethodDefinition(
const ObjCMethodDecl *MD);
980 llvm::Constant *BuildIvarLayout(
const ObjCImplementationDecl *OI,
981 CharUnits beginOffset, CharUnits endOffset,
984 llvm::Constant *BuildStrongIvarLayout(
const ObjCImplementationDecl *OI,
985 CharUnits beginOffset,
986 CharUnits endOffset) {
987 return BuildIvarLayout(OI, beginOffset, endOffset,
true,
false);
990 llvm::Constant *BuildWeakIvarLayout(
const ObjCImplementationDecl *OI,
991 CharUnits beginOffset,
994 return BuildIvarLayout(OI, beginOffset, endOffset,
false,
hasMRCWeakIvars);
1001 CharUnits FieldOffset, CharUnits FieldSize);
1003 void BuildRCBlockVarRecordLayout(
const RecordType *RT, CharUnits BytePos,
1004 bool &HasUnion,
bool ByrefLayout =
false);
1006 void BuildRCRecordLayout(
const llvm::StructLayout *RecLayout,
1007 const RecordDecl *RD,
1008 ArrayRef<const FieldDecl *> RecFields,
1009 CharUnits BytePos,
bool &HasUnion,
bool ByrefLayout);
1011 uint64_t InlineLayoutInstruction(SmallVectorImpl<unsigned char> &Layout);
1013 llvm::Constant *getBitmapBlockLayout(
bool ComputeByrefLayout);
1017 llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident,
1018 const ObjCCommonTypesHelper &ObjCTypes);
1022 llvm::Constant *EmitPropertyList(Twine Name,
const Decl *Container,
1023 const ObjCContainerDecl *OCD,
1024 const ObjCCommonTypesHelper &ObjCTypes,
1025 bool IsClassProperty);
1030 EmitProtocolMethodTypes(Twine Name, ArrayRef<llvm::Constant *> MethodTypes,
1031 const ObjCCommonTypesHelper &ObjCTypes);
1036 llvm::Constant *GetProtocolRef(
const ObjCProtocolDecl *PD);
1040 llvm::Value *EmitClassRefViaRuntime(CodeGenFunction &CGF,
1041 const ObjCInterfaceDecl *ID,
1042 ObjCCommonTypesHelper &ObjCTypes);
1044 std::string GetSectionName(StringRef Section, StringRef MachOAttributes);
1047 static constexpr llvm::StringLiteral GetNSConstantIntegerNumberSectionName() {
1048 return "__DATA,__objc_intobj,regular,no_dead_strip";
1052 static constexpr llvm::StringLiteral GetNSConstantFloatNumberSectionName() {
1053 return "__DATA,__objc_floatobj,regular,no_dead_strip";
1057 static constexpr llvm::StringLiteral GetNSConstantDoubleNumberSectionName() {
1058 return "__DATA,__objc_doubleobj,regular,no_dead_strip";
1063 static constexpr llvm::StringLiteral
1064 GetNSConstantCollectionStorageSectionName() {
1065 return "__DATA,__objc_arraydata,regular,no_dead_strip";
1069 static constexpr llvm::StringLiteral GetNSConstantArraySectionName() {
1070 return "__DATA,__objc_arrayobj,regular,no_dead_strip";
1074 static constexpr llvm::StringLiteral GetNSConstantDictionarySectionName() {
1075 return "__DATA,__objc_dictobj,regular,no_dead_strip";
1093 llvm::GlobalVariable *CreateMetadataVar(Twine Name,
1094 ConstantStructBuilder &
Init,
1095 StringRef Section, CharUnits Align,
1097 llvm::GlobalVariable *CreateMetadataVar(Twine Name, llvm::Constant *
Init,
1098 StringRef Section, CharUnits Align,
1101 llvm::GlobalVariable *CreateCStringLiteral(StringRef Name,
1102 ObjCLabelType LabelType,
1103 bool ForceNonFragileABI =
false,
1104 bool NullTerminate =
true);
1107 CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
1108 ReturnValueSlot Return, QualType ResultType,
1109 Selector Sel, llvm::Value *Arg0,
1110 QualType Arg0Ty,
bool IsSuper,
1111 const CallArgList &CallArgs,
1112 const ObjCMethodDecl *OMD,
1113 const ObjCInterfaceDecl *ClassReceiver,
1114 const ObjCCommonTypesHelper &ObjCTypes);
1118 void EmitImageInfo();
1121 CGObjCCommonMac(CodeGen::CodeGenModule &cgm)
1122 : CGObjCRuntime(cgm), VMContext(cgm.getLLVMContext()) {}
1124 bool isNonFragileABI()
const {
return ObjCABI == 2; }
1127 llvm::GlobalVariable *EmitConstantCFBooleanTrue() {
1128 if (DefinedCFBooleanTrue)
1129 return DefinedCFBooleanTrue;
1132 "The current ABI doesn't support the constant CFBooleanTrue "
1137 DefinedCFBooleanTrue->addAttribute(
"objc_arc_inert");
1138 return DefinedCFBooleanTrue;
1142 llvm::GlobalVariable *EmitConstantCFBooleanFalse() {
1143 if (DefinedCFBooleanFalse)
1144 return DefinedCFBooleanFalse;
1147 "The current ABI doesn't support the constant CFBooleanFalse "
1152 DefinedCFBooleanFalse->addAttribute(
"objc_arc_inert");
1153 return DefinedCFBooleanFalse;
1157 llvm::GlobalVariable *EmitEmptyConstantNSDictionary() {
1158 if (DefinedEmptyNSDictionary)
1159 return DefinedEmptyNSDictionary;
1162 "The current ABI doesn't support an empty constant NSDictionary "
1167 DefinedEmptyNSDictionary->addAttribute(
"objc_arc_inert");
1168 return DefinedEmptyNSDictionary;
1172 llvm::GlobalVariable *EmitEmptyConstantNSArray() {
1173 if (DefinedEmptyNSArray)
1174 return DefinedEmptyNSArray;
1178 "The current ABI doesn't support an empty constant NSArray singleton!");
1182 DefinedEmptyNSArray->addAttribute(
"objc_arc_inert");
1183 return DefinedEmptyNSArray;
1186 ConstantAddress GenerateConstantString(
const StringLiteral *SL)
override;
1188 ConstantAddress GenerateConstantNumber(
const bool Value,
1189 const QualType &Ty)
override;
1190 ConstantAddress GenerateConstantNumber(
const llvm::APSInt &
Value,
1191 const QualType &Ty)
override;
1192 ConstantAddress GenerateConstantNumber(
const llvm::APFloat &
Value,
1193 const QualType &Ty)
override;
1195 GenerateConstantArray(
const ArrayRef<llvm::Constant *> &Objects)
override;
1196 ConstantAddress GenerateConstantDictionary(
1197 const ObjCDictionaryLiteral *E,
1198 ArrayRef<std::pair<llvm::Constant *, llvm::Constant *>> KeysAndObjects)
1201 ConstantAddress GenerateConstantNSString(
const StringLiteral *SL);
1202 ConstantAddress GenerateConstantNSNumber(
const bool Value,
1203 const QualType &Ty);
1204 ConstantAddress GenerateConstantNSNumber(
const llvm::APSInt &
Value,
1205 const QualType &Ty);
1206 ConstantAddress GenerateConstantNSNumber(
const llvm::APFloat &
Value,
1207 const QualType &Ty);
1209 GenerateConstantNSArray(
const ArrayRef<llvm::Constant *> &Objects);
1210 ConstantAddress GenerateConstantNSDictionary(
1211 const ObjCDictionaryLiteral *E,
1212 ArrayRef<std::pair<llvm::Constant *, llvm::Constant *>> KeysAndObjects);
1215 GenerateMethod(
const ObjCMethodDecl *OMD,
1216 const ObjCContainerDecl *CD =
nullptr)
override;
1218 DirectMethodInfo &GenerateDirectMethod(
const ObjCMethodDecl *OMD,
1219 const ObjCContainerDecl *CD);
1221 llvm::Function *GenerateObjCDirectThunk(
const ObjCMethodDecl *OMD,
1222 const ObjCContainerDecl *CD,
1223 llvm::Function *Implementation);
1225 llvm::Function *GetDirectMethodCallee(
const ObjCMethodDecl *OMD,
1226 const ObjCContainerDecl *CD,
1227 bool ReceiverCanBeNull,
1228 bool ClassObjectCanBeUnrealized);
1233 llvm::Value *GenerateClassRealization(CodeGenFunction &CGF,
1234 llvm::Value *classObject,
1235 const ObjCInterfaceDecl *OID);
1237 void GenerateDirectMethodsPreconditionCheck(
1238 CodeGenFunction &CGF, llvm::Function *Fn,
const ObjCMethodDecl *OMD,
1239 const ObjCContainerDecl *CD)
override;
1241 void GenerateDirectMethodPrologue(CodeGenFunction &CGF, llvm::Function *Fn,
1242 const ObjCMethodDecl *OMD,
1243 const ObjCContainerDecl *CD)
override;
1246 GenerateMethodSelectorStub(Selector Sel, StringRef ClassName,
1247 const ObjCCommonTypesHelper &ObjCTypes);
1249 void GenerateProtocol(
const ObjCProtocolDecl *PD)
override;
1255 virtual llvm::Constant *GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD) = 0;
1257 virtual llvm::Constant *getNSConstantStringClassRef() = 0;
1258 virtual llvm::Constant *getNSConstantArrayClassRef() = 0;
1259 virtual llvm::Constant *getNSConstantDictionaryClassRef() = 0;
1261 virtual llvm::Constant *getNSConstantIntegerNumberClassRef() = 0;
1262 virtual llvm::Constant *getNSConstantFloatNumberClassRef() = 0;
1263 virtual llvm::Constant *getNSConstantDoubleNumberClassRef() = 0;
1265 llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM,
1266 const CGBlockInfo &blockInfo)
override;
1267 llvm::Constant *BuildRCBlockLayout(CodeGen::CodeGenModule &CGM,
1268 const CGBlockInfo &blockInfo)
override;
1269 std::string getRCBlockLayoutStr(CodeGen::CodeGenModule &CGM,
1270 const CGBlockInfo &blockInfo)
override;
1272 llvm::Constant *BuildByrefLayout(CodeGen::CodeGenModule &CGM,
1273 QualType T)
override;
1276 void fillRunSkipBlockVars(CodeGenModule &CGM,
const CGBlockInfo &blockInfo);
1277 llvm::GlobalVariable *EmitNSConstantCollectionLiteralArrayStorage(
1278 const ArrayRef<llvm::Constant *> &Elements);
1283enum class MethodListType {
1284 CategoryInstanceMethods,
1285 CategoryClassMethods,
1288 ProtocolInstanceMethods,
1289 ProtocolClassMethods,
1290 OptionalProtocolInstanceMethods,
1291 OptionalProtocolClassMethods,
1296class ProtocolMethodLists {
1299 RequiredInstanceMethods,
1300 RequiredClassMethods,
1301 OptionalInstanceMethods,
1302 OptionalClassMethods
1304 enum { NumProtocolMethodLists = 4 };
1306 static MethodListType getMethodListKind(Kind
kind) {
1308 case RequiredInstanceMethods:
1309 return MethodListType::ProtocolInstanceMethods;
1310 case RequiredClassMethods:
1311 return MethodListType::ProtocolClassMethods;
1312 case OptionalInstanceMethods:
1313 return MethodListType::OptionalProtocolInstanceMethods;
1314 case OptionalClassMethods:
1315 return MethodListType::OptionalProtocolClassMethods;
1317 llvm_unreachable(
"bad kind");
1320 SmallVector<const ObjCMethodDecl *, 4> Methods[NumProtocolMethodLists];
1322 static ProtocolMethodLists get(
const ObjCProtocolDecl *PD) {
1323 ProtocolMethodLists result;
1325 for (
auto *MD : PD->
methods()) {
1327 (2 *
size_t(MD->isOptional())) + (
size_t(MD->isClassMethod()));
1328 result.Methods[index].push_back(MD);
1334 template <
class Self>
1335 SmallVector<llvm::Constant *, 8> emitExtendedTypesArray(
Self *self)
const {
1342 SmallVector<llvm::Constant *, 8> result;
1345 for (
auto &list : Methods) {
1346 for (
auto MD : list) {
1347 result.push_back(self->GetMethodVarType(MD,
true));
1354 template <
class Self>
1355 llvm::Constant *emitMethodList(
Self *self,
const ObjCProtocolDecl *PD,
1358 getMethodListKind(
kind), Methods[
kind]);
1364class CGObjCMac :
public CGObjCCommonMac {
1366 friend ProtocolMethodLists;
1368 ObjCTypesHelper ObjCTypes;
1372 void EmitModuleInfo();
1376 llvm::Constant *EmitModuleSymbols();
1380 void FinishModule();
1385 llvm::Constant *EmitClassExtension(
const ObjCImplementationDecl *ID,
1386 CharUnits instanceSize,
1391 llvm::Value *EmitClassRef(CodeGenFunction &CGF,
const ObjCInterfaceDecl *ID);
1393 llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF, IdentifierInfo *II);
1395 llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF)
override;
1398 llvm::Value *EmitSuperClassRef(
const ObjCInterfaceDecl *ID);
1405 llvm::Constant *EmitIvarList(
const ObjCImplementationDecl *ID,
bool ForClass);
1410 llvm::Constant *EmitMetaClassRef(
const ObjCInterfaceDecl *ID);
1414 llvm::Constant *EmitMetaClass(
const ObjCImplementationDecl *ID,
1415 llvm::Constant *Protocols,
1416 ArrayRef<const ObjCMethodDecl *> Methods);
1418 void emitMethodConstant(ConstantArrayBuilder &builder,
1419 const ObjCMethodDecl *MD);
1421 void emitMethodDescriptionConstant(ConstantArrayBuilder &builder,
1422 const ObjCMethodDecl *MD);
1426 llvm::Constant *emitMethodList(Twine Name, MethodListType MLT,
1427 ArrayRef<const ObjCMethodDecl *> Methods);
1432 llvm::Constant *GetOrEmitProtocol(
const ObjCProtocolDecl *PD)
override;
1438 llvm::Constant *GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD)
override;
1444 llvm::Constant *EmitProtocolExtension(
const ObjCProtocolDecl *PD,
1445 const ProtocolMethodLists &methodLists);
1449 llvm::Constant *EmitProtocolList(Twine Name,
1455 llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel);
1456 ConstantAddress EmitSelectorAddr(Selector Sel);
1459 CGObjCMac(CodeGen::CodeGenModule &cgm);
1461 llvm::Constant *getNSConstantStringClassRef()
override;
1462 llvm::Constant *getNSConstantArrayClassRef()
override;
1463 llvm::Constant *getNSConstantDictionaryClassRef()
override;
1465 llvm::Constant *getNSConstantIntegerNumberClassRef()
override;
1466 llvm::Constant *getNSConstantFloatNumberClassRef()
override;
1467 llvm::Constant *getNSConstantDoubleNumberClassRef()
override;
1469 llvm::Function *ModuleInitFunction()
override;
1471 CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1472 ReturnValueSlot Return,
1473 QualType ResultType, Selector Sel,
1474 llvm::Value *Receiver,
1475 const CallArgList &CallArgs,
1476 const ObjCInterfaceDecl *
Class,
1477 const ObjCMethodDecl *
Method)
override;
1479 CodeGen::RValue GenerateMessageSendSuper(
1480 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return,
1481 QualType ResultType, Selector Sel,
const ObjCInterfaceDecl *
Class,
1482 bool isCategoryImpl, llvm::Value *Receiver,
bool IsClassMessage,
1483 const CallArgList &CallArgs,
const ObjCMethodDecl *
Method)
override;
1485 llvm::Value *GetClass(CodeGenFunction &CGF,
1486 const ObjCInterfaceDecl *ID)
override;
1488 llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel)
override;
1489 Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel)
override;
1493 llvm::Value *GetSelector(CodeGenFunction &CGF,
1494 const ObjCMethodDecl *
Method)
override;
1496 llvm::Constant *GetEHType(QualType T)
override;
1498 void GenerateCategory(
const ObjCCategoryImplDecl *CMD)
override;
1500 void GenerateClass(
const ObjCImplementationDecl *ClassDecl)
override;
1502 void RegisterAlias(
const ObjCCompatibleAliasDecl *OAD)
override {}
1504 llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
1505 const ObjCProtocolDecl *PD)
override;
1507 llvm::FunctionCallee GetPropertyGetFunction()
override;
1508 llvm::FunctionCallee GetPropertySetFunction()
override;
1509 llvm::FunctionCallee GetOptimizedPropertySetFunction(
bool atomic,
1510 bool copy)
override;
1511 llvm::FunctionCallee GetGetStructFunction()
override;
1512 llvm::FunctionCallee GetSetStructFunction()
override;
1513 llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override;
1514 llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override;
1515 llvm::FunctionCallee EnumerationMutationFunction()
override;
1517 void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1518 const ObjCAtTryStmt &S)
override;
1519 void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1520 const ObjCAtSynchronizedStmt &S)
override;
1521 void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
const Stmt &S);
1522 void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
const ObjCAtThrowStmt &S,
1523 bool ClearInsertionPoint =
true)
override;
1524 llvm::Value *EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1525 Address AddrWeakObj)
override;
1526 void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1527 Address dst)
override;
1528 void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1529 Address dest,
bool threadlocal =
false)
override;
1530 void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1531 Address dest, llvm::Value *ivarOffset)
override;
1532 void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1533 Address dest)
override;
1534 void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, Address dest,
1535 Address src, llvm::Value *size)
override;
1537 LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy,
1538 llvm::Value *BaseValue,
const ObjCIvarDecl *Ivar,
1539 unsigned CVRQualifiers)
override;
1540 llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1542 const ObjCIvarDecl *Ivar)
override;
1545class CGObjCNonFragileABIMac :
public CGObjCCommonMac {
1547 friend ProtocolMethodLists;
1548 ObjCNonFragileABITypesHelper ObjCTypes;
1549 llvm::GlobalVariable *ObjCEmptyCacheVar;
1550 llvm::Constant *ObjCEmptyVtableVar;
1553 llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> SuperClassReferences;
1556 llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> MetaClassReferences;
1559 llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> EHTypeReferences;
1563 llvm::DenseSet<Selector> VTableDispatchMethods;
1566 std::vector<llvm::GlobalValue *> DefinedMetaClasses;
1570 bool isVTableDispatchedSelector(Selector Sel);
1574 void FinishNonFragileABIModule();
1578 void AddModuleClassList(ArrayRef<llvm::GlobalValue *> Container,
1579 StringRef SymbolName, StringRef SectionName);
1581 llvm::GlobalVariable *
1582 BuildClassRoTInitializer(
unsigned flags,
unsigned InstanceStart,
1583 unsigned InstanceSize,
1584 const ObjCImplementationDecl *ID);
1585 llvm::GlobalVariable *
1586 BuildClassObject(
const ObjCInterfaceDecl *CI,
bool isMetaclass,
1587 llvm::Constant *IsAGV, llvm::Constant *SuperClassGV,
1590 void emitMethodConstant(ConstantArrayBuilder &builder,
1591 const ObjCMethodDecl *MD,
bool forProtocol);
1595 llvm::Constant *emitMethodList(Twine Name, MethodListType MLT,
1596 ArrayRef<const ObjCMethodDecl *> Methods);
1603 llvm::Constant *EmitIvarList(
const ObjCImplementationDecl *ID);
1605 llvm::Constant *EmitIvarOffsetVar(
const ObjCInterfaceDecl *ID,
1606 const ObjCIvarDecl *Ivar,
1607 unsigned long int offset);
1612 llvm::Constant *GetOrEmitProtocol(
const ObjCProtocolDecl *PD)
override;
1618 llvm::Constant *GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD)
override;
1622 llvm::Constant *EmitProtocolList(Twine Name,
1626 CodeGen::RValue EmitVTableMessageSend(
1627 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return,
1628 QualType ResultType, Selector Sel, llvm::Value *Receiver, QualType Arg0Ty,
1629 bool IsSuper,
const CallArgList &CallArgs,
const ObjCMethodDecl *
Method);
1633 llvm::Constant *GetClassGlobal(StringRef Name,
1635 bool Weak =
false,
bool DLLImport =
false);
1636 llvm::Constant *GetClassGlobal(
const ObjCInterfaceDecl *ID,
bool isMetaclass,
1639 llvm::Constant *GetClassGlobalForClassRef(
const ObjCInterfaceDecl *ID);
1641 llvm::Value *EmitLoadOfClassRef(CodeGenFunction &CGF,
1642 const ObjCInterfaceDecl *ID,
1643 llvm::GlobalVariable *Entry);
1647 llvm::Value *EmitClassRef(CodeGenFunction &CGF,
const ObjCInterfaceDecl *ID);
1649 llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF, IdentifierInfo *II,
1650 const ObjCInterfaceDecl *ID);
1652 llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF)
override;
1656 llvm::Value *EmitSuperClassRef(CodeGenFunction &CGF,
1657 const ObjCInterfaceDecl *ID);
1661 llvm::Value *EmitMetaClassRef(CodeGenFunction &CGF,
1662 const ObjCInterfaceDecl *ID,
bool Weak);
1667 llvm::GlobalVariable *ObjCIvarOffsetVariable(
const ObjCInterfaceDecl *ID,
1668 const ObjCIvarDecl *Ivar);
1672 llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel);
1673 ConstantAddress EmitSelectorAddr(Selector Sel);
1677 llvm::Constant *GetInterfaceEHType(
const ObjCInterfaceDecl *ID,
1680 StringRef getMetaclassSymbolPrefix()
const {
return "OBJC_METACLASS_$_"; }
1682 StringRef getClassSymbolPrefix()
const {
return "OBJC_CLASS_$_"; }
1684 void GetClassSizeInfo(
const ObjCImplementationDecl *OID,
1700 bool ImplementationIsNonLazy(
const ObjCImplDecl *OD)
const;
1702 bool IsIvarOffsetKnownIdempotent(
const CodeGen::CodeGenFunction &CGF,
1703 const ObjCIvarDecl *IV) {
1718 if (
const ObjCMethodDecl *MD =
1719 dyn_cast_or_null<ObjCMethodDecl>(CGF.
CurFuncDecl))
1720 if (MD->isInstanceMethod() && !MD->isDirectMethod())
1721 if (
const ObjCInterfaceDecl *ID = MD->getClassInterface())
1726 bool isClassLayoutKnownStatically(
const ObjCInterfaceDecl *ID) {
1729 assert(ID !=
nullptr &&
"Passed a null class to check layout");
1730 for (;
ID !=
nullptr;
ID =
ID->getSuperClass()) {
1733 if (
ID->getIdentifier()->getName() ==
"NSObject")
1738 if (!
ID->getImplementation())
1747 CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm);
1749 llvm::Constant *getNSConstantStringClassRef()
override;
1750 llvm::Constant *getNSConstantArrayClassRef()
override;
1751 llvm::Constant *getNSConstantDictionaryClassRef()
override;
1753 llvm::Constant *getNSConstantIntegerNumberClassRef()
override;
1754 llvm::Constant *getNSConstantFloatNumberClassRef()
override;
1755 llvm::Constant *getNSConstantDoubleNumberClassRef()
override;
1757 llvm::Function *ModuleInitFunction()
override;
1759 CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1760 ReturnValueSlot Return,
1761 QualType ResultType, Selector Sel,
1762 llvm::Value *Receiver,
1763 const CallArgList &CallArgs,
1764 const ObjCInterfaceDecl *
Class,
1765 const ObjCMethodDecl *
Method)
override;
1767 CodeGen::RValue GenerateMessageSendSuper(
1768 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return,
1769 QualType ResultType, Selector Sel,
const ObjCInterfaceDecl *
Class,
1770 bool isCategoryImpl, llvm::Value *Receiver,
bool IsClassMessage,
1771 const CallArgList &CallArgs,
const ObjCMethodDecl *
Method)
override;
1773 llvm::Value *GetClass(CodeGenFunction &CGF,
1774 const ObjCInterfaceDecl *ID)
override;
1776 llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel)
override {
1777 return EmitSelector(CGF, Sel);
1779 Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel)
override {
1780 return EmitSelectorAddr(Sel);
1785 llvm::Value *GetSelector(CodeGenFunction &CGF,
1786 const ObjCMethodDecl *
Method)
override {
1787 return EmitSelector(CGF,
Method->getSelector());
1790 void GenerateCategory(
const ObjCCategoryImplDecl *CMD)
override;
1792 void GenerateClass(
const ObjCImplementationDecl *ClassDecl)
override;
1794 void RegisterAlias(
const ObjCCompatibleAliasDecl *OAD)
override {}
1796 llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
1797 const ObjCProtocolDecl *PD)
override;
1799 llvm::Constant *GetEHType(QualType T)
override;
1801 llvm::FunctionCallee GetPropertyGetFunction()
override {
1802 return ObjCTypes.getGetPropertyFn();
1804 llvm::FunctionCallee GetPropertySetFunction()
override {
1805 return ObjCTypes.getSetPropertyFn();
1808 llvm::FunctionCallee GetOptimizedPropertySetFunction(
bool atomic,
1809 bool copy)
override {
1810 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
1813 llvm::FunctionCallee GetSetStructFunction()
override {
1814 return ObjCTypes.getCopyStructFn();
1817 llvm::FunctionCallee GetGetStructFunction()
override {
1818 return ObjCTypes.getCopyStructFn();
1821 llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override {
1822 return ObjCTypes.getCppAtomicObjectFunction();
1825 llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override {
1826 return ObjCTypes.getCppAtomicObjectFunction();
1829 llvm::FunctionCallee EnumerationMutationFunction()
override {
1830 return ObjCTypes.getEnumerationMutationFn();
1833 void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1834 const ObjCAtTryStmt &S)
override;
1835 void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1836 const ObjCAtSynchronizedStmt &S)
override;
1837 void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
const ObjCAtThrowStmt &S,
1838 bool ClearInsertionPoint =
true)
override;
1839 llvm::Value *EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1840 Address AddrWeakObj)
override;
1841 void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1842 Address edst)
override;
1843 void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1844 Address dest,
bool threadlocal =
false)
override;
1845 void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1846 Address dest, llvm::Value *ivarOffset)
override;
1847 void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1848 Address dest)
override;
1849 void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, Address dest,
1850 Address src, llvm::Value *size)
override;
1851 LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy,
1852 llvm::Value *BaseValue,
const ObjCIvarDecl *Ivar,
1853 unsigned CVRQualifiers)
override;
1854 llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1856 const ObjCIvarDecl *Ivar)
override;
1861struct NullReturnState {
1862 llvm::BasicBlock *NullBB =
nullptr;
1863 NullReturnState() =
default;
1866 void init(CodeGenFunction &CGF, llvm::Value *receiver) {
1876 CGF.
Builder.CreateCondBr(isNull, NullBB, callBB);
1884 RValue complete(CodeGenFunction &CGF, ReturnValueSlot returnSlot,
1885 RValue result, QualType resultType,
1886 const CallArgList &CallArgs,
const ObjCMethodDecl *
Method) {
1893 llvm::BasicBlock *contBB =
nullptr;
1896 llvm::BasicBlock *callBB = CGF.
Builder.GetInsertBlock();
1911 assert(CGF.
Builder.GetInsertBlock() == NullBB);
1933 llvm::PHINode *phi = CGF.
Builder.CreatePHI(null->getType(), 2);
1935 phi->addIncoming(null, NullBB);
1944 assert(result.
isAggregate() &&
"null init of non-aggregate result?");
1957 llvm::Type *scalarTy = callResult.first->getType();
1958 llvm::Constant *scalarZero = llvm::Constant::getNullValue(scalarTy);
1961 llvm::PHINode *real = CGF.
Builder.CreatePHI(scalarTy, 2);
1962 real->addIncoming(callResult.first, callBB);
1963 real->addIncoming(scalarZero, NullBB);
1964 llvm::PHINode *imag = CGF.
Builder.CreatePHI(scalarTy, 2);
1965 imag->addIncoming(callResult.second, callBB);
1966 imag->addIncoming(scalarZero, NullBB);
1977 llvm::GlobalVariable *
C,
unsigned idx0,
1979 llvm::Value *Idxs[] = {
1980 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),
1981 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)};
1982 return llvm::ConstantExpr::getGetElementPtr(
C->getValueType(),
C, Idxs);
1989 if (OID->
hasAttr<ObjCExceptionAttr>())
1996static llvm::GlobalValue::LinkageTypes
1998 if (CGM.
getTriple().isOSBinFormatMachO() &&
1999 (Section.empty() || Section.starts_with(
"__DATA")))
2000 return llvm::GlobalValue::InternalLinkage;
2001 return llvm::GlobalValue::PrivateLinkage;
2005static llvm::GlobalVariable *
2008 std::string SectionName;
2009 if (CGM.
getTriple().isOSBinFormatMachO())
2010 SectionName =
"__DATA, __objc_const";
2011 auto *GV = Builder.finishAndCreateGlobal(
2014 GV->setSection(SectionName);
2021 : CGObjCCommonMac(cgm), ObjCTypes(cgm) {
2030 return EmitClassRef(CGF, ID);
2034llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF, Selector Sel) {
2035 return EmitSelector(CGF, Sel);
2037Address CGObjCMac::GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) {
2038 return EmitSelectorAddr(Sel);
2040llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF,
2041 const ObjCMethodDecl *
Method) {
2042 return EmitSelector(CGF,
Method->getSelector());
2045llvm::Constant *CGObjCMac::GetEHType(QualType T) {
2057 llvm_unreachable(
"asking for catch type for ObjC type in fragile runtime");
2080CGObjCCommonMac::GenerateConstantString(
const StringLiteral *SL) {
2083 : GenerateConstantNSString(SL));
2086ConstantAddress CGObjCCommonMac::GenerateConstantNumber(
const bool Value,
2087 const QualType &Ty) {
2088 return GenerateConstantNSNumber(
Value, Ty);
2092CGObjCCommonMac::GenerateConstantNumber(
const llvm::APSInt &
Value,
2093 const QualType &Ty) {
2094 return GenerateConstantNSNumber(
Value, Ty);
2098CGObjCCommonMac::GenerateConstantNumber(
const llvm::APFloat &
Value,
2099 const QualType &Ty) {
2100 return GenerateConstantNSNumber(
Value, Ty);
2103ConstantAddress CGObjCCommonMac::GenerateConstantArray(
2104 const ArrayRef<llvm::Constant *> &Objects) {
2105 return GenerateConstantNSArray(Objects);
2108ConstantAddress CGObjCCommonMac::GenerateConstantDictionary(
2109 const ObjCDictionaryLiteral *E,
2110 ArrayRef<std::pair<llvm::Constant *, llvm::Constant *>> KeysAndObjects) {
2111 return GenerateConstantNSDictionary(E, KeysAndObjects);
2114static llvm::StringMapEntry<llvm::GlobalVariable *> &
2117 StringRef String = Literal->getString();
2118 StringLength = String.size();
2119 return *Map.insert(std::make_pair(String,
nullptr)).first;
2122llvm::Constant *CGObjCMac::getNSConstantStringClassRef() {
2123 if (llvm::Value *
V = ConstantStringClassRef)
2127 std::string str = StringClass.empty() ?
"_NSConstantStringClassReference"
2128 :
"_" + StringClass +
"ClassReference";
2130 llvm::Type *PTy = llvm::ArrayType::get(CGM.
IntTy, 0);
2132 ConstantStringClassRef = GV;
2136llvm::Constant *CGObjCMac::getNSConstantArrayClassRef() {
2137 llvm_unreachable(
"constant array literals not supported for fragile ABI");
2140llvm::Constant *CGObjCMac::getNSConstantDictionaryClassRef() {
2141 llvm_unreachable(
"constant dictionary literals not supported for fragile "
2145llvm::Constant *CGObjCMac::getNSConstantIntegerNumberClassRef() {
2146 llvm_unreachable(
"constant number literals not supported for fragile ABI");
2149llvm::Constant *CGObjCMac::getNSConstantFloatNumberClassRef() {
2150 llvm_unreachable(
"constant number literals not supported for fragile ABI");
2153llvm::Constant *CGObjCMac::getNSConstantDoubleNumberClassRef() {
2154 llvm_unreachable(
"constant number literals not supported for fragile ABI");
2157llvm::Constant *CGObjCNonFragileABIMac::getNSConstantStringClassRef() {
2158 if (llvm::Value *
V = ConstantStringClassRef)
2162 std::string str = StringClass.empty() ?
"OBJC_CLASS_$_NSConstantString"
2163 :
"OBJC_CLASS_$_" + StringClass;
2165 ConstantStringClassRef = GV;
2169llvm::Constant *CGObjCNonFragileABIMac::getNSConstantArrayClassRef() {
2170 if (llvm::Value *
V = ConstantArrayClassRef)
2174 std::string Str = ArrayClass.empty() ?
"OBJC_CLASS_$_NSConstantArray"
2175 :
"OBJC_CLASS_$_" + ArrayClass;
2178 ConstantArrayClassRef = GV;
2182llvm::Constant *CGObjCNonFragileABIMac::getNSConstantDictionaryClassRef() {
2183 if (llvm::Value *
V = ConstantDictionaryClassRef)
2186 const std::string &DictionaryClass =
2188 std::string Str = DictionaryClass.empty()
2189 ?
"OBJC_CLASS_$_NSConstantDictionary"
2190 :
"OBJC_CLASS_$_" + DictionaryClass;
2193 ConstantDictionaryClassRef = GV;
2197llvm::Constant *CGObjCNonFragileABIMac::getNSConstantIntegerNumberClassRef() {
2198 if (llvm::Value *
V = ConstantIntegerNumberClassRef)
2201 const std::string &NumberClass =
2203 std::string Str = NumberClass.empty() ?
"OBJC_CLASS_$_NSConstantIntegerNumber"
2204 :
"OBJC_CLASS_$_" + NumberClass;
2207 ConstantIntegerNumberClassRef = GV;
2211llvm::Constant *CGObjCNonFragileABIMac::getNSConstantFloatNumberClassRef() {
2212 if (llvm::Value *
V = ConstantFloatNumberClassRef)
2215 const std::string &NumberClass =
2217 std::string Str = NumberClass.empty() ?
"OBJC_CLASS_$_NSConstantFloatNumber"
2218 :
"OBJC_CLASS_$_" + NumberClass;
2221 ConstantFloatNumberClassRef = GV;
2225llvm::Constant *CGObjCNonFragileABIMac::getNSConstantDoubleNumberClassRef() {
2226 if (llvm::Value *
V = ConstantDoubleNumberClassRef)
2229 const std::string &NumberClass =
2231 std::string Str = NumberClass.empty() ?
"OBJC_CLASS_$_NSConstantDoubleNumber"
2232 :
"OBJC_CLASS_$_" + NumberClass;
2235 ConstantDoubleNumberClassRef = GV;
2240CGObjCCommonMac::GenerateConstantNSString(
const StringLiteral *Literal) {
2241 unsigned StringLength = 0;
2242 llvm::StringMapEntry<llvm::GlobalVariable *> &Entry =
2245 if (
auto *
C = Entry.second)
2246 return ConstantAddress(
C,
C->getValueType(),
2250 llvm::Constant *
Class = getNSConstantStringClassRef();
2253 if (!NSConstantStringType) {
2257 NSConstantStringType =
2259 "struct.__builtin_NSString");
2262 ConstantInitBuilder Builder(CGM);
2263 auto Fields = Builder.beginStruct(NSConstantStringType);
2266 Fields.addSignedPointer(
Class,
2268 GlobalDecl(), QualType());
2272 llvm::ConstantDataArray::getString(VMContext, Entry.first());
2274 llvm::GlobalValue::LinkageTypes
Linkage = llvm::GlobalValue::PrivateLinkage;
2275 bool isConstant = !CGM.
getLangOpts().WritableStrings;
2277 auto *GV =
new llvm::GlobalVariable(CGM.
getModule(),
C->getType(), isConstant,
2279 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2282 GV->setAlignment(llvm::Align(1));
2286 Fields.addInt(CGM.
IntTy, StringLength);
2290 GV = Fields.finishAndCreateGlobal(
"_unnamed_nsstring_", Alignment,
2292 llvm::GlobalVariable::PrivateLinkage);
2293 const char *NSStringSection =
"__OBJC,__cstring_object,regular,no_dead_strip";
2294 const char *NSStringNonFragileABISection =
2295 "__DATA,__objc_stringobj,regular,no_dead_strip";
2298 ? NSStringNonFragileABISection
2302 return ConstantAddress(GV, GV->getValueType(), Alignment);
2306ConstantAddress CGObjCCommonMac::GenerateConstantNSNumber(
const bool Value,
2307 const QualType &Ty) {
2308 llvm::GlobalVariable *Val =
2309 Value ? EmitConstantCFBooleanTrue() : EmitConstantCFBooleanFalse();
2310 return ConstantAddress(Val, Val->getValueType(), CGM.
getPointerAlign());
2323CGObjCCommonMac::GenerateConstantNSNumber(
const llvm::APSInt &
Value,
2324 const QualType &Ty) {
2328 llvm::GlobalVariable *&Entry =
2331 return ConstantAddress(Entry, Entry->getValueType(), Alignment);
2335 std::string ObjCEncodingType;
2336 CodeGenFunction(CGM).getContext().getObjCEncodingForType(Ty,
2339 llvm::Constant *
const Class = getNSConstantIntegerNumberClassRef();
2341 if (!NSConstantIntegerNumberType) {
2342 NSConstantIntegerNumberType = llvm::StructType::create(
2348 "struct.__builtin_NSConstantIntegerNumber");
2351 ConstantInitBuilder Builder(CGM);
2352 auto Fields = Builder.beginStruct(NSConstantIntegerNumberType);
2355 Fields.addSignedPointer(
Class,
2357 GlobalDecl(), QualType());
2363 llvm::Constant *IntegerValue =
2364 llvm::ConstantInt::get(CGM.
Int64Ty,
Value.extOrTrunc(64));
2366 Fields.add(IntegerValue);
2369 llvm::GlobalVariable *
const GV = Fields.finishAndCreateGlobal(
2370 "_unnamed_nsconstantintegernumber_", Alignment,
2371 true, llvm::GlobalVariable::PrivateLinkage);
2373 GV->setSection(GetNSConstantIntegerNumberSectionName());
2374 GV->addAttribute(
"objc_arc_inert");
2378 return ConstantAddress(GV, GV->getValueType(), Alignment);
2396CGObjCCommonMac::GenerateConstantNSNumber(
const llvm::APFloat &
Value,
2397 const QualType &Ty) {
2401 llvm::GlobalVariable *&Entry =
2404 return ConstantAddress(Entry, Entry->getValueType(), Alignment);
2408 std::string ObjCEncodingType;
2409 CodeGenFunction(CGM).getContext().getObjCEncodingForType(Ty,
2412 assert((ObjCEncodingType ==
"d" || ObjCEncodingType ==
"f") &&
2413 "Unexpected or unknown ObjCEncodingType used in constant NSNumber");
2415 llvm::GlobalValue::LinkageTypes
Linkage =
2416 llvm::GlobalVariable::PrivateLinkage;
2419 if (ObjCEncodingType ==
"f") {
2420 llvm::Constant *
const Class = getNSConstantFloatNumberClassRef();
2422 if (!NSConstantFloatNumberType) {
2423 NSConstantFloatNumberType = llvm::StructType::create(
2428 "struct.__builtin_NSConstantFloatNumber");
2431 ConstantInitBuilder Builder(CGM);
2432 auto Fields = Builder.beginStruct(NSConstantFloatNumberType);
2435 Fields.addSignedPointer(
Class,
2437 GlobalDecl(), QualType());
2440 llvm::Constant *FV = llvm::ConstantFP::get(CGM.
FloatTy,
Value);
2444 llvm::GlobalVariable *
const GV = Fields.finishAndCreateGlobal(
2445 "_unnamed_nsconstantfloatnumber_", Alignment,
2448 GV->setSection(GetNSConstantFloatNumberSectionName());
2449 GV->addAttribute(
"objc_arc_inert");
2453 return ConstantAddress(GV, GV->getValueType(), Alignment);
2456 llvm::Constant *
const Class = getNSConstantDoubleNumberClassRef();
2457 if (!NSConstantDoubleNumberType) {
2459 NSConstantDoubleNumberType = llvm::StructType::create(
2464 "struct.__builtin_NSConstantDoubleNumber");
2467 ConstantInitBuilder Builder(CGM);
2468 auto Fields = Builder.beginStruct(NSConstantDoubleNumberType);
2471 Fields.addSignedPointer(
Class,
2473 GlobalDecl(), QualType());
2476 llvm::Constant *DV = llvm::ConstantFP::get(CGM.
DoubleTy,
Value);
2480 llvm::GlobalVariable *
const GV = Fields.finishAndCreateGlobal(
2481 "_unnamed_nsconstantdoublenumber_", Alignment,
2484 GV->setSection(GetNSConstantDoubleNumberSectionName());
2485 GV->addAttribute(
"objc_arc_inert");
2489 return ConstantAddress(GV, GV->getValueType(), Alignment);
2494llvm::GlobalVariable *
2495CGObjCCommonMac::EmitNSConstantCollectionLiteralArrayStorage(
2496 const ArrayRef<llvm::Constant *> &Elements) {
2497 llvm::Type *ElementsTy = Elements[0]->getType();
2498 llvm::ArrayType *ArrayTy = llvm::ArrayType::get(ElementsTy, Elements.size());
2500 llvm::Constant *
const ArrayData = llvm::ConstantArray::get(ArrayTy, Elements);
2502 llvm::GlobalVariable *ObjectsGV =
new llvm::GlobalVariable(
2503 CGM.
getModule(), ArrayTy,
true, llvm::GlobalValue::InternalLinkage,
2504 ArrayData,
"_unnamed_array_storage");
2507 ObjectsGV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2508 ObjectsGV->setSection(GetNSConstantCollectionStorageSectionName());
2521ConstantAddress CGObjCCommonMac::GenerateConstantNSArray(
2522 const ArrayRef<llvm::Constant *> &Objects) {
2525 if (Objects.size() == 0) {
2526 llvm::GlobalVariable *GV = EmitEmptyConstantNSArray();
2527 return ConstantAddress(GV, GV->getValueType(), Alignment);
2531 CodeGenTypes &Types = CGM.
getTypes();
2532 llvm::Constant *
const Class = getNSConstantArrayClassRef();
2533 llvm::Type *
const NSUIntegerTy =
2536 if (!NSConstantArrayType) {
2537 NSConstantArrayType = llvm::StructType::create(
2543 "struct.__builtin_NSArray");
2546 ConstantInitBuilder Builder(CGM);
2547 auto Fields = Builder.beginStruct(NSConstantArrayType);
2550 Fields.addSignedPointer(
Class,
2552 GlobalDecl(), QualType());
2555 uint64_t ObjectCount = Objects.size();
2556 llvm::Constant *Count = llvm::ConstantInt::get(NSUIntegerTy, ObjectCount);
2560 llvm::GlobalVariable *ObjectsGV =
2561 EmitNSConstantCollectionLiteralArrayStorage(Objects);
2562 Fields.add(ObjectsGV);
2565 llvm::GlobalVariable *GV = Fields.finishAndCreateGlobal(
2566 "_unnamed_nsarray_", Alignment,
2567 true, llvm::GlobalValue::PrivateLinkage);
2569 GV->setSection(GetNSConstantArraySectionName());
2570 GV->addAttribute(
"objc_arc_inert");
2572 return ConstantAddress(GV, GV->getValueType(), Alignment);
2587ConstantAddress CGObjCCommonMac::GenerateConstantNSDictionary(
2588 const ObjCDictionaryLiteral *E,
2589 ArrayRef<std::pair<llvm::Constant *, llvm::Constant *>> KeysAndObjects) {
2592 if (KeysAndObjects.size() == 0) {
2593 llvm::GlobalVariable *GV = EmitEmptyConstantNSDictionary();
2594 return ConstantAddress(GV, GV->getValueType(), Alignment);
2598 CodeGenTypes &Types = CGM.
getTypes();
2599 llvm::Constant *
const Class = getNSConstantDictionaryClassRef();
2601 llvm::Type *
const NSUIntegerTy =
2604 if (!NSConstantDictionaryType) {
2605 NSConstantDictionaryType = llvm::StructType::create(
2613 "struct.__builtin_NSDictionary");
2616 ConstantInitBuilder Builder(CGM);
2617 auto Fields = Builder.beginStruct(NSConstantDictionaryType);
2620 Fields.addSignedPointer(
Class,
2622 GlobalDecl(), QualType());
2625 auto HashOpts(NSDictionaryBuilder::Options::Sorted);
2626 NSDictionaryBuilder DictBuilder(E, KeysAndObjects, HashOpts);
2629 uint64_t const NumElements = DictBuilder.getNumElements();
2631 llvm::Constant *OptionsConstant = llvm::ConstantInt::get(
2632 NSUIntegerTy,
static_cast<uint64_t>(DictBuilder.getOptions()));
2633 Fields.add(OptionsConstant);
2636 llvm::Constant *Count = llvm::ConstantInt::get(NSUIntegerTy, NumElements);
2640 SmallVector<llvm::Constant *, 16> SortedKeys, SortedObjects;
2641 SortedKeys.reserve(NumElements);
2642 SortedObjects.reserve(NumElements);
2643 for (
auto &[Key, Obj] : DictBuilder.getElements()) {
2644 SortedKeys.push_back(Key);
2645 SortedObjects.push_back(Obj);
2649 llvm::GlobalVariable *KeysGV =
2650 EmitNSConstantCollectionLiteralArrayStorage(SortedKeys);
2654 llvm::GlobalVariable *ObjectsGV =
2655 EmitNSConstantCollectionLiteralArrayStorage(SortedObjects);
2656 Fields.add(ObjectsGV);
2659 llvm::GlobalVariable *GV = Fields.finishAndCreateGlobal(
2660 "_unnamed_nsdictionary_", Alignment,
2661 true, llvm::GlobalValue::PrivateLinkage);
2663 GV->setSection(GetNSConstantDictionarySectionName());
2664 GV->addAttribute(
"objc_arc_inert");
2666 return ConstantAddress(GV, GV->getValueType(), Alignment);
2674CodeGen::RValue CGObjCMac::GenerateMessageSendSuper(
2675 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
2676 Selector Sel,
const ObjCInterfaceDecl *
Class,
bool isCategoryImpl,
2677 llvm::Value *Receiver,
bool IsClassMessage,
2678 const CodeGen::CallArgList &CallArgs,
const ObjCMethodDecl *
Method) {
2683 llvm::Value *ReceiverAsObject =
2684 CGF.
Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
2689 llvm::Type *ClassTyPtr = llvm::PointerType::getUnqual(VMContext);
2691 if (IsClassMessage) {
2692 if (isCategoryImpl) {
2699 Target = EmitClassRef(CGF,
Class->getSuperClass());
2704 llvm::Constant *MetaClassPtr = EmitMetaClassRef(
Class);
2705 llvm::Value *SuperPtr =
2711 }
else if (isCategoryImpl)
2712 Target = EmitClassRef(CGF,
Class->getSuperClass());
2714 llvm::Value *ClassPtr = EmitSuperClassRef(
Class);
2721 llvm::Type *ClassTy =
2725 return EmitMessageSend(CGF, Return, ResultType, Sel, ObjCSuper.
getPointer(),
2726 ObjCTypes.SuperPtrCTy,
true, CallArgs,
Method,
Class,
2731CodeGen::RValue CGObjCMac::GenerateMessageSend(
2732 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
2733 Selector Sel, llvm::Value *Receiver,
const CallArgList &CallArgs,
2734 const ObjCInterfaceDecl *
Class,
const ObjCMethodDecl *
Method) {
2735 return EmitMessageSend(CGF, Return, ResultType, Sel, Receiver,
2740CodeGen::RValue CGObjCCommonMac::EmitMessageSend(
2741 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
2742 Selector Sel, llvm::Value *Arg0, QualType Arg0Ty,
bool IsSuper,
2743 const CallArgList &CallArgs,
const ObjCMethodDecl *
Method,
2744 const ObjCInterfaceDecl *ClassReceiver,
2745 const ObjCCommonTypesHelper &ObjCTypes) {
2746 CodeGenTypes &Types = CGM.
getTypes();
2748 llvm::Value *ReceiverValue =
2749 llvm::PoisonValue::get(Types.
ConvertType(Arg0Ty));
2750 llvm::Value *SelValue = llvm::UndefValue::get(Types.
ConvertType(selTy));
2752 CallArgList ActualArgs;
2754 Arg0 = CGF.
Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy);
2761 MessageSendInfo MSI = getMessageSendInfo(
Method, ResultType, ActualArgs);
2766 "Result type mismatch!");
2768 bool ReceiverCanBeNull =
2769 canMessageReceiverBeNull(CGF,
Method, IsSuper, ClassReceiver, Arg0);
2770 bool ClassObjectCanBeUnrealized =
2772 canClassObjectBeUnrealized(ClassReceiver, CGF);
2774 bool RequiresNullCheck =
false;
2775 bool RequiresReceiverValue =
true;
2776 bool RequiresSelValue =
true;
2778 llvm::FunctionCallee
Fn =
nullptr;
2782 ReceiverCanBeNull, ClassObjectCanBeUnrealized);
2785 RequiresSelValue =
false;
2787 if (ReceiverCanBeNull)
2788 RequiresNullCheck =
true;
2789 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
2790 : ObjCTypes.getSendStretFn(IsSuper);
2792 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
2793 : ObjCTypes.getSendFpretFn(IsSuper);
2795 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)
2796 : ObjCTypes.getSendFp2retFn(IsSuper);
2801 RequiresNullCheck =
true;
2803 StringRef ClassName;
2809 if (CGM.
getCodeGenOpts().ObjCMsgSendClassSelectorStubs && ClassReceiver &&
2811 !ClassReceiver->
hasAttr<ObjCClassStubAttr>() &&
2812 !ClassReceiver->
hasAttr<ObjCRuntimeVisibleAttr>() &&
2816 bool UseClassStub = ClassName.data();
2819 (CGM.
getCodeGenOpts().ObjCMsgSendSelectorStubs || UseClassStub)) {
2820 Fn = GenerateMethodSelectorStub(Sel, ClassName, ObjCTypes);
2822 RequiresReceiverValue = !UseClassStub;
2823 RequiresSelValue =
false;
2825 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
2826 : ObjCTypes.getSendFn(IsSuper);
2832 CGF.
Builder.CreateBitCast(
Fn.getCallee(), MSI.MessengerType));
2837 RequiresNullCheck =
false;
2840 if (!RequiresNullCheck &&
Method &&
Method->hasParamDestroyedInCallee())
2841 RequiresNullCheck =
true;
2848 if (ClassReceiver && ClassObjectCanBeUnrealized) {
2850 Arg0 = GenerateClassRealization(CGF, Arg0, ClassReceiver);
2851 ActualArgs[0] = CallArg(
RValue::get(Arg0), ActualArgs[0].Ty);
2857 RequiresNullCheck |= ReceiverCanBeNull;
2860 NullReturnState nullReturn;
2861 if (RequiresNullCheck) {
2862 nullReturn.init(CGF, Arg0);
2866 if (RequiresReceiverValue)
2867 ActualArgs[0] = CallArg(
RValue::get(Arg0), Arg0Ty);
2870 if (RequiresSelValue) {
2871 SelValue = GetSelector(CGF, Sel);
2872 ActualArgs[1] = CallArg(
RValue::get(SelValue), selTy);
2875 llvm::CallBase *CallSite;
2878 CGF.
EmitCall(MSI.CallInfo, Callee, Return, ActualArgs, &CallSite);
2882 if (
Method &&
Method->hasAttr<NoReturnAttr>() && !ReceiverCanBeNull) {
2883 CallSite->setDoesNotReturn();
2886 return nullReturn.complete(CGF, Return, rvalue, ResultType, CallArgs,
2887 RequiresNullCheck ?
Method :
nullptr);
2891 bool pointee =
false) {
2905 switch (ownership) {
2913 llvm_unreachable(
"autoreleasing ivar?");
2915 llvm_unreachable(
"known nonzero");
2917 llvm_unreachable(
"bad objc ownership");
2937 IvarInfo(CharUnits offset, uint64_t sizeInWords)
2938 : Offset(offset), SizeInWords(sizeInWords) {}
2941 bool operator<(
const IvarInfo &other)
const {
return Offset < other.Offset; }
2945class IvarLayoutBuilder {
2950 CharUnits InstanceBegin;
2953 CharUnits InstanceEnd;
2956 bool ForStrongLayout;
2959 bool IsDisordered =
false;
2961 llvm::SmallVector<IvarInfo, 8> IvarsInfo;
2964 IvarLayoutBuilder(CodeGenModule &CGM, CharUnits instanceBegin,
2965 CharUnits instanceEnd,
bool forStrongLayout)
2966 : CGM(CGM), InstanceBegin(instanceBegin), InstanceEnd(instanceEnd),
2967 ForStrongLayout(forStrongLayout) {}
2969 void visitRecord(
const RecordType *RT, CharUnits offset);
2971 template <
class Iterator,
class GetOffsetFn>
2972 void visitAggregate(Iterator begin, Iterator end, CharUnits aggrOffset,
2973 const GetOffsetFn &getOffset);
2975 void visitField(
const FieldDecl *field, CharUnits offset);
2978 void visitBlock(
const CGBlockInfo &blockInfo);
2981 bool hasBitmapData()
const {
return !IvarsInfo.empty(); }
2983 llvm::Constant *buildBitmap(CGObjCCommonMac &CGObjC,
2984 llvm::SmallVectorImpl<unsigned char> &buffer);
2986 static void dump(ArrayRef<unsigned char> buffer) {
2987 const unsigned char *s = buffer.data();
2988 for (
unsigned i = 0, e = buffer.size(); i < e; i++)
2990 printf(
"0x0%x%s", s[i], s[i] != 0 ?
", " :
"");
2992 printf(
"0x%x%s", s[i], s[i] != 0 ?
", " :
"");
2999CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,
3000 const CGBlockInfo &blockInfo) {
3002 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
3003 if (CGM.
getLangOpts().getGC() == LangOptions::NonGC)
3009 builder.visitBlock(blockInfo);
3011 if (!builder.hasBitmapData())
3014 llvm::SmallVector<unsigned char, 32> buffer;
3015 llvm::Constant *
C = builder.buildBitmap(*
this, buffer);
3016 if (CGM.
getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
3017 printf(
"\n block variable layout for block: ");
3018 builder.dump(buffer);
3024void IvarLayoutBuilder::visitBlock(
const CGBlockInfo &blockInfo) {
3034 CharUnits lastFieldOffset;
3037 for (
const auto &CI :
blockDecl->captures()) {
3038 const VarDecl *variable = CI.getVariable();
3041 const CGBlockInfo::Capture &capture = blockInfo.
getCapture(variable);
3047 CharUnits fieldOffset = capture.
getOffset();
3051 if (fieldOffset < lastFieldOffset)
3052 IsDisordered =
true;
3053 lastFieldOffset = fieldOffset;
3057 IvarsInfo.push_back(IvarInfo(fieldOffset, 1));
3061 assert(!
type->isArrayType() &&
"array variable should not be caught");
3062 if (
const RecordType *record =
type->getAsCanonical<RecordType>()) {
3063 visitRecord(record, fieldOffset);
3072 IvarsInfo.push_back(IvarInfo(fieldOffset, 1));
3081CGObjCCommonMac::getBlockCaptureLifetime(QualType FQT,
bool ByrefLayout) {
3097void CGObjCCommonMac::UpdateRunSkipBlockVars(
bool IsByref,
3099 CharUnits FieldOffset,
3100 CharUnits FieldSize) {
3103 RunSkipBlockVars.push_back(
3104 RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset, FieldSize));
3106 RunSkipBlockVars.push_back(
3107 RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset, FieldSize));
3109 RunSkipBlockVars.push_back(
3110 RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset, FieldSize));
3112 RunSkipBlockVars.push_back(
3113 RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset, FieldSize));
3115 RunSkipBlockVars.push_back(
3116 RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES, FieldOffset, FieldSize));
3119void CGObjCCommonMac::BuildRCRecordLayout(
const llvm::StructLayout *RecLayout,
3120 const RecordDecl *RD,
3121 ArrayRef<const FieldDecl *> RecFields,
3122 CharUnits BytePos,
bool &HasUnion,
3124 bool IsUnion = (RD && RD->
isUnion());
3126 const FieldDecl *MaxField =
nullptr;
3127 const FieldDecl *LastFieldBitfieldOrUnnamed =
nullptr;
3131 if (RecFields.empty())
3135 for (
unsigned i = 0, e = RecFields.size(); i != e; ++i) {
3136 const FieldDecl *
Field = RecFields[i];
3140 CharUnits FieldOffset =
3144 if (!
Field->getIdentifier() ||
Field->isBitField()) {
3145 LastFieldBitfieldOrUnnamed =
Field;
3146 LastBitfieldOrUnnamedOffset = FieldOffset;
3150 LastFieldBitfieldOrUnnamed =
nullptr;
3151 QualType FQT =
Field->getType();
3157 BytePos + FieldOffset, HasUnion);
3163 uint64_t ElCount = CArray->getZExtSize();
3164 assert(CArray &&
"only array with known element size is supported");
3165 FQT = CArray->getElementType();
3168 ElCount *= CArray->getZExtSize();
3169 FQT = CArray->getElementType();
3172 int OldIndex = RunSkipBlockVars.size() - 1;
3174 BuildRCBlockVarRecordLayout(RT, BytePos + FieldOffset, HasUnion);
3179 for (
int FirstIndex = RunSkipBlockVars.size() - 1; ElIx < ElCount;
3182 for (
int i = OldIndex + 1; i <= FirstIndex; ++i)
3183 RunSkipBlockVars.push_back(
3184 RUN_SKIP(RunSkipBlockVars[i].opcode,
3185 RunSkipBlockVars[i].block_var_bytepos + Size * ElIx,
3186 RunSkipBlockVars[i].block_var_size));
3193 CharUnits UnionIvarSize = FieldSize;
3194 if (UnionIvarSize > MaxUnionSize) {
3195 MaxUnionSize = UnionIvarSize;
3197 MaxFieldOffset = FieldOffset;
3200 UpdateRunSkipBlockVars(
false, getBlockCaptureLifetime(FQT, ByrefLayout),
3201 BytePos + FieldOffset, FieldSize);
3205 if (LastFieldBitfieldOrUnnamed) {
3206 if (LastFieldBitfieldOrUnnamed->
isBitField()) {
3209 unsigned UnsSize = (BitFieldSize / ByteSizeInBits) +
3210 ((BitFieldSize % ByteSizeInBits) != 0);
3212 Size += LastBitfieldOrUnnamedOffset;
3213 UpdateRunSkipBlockVars(
3215 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
3217 BytePos + LastBitfieldOrUnnamedOffset, Size);
3220 "Expected unnamed");
3223 LastFieldBitfieldOrUnnamed->
getType());
3224 UpdateRunSkipBlockVars(
3226 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
3228 BytePos + LastBitfieldOrUnnamedOffset, FieldSize);
3233 UpdateRunSkipBlockVars(
3234 false, getBlockCaptureLifetime(MaxField->
getType(), ByrefLayout),
3235 BytePos + MaxFieldOffset, MaxUnionSize);
3238void CGObjCCommonMac::BuildRCBlockVarRecordLayout(
const RecordType *RT,
3243 SmallVector<const FieldDecl *, 16> Fields(RD->
fields());
3245 const llvm::StructLayout *RecLayout =
3248 BuildRCRecordLayout(RecLayout, RD, Fields, BytePos, HasUnion, ByrefLayout);
3260uint64_t CGObjCCommonMac::InlineLayoutInstruction(
3261 SmallVectorImpl<unsigned char> &Layout) {
3263 if (Layout.size() <= 3) {
3264 unsigned size = Layout.size();
3265 unsigned strong_word_count = 0, byref_word_count = 0, weak_word_count = 0;
3267 enum BLOCK_LAYOUT_OPCODE opcode;
3271 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3272 if (opcode == BLOCK_LAYOUT_STRONG)
3273 strong_word_count = (inst & 0xF) + 1;
3277 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3278 if (opcode == BLOCK_LAYOUT_BYREF)
3279 byref_word_count = (inst & 0xF) + 1;
3283 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3284 if (opcode == BLOCK_LAYOUT_WEAK)
3285 weak_word_count = (inst & 0xF) + 1;
3292 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3293 if (opcode == BLOCK_LAYOUT_STRONG) {
3294 strong_word_count = (inst & 0xF) + 1;
3296 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3297 if (opcode == BLOCK_LAYOUT_BYREF)
3298 byref_word_count = (inst & 0xF) + 1;
3299 else if (opcode == BLOCK_LAYOUT_WEAK)
3300 weak_word_count = (inst & 0xF) + 1;
3303 }
else if (opcode == BLOCK_LAYOUT_BYREF) {
3304 byref_word_count = (inst & 0xF) + 1;
3306 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3307 if (opcode == BLOCK_LAYOUT_WEAK)
3308 weak_word_count = (inst & 0xF) + 1;
3317 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3318 if (opcode == BLOCK_LAYOUT_STRONG)
3319 strong_word_count = (inst & 0xF) + 1;
3320 else if (opcode == BLOCK_LAYOUT_BYREF)
3321 byref_word_count = (inst & 0xF) + 1;
3322 else if (opcode == BLOCK_LAYOUT_WEAK)
3323 weak_word_count = (inst & 0xF) + 1;
3335 if (strong_word_count == 16 || byref_word_count == 16 ||
3336 weak_word_count == 16)
3339 unsigned count = (strong_word_count != 0) + (byref_word_count != 0) +
3340 (weak_word_count != 0);
3342 if (size == count) {
3343 if (strong_word_count)
3344 Result = strong_word_count;
3346 if (byref_word_count)
3347 Result += byref_word_count;
3349 if (weak_word_count)
3350 Result += weak_word_count;
3356llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(
bool ComputeByrefLayout) {
3357 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
3358 if (RunSkipBlockVars.empty())
3362 unsigned WordSizeInBytes = WordSizeInBits / ByteSizeInBits;
3366 llvm::array_pod_sort(RunSkipBlockVars.begin(), RunSkipBlockVars.end());
3367 SmallVector<unsigned char, 16> Layout;
3369 unsigned size = RunSkipBlockVars.size();
3370 for (
unsigned i = 0; i < size; i++) {
3371 enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode;
3372 CharUnits start_byte_pos = RunSkipBlockVars[i].block_var_bytepos;
3373 CharUnits end_byte_pos = start_byte_pos;
3376 if (opcode == RunSkipBlockVars[j].opcode) {
3377 end_byte_pos = RunSkipBlockVars[j++].block_var_bytepos;
3382 CharUnits size_in_bytes =
3383 end_byte_pos - start_byte_pos + RunSkipBlockVars[j - 1].block_var_size;
3385 CharUnits gap = RunSkipBlockVars[j].block_var_bytepos -
3386 RunSkipBlockVars[j - 1].block_var_bytepos -
3387 RunSkipBlockVars[j - 1].block_var_size;
3388 size_in_bytes += gap;
3391 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) {
3392 residue_in_bytes = size_in_bytes % WordSizeInBytes;
3393 size_in_bytes -= residue_in_bytes;
3394 opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS;
3397 unsigned size_in_words = size_in_bytes.
getQuantity() / WordSizeInBytes;
3398 while (size_in_words >= 16) {
3401 unsigned char inst = (opcode << 4) | 0xf;
3402 Layout.push_back(inst);
3403 size_in_words -= 16;
3405 if (size_in_words > 0) {
3408 unsigned char inst = (opcode << 4) | (size_in_words - 1);
3409 Layout.push_back(inst);
3412 unsigned char inst = (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) |
3414 Layout.push_back(inst);
3418 while (!Layout.empty()) {
3419 unsigned char inst = Layout.back();
3420 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3421 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES ||
3422 opcode == BLOCK_LAYOUT_NON_OBJECT_WORDS)
3432 if (ComputeByrefLayout)
3433 printf(
"\n Inline BYREF variable layout: ");
3435 printf(
"\n Inline block variable layout: ");
3437 if (
auto numStrong = (
Result & 0xF00) >> 8)
3438 printf(
", BL_STRONG:%d", (
int)numStrong);
3439 if (
auto numByref = (
Result & 0x0F0) >> 4)
3440 printf(
", BL_BYREF:%d", (
int)numByref);
3441 if (
auto numWeak = (
Result & 0x00F) >> 0)
3442 printf(
", BL_WEAK:%d", (
int)numWeak);
3443 printf(
", BL_OPERATOR:0\n");
3448 unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0;
3449 Layout.push_back(inst);
3451 for (
unsigned char C : Layout)
3455 if (ComputeByrefLayout)
3456 printf(
"\n Byref variable layout: ");
3458 printf(
"\n Block variable layout: ");
3459 for (
unsigned i = 0, e = BitMap.size(); i != e; i++) {
3460 unsigned char inst = BitMap[i];
3461 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3464 case BLOCK_LAYOUT_OPERATOR:
3468 case BLOCK_LAYOUT_NON_OBJECT_BYTES:
3469 printf(
"BL_NON_OBJECT_BYTES:");
3471 case BLOCK_LAYOUT_NON_OBJECT_WORDS:
3472 printf(
"BL_NON_OBJECT_WORD:");
3474 case BLOCK_LAYOUT_STRONG:
3477 case BLOCK_LAYOUT_BYREF:
3480 case BLOCK_LAYOUT_WEAK:
3483 case BLOCK_LAYOUT_UNRETAINED:
3484 printf(
"BL_UNRETAINED:");
3489 printf(
"%d", (inst & 0xf) + delta);
3497 auto *Entry = CreateCStringLiteral(BitMap, ObjCLabelType::LayoutBitMap,
3505 bool HasCopyDisposeHelpers) {
3507 for (
const CGObjCCommonMac::RUN_SKIP &R : RunSkipBlockVars) {
3508 if (R.opcode == CGObjCCommonMac::BLOCK_LAYOUT_UNRETAINED) {
3512 }
else if (HasCopyDisposeHelpers) {
3520 case CGObjCCommonMac::BLOCK_LAYOUT_STRONG:
3523 case CGObjCCommonMac::BLOCK_LAYOUT_BYREF:
3526 case CGObjCCommonMac::BLOCK_LAYOUT_WEAK:
3533 Str += llvm::to_string(R.block_var_bytepos.getQuantity());
3534 Str +=
"l" + llvm::to_string(R.block_var_size.getQuantity());
3539void CGObjCCommonMac::fillRunSkipBlockVars(CodeGenModule &CGM,
3540 const CGBlockInfo &blockInfo) {
3541 assert(CGM.
getLangOpts().getGC() == LangOptions::NonGC);
3543 RunSkipBlockVars.clear();
3544 bool hasUnion =
false;
3548 unsigned WordSizeInBytes = WordSizeInBits / ByteSizeInBits;
3553 const llvm::StructLayout *layout =
3563 for (
const auto &CI :
blockDecl->captures()) {
3564 const VarDecl *variable = CI.getVariable();
3567 const CGBlockInfo::Capture &capture = blockInfo.
getCapture(variable);
3573 CharUnits fieldOffset =
3576 assert(!
type->isArrayType() &&
"array variable should not be caught");
3578 if (
const auto *record =
type->getAsCanonical<RecordType>()) {
3579 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion);
3582 CharUnits fieldSize;
3587 UpdateRunSkipBlockVars(CI.isByRef(), getBlockCaptureLifetime(
type,
false),
3588 fieldOffset, fieldSize);
3593CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM,
3594 const CGBlockInfo &blockInfo) {
3595 fillRunSkipBlockVars(CGM, blockInfo);
3596 return getBitmapBlockLayout(
false);
3599std::string CGObjCCommonMac::getRCBlockLayoutStr(CodeGenModule &CGM,
3600 const CGBlockInfo &blockInfo) {
3601 fillRunSkipBlockVars(CGM, blockInfo);
3605llvm::Constant *CGObjCCommonMac::BuildByrefLayout(CodeGen::CodeGenModule &CGM,
3607 assert(CGM.
getLangOpts().getGC() == LangOptions::NonGC);
3608 assert(!T->
isArrayType() &&
"__block array variable should not be caught");
3609 CharUnits fieldOffset;
3610 RunSkipBlockVars.clear();
3611 bool hasUnion =
false;
3613 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion,
3615 llvm::Constant *
Result = getBitmapBlockLayout(
true);
3620 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
3624llvm::Value *CGObjCMac::GenerateProtocolRef(CodeGenFunction &CGF,
3625 const ObjCProtocolDecl *PD) {
3630 return GetProtocolRef(PD);
3633void CGObjCCommonMac::GenerateProtocol(
const ObjCProtocolDecl *PD) {
3642 GetOrEmitProtocol(PD);
3645llvm::Constant *CGObjCCommonMac::GetProtocolRef(
const ObjCProtocolDecl *PD) {
3647 return GetOrEmitProtocol(PD);
3649 return GetOrEmitProtocolRef(PD);
3653CGObjCCommonMac::EmitClassRefViaRuntime(CodeGenFunction &CGF,
3654 const ObjCInterfaceDecl *ID,
3655 ObjCCommonTypesHelper &ObjCTypes) {
3656 llvm::FunctionCallee lookUpClassFn = ObjCTypes.getLookUpClassFn();
3658 llvm::Value *className = CGF.
CGM
3660 ID->getObjCRuntimeNameAsString()))
3663 className = CGF.
Builder.CreateBitCast(
3665 llvm::CallInst *call = CGF.
Builder.CreateCall(lookUpClassFn, className);
3666 call->setDoesNotThrow();
3682llvm::Constant *CGObjCMac::GetOrEmitProtocol(
const ObjCProtocolDecl *PD) {
3683 llvm::GlobalVariable *Entry = Protocols[PD->
getIdentifier()];
3686 if (Entry && Entry->hasInitializer())
3698 auto methodLists = ProtocolMethodLists::get(PD);
3700 ConstantInitBuilder builder(CGM);
3701 auto values = builder.beginStruct(ObjCTypes.ProtocolTy);
3702 values.add(EmitProtocolExtension(PD, methodLists));
3704 values.add(EmitProtocolList(
"OBJC_PROTOCOL_REFS_" + PD->
getName(),
3706 values.add(methodLists.emitMethodList(
3707 this, PD, ProtocolMethodLists::RequiredInstanceMethods));
3708 values.add(methodLists.emitMethodList(
3709 this, PD, ProtocolMethodLists::RequiredClassMethods));
3713 assert(Entry->hasPrivateLinkage());
3714 values.finishAndSetAsInitializer(Entry);
3716 Entry = values.finishAndCreateGlobal(
3718 false, llvm::GlobalValue::PrivateLinkage);
3719 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
3728llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD) {
3729 llvm::GlobalVariable *&Entry = Protocols[PD->
getIdentifier()];
3735 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolTy,
3736 false, llvm::GlobalValue::PrivateLinkage,
3737 nullptr,
"OBJC_PROTOCOL_" + PD->
getName());
3738 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
3740 Entry->setAlignment(llvm::Align(4));
3757CGObjCMac::EmitProtocolExtension(
const ObjCProtocolDecl *PD,
3758 const ProtocolMethodLists &methodLists) {
3759 auto optInstanceMethods = methodLists.emitMethodList(
3760 this, PD, ProtocolMethodLists::OptionalInstanceMethods);
3761 auto optClassMethods = methodLists.emitMethodList(
3762 this, PD, ProtocolMethodLists::OptionalClassMethods);
3764 auto extendedMethodTypes = EmitProtocolMethodTypes(
3765 "OBJC_PROTOCOL_METHOD_TYPES_" + PD->
getName(),
3766 methodLists.emitExtendedTypesArray(
this), ObjCTypes);
3768 auto instanceProperties = EmitPropertyList(
3769 "OBJC_$_PROP_PROTO_LIST_" + PD->
getName(),
nullptr, PD, ObjCTypes,
false);
3770 auto classProperties =
3771 EmitPropertyList(
"OBJC_$_CLASS_PROP_PROTO_LIST_" + PD->
getName(),
nullptr,
3772 PD, ObjCTypes,
true);
3775 if (optInstanceMethods->isNullValue() && optClassMethods->isNullValue() &&
3776 extendedMethodTypes->isNullValue() && instanceProperties->isNullValue() &&
3777 classProperties->isNullValue()) {
3778 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
3782 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
3784 ConstantInitBuilder builder(CGM);
3785 auto values = builder.beginStruct(ObjCTypes.ProtocolExtensionTy);
3786 values.addInt(ObjCTypes.IntTy, size);
3787 values.add(optInstanceMethods);
3788 values.add(optClassMethods);
3789 values.add(instanceProperties);
3790 values.add(extendedMethodTypes);
3791 values.add(classProperties);
3794 return CreateMetadataVar(
"_OBJC_PROTOCOLEXT_" + PD->
getName(), values,
3806CGObjCMac::EmitProtocolList(Twine name,
3810 auto PDs = GetRuntimeProtocolList(begin, end);
3812 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
3814 ConstantInitBuilder builder(CGM);
3815 auto values = builder.beginStruct();
3818 values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
3821 auto countSlot = values.addPlaceholder();
3823 auto refsArray = values.beginArray(ObjCTypes.ProtocolPtrTy);
3824 for (
const auto *Proto : PDs)
3825 refsArray.add(GetProtocolRef(Proto));
3827 auto count = refsArray.size();
3830 refsArray.addNullPointer(ObjCTypes.ProtocolPtrTy);
3832 refsArray.finishAndAddTo(values);
3833 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
3836 if (CGM.
getTriple().isOSBinFormatMachO())
3837 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3839 llvm::GlobalVariable *GV =
3840 CreateMetadataVar(name, values, section, CGM.
getPointerAlign(),
false);
3849 if (IsClassProperty != PD->isClassProperty())
3853 Properties.push_back(PD);
3856 for (
const auto *P : Proto->
protocols())
3872llvm::Constant *CGObjCCommonMac::EmitPropertyList(
3873 Twine Name,
const Decl *Container,
const ObjCContainerDecl *OCD,
3874 const ObjCCommonTypesHelper &ObjCTypes,
bool IsClassProperty) {
3875 if (IsClassProperty) {
3879 if ((Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 11)) ||
3880 (Triple.isiOS() && Triple.isOSVersionLT(9)))
3881 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3884 SmallVector<const ObjCPropertyDecl *, 16> Properties;
3885 llvm::SmallPtrSet<const IdentifierInfo *, 16> PropertySet;
3887 if (
const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD))
3888 for (
const ObjCCategoryDecl *ClassExt : OID->known_extensions())
3889 for (
auto *PD : ClassExt->properties()) {
3890 if (IsClassProperty != PD->isClassProperty())
3892 if (PD->isDirectProperty())
3895 Properties.push_back(PD);
3899 if (IsClassProperty != PD->isClassProperty())
3905 if (PD->isDirectProperty())
3907 Properties.push_back(PD);
3910 if (
const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) {
3911 for (
const auto *P : OID->all_referenced_protocols())
3913 }
else if (
const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD)) {
3914 for (
const auto *P : CD->protocols())
3919 if (Properties.empty())
3920 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3922 unsigned propertySize =
3925 ConstantInitBuilder builder(CGM);
3926 auto values = builder.beginStruct();
3927 values.addInt(ObjCTypes.IntTy, propertySize);
3928 values.addInt(ObjCTypes.IntTy, Properties.size());
3929 auto propertiesArray = values.beginArray(ObjCTypes.PropertyTy);
3930 for (
auto PD : Properties) {
3931 auto property = propertiesArray.beginStruct(ObjCTypes.PropertyTy);
3933 property.add(GetPropertyTypeString(PD, Container));
3934 property.finishAndAddTo(propertiesArray);
3936 propertiesArray.finishAndAddTo(values);
3939 if (CGM.
getTriple().isOSBinFormatMachO())
3940 Section = (ObjCABI == 2) ?
"__DATA, __objc_const"
3941 :
"__OBJC,__property,regular,no_dead_strip";
3943 llvm::GlobalVariable *GV =
3944 CreateMetadataVar(Name, values, Section, CGM.
getPointerAlign(),
true);
3948llvm::Constant *CGObjCCommonMac::EmitProtocolMethodTypes(
3949 Twine Name, ArrayRef<llvm::Constant *> MethodTypes,
3950 const ObjCCommonTypesHelper &ObjCTypes) {
3952 if (MethodTypes.empty())
3953 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy);
3955 llvm::ArrayType *AT =
3956 llvm::ArrayType::get(ObjCTypes.Int8PtrTy, MethodTypes.size());
3957 llvm::Constant *
Init = llvm::ConstantArray::get(AT, MethodTypes);
3960 if (CGM.
getTriple().isOSBinFormatMachO() && ObjCABI == 2)
3961 Section =
"__DATA, __objc_const";
3963 llvm::GlobalVariable *GV =
3980void CGObjCMac::GenerateCategory(
const ObjCCategoryImplDecl *OCD) {
3988 const ObjCCategoryDecl *Category =
3991 SmallString<256> ExtName;
3992 llvm::raw_svector_ostream(ExtName)
3995 ConstantInitBuilder Builder(CGM);
3996 auto Values = Builder.beginStruct(ObjCTypes.CategoryTy);
3998 enum { InstanceMethods, ClassMethods, NumMethodLists };
3999 SmallVector<const ObjCMethodDecl *, 16> Methods[NumMethodLists];
4000 for (
const auto *MD : OCD->
methods()) {
4001 if (!MD->isDirectMethod())
4002 Methods[unsigned(MD->isClassMethod())].push_back(MD);
4005 Values.add(GetClassName(OCD->
getName()));
4006 Values.add(GetClassName(
Interface->getObjCRuntimeNameAsString()));
4007 LazySymbols.insert(
Interface->getIdentifier());
4009 Values.add(emitMethodList(ExtName, MethodListType::CategoryInstanceMethods,
4010 Methods[InstanceMethods]));
4011 Values.add(emitMethodList(ExtName, MethodListType::CategoryClassMethods,
4012 Methods[ClassMethods]));
4014 Values.add(EmitProtocolList(
"OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
4015 Category->protocol_begin(),
4016 Category->protocol_end()));
4018 Values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
4020 Values.addInt(ObjCTypes.IntTy, Size);
4024 Values.add(EmitPropertyList(
"_OBJC_$_PROP_LIST_" + ExtName.str(), OCD,
4025 Category, ObjCTypes,
false));
4026 Values.add(EmitPropertyList(
"_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(), OCD,
4027 Category, ObjCTypes,
true));
4029 Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
4030 Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
4033 llvm::GlobalVariable *GV = CreateMetadataVar(
4034 "OBJC_CATEGORY_" + ExtName.str(), Values,
4035 "__OBJC,__category,regular,no_dead_strip", CGM.
getPointerAlign(),
true);
4036 DefinedCategories.push_back(GV);
4037 DefinedCategoryNames.insert(llvm::CachedHashString(ExtName));
4039 MethodDefinitions.clear();
4100 if (
auto *RD =
type->getAsRecordDecl()) {
4101 for (
auto *field : RD->
fields()) {
4120 ID->getClassInterface()->all_declared_ivar_begin();
4148void CGObjCMac::GenerateClass(
const ObjCImplementationDecl *ID) {
4149 IdentifierInfo *RuntimeName =
4151 DefinedSymbols.insert(RuntimeName);
4153 std::string ClassName =
ID->getNameAsString();
4156 const_cast<ObjCInterfaceDecl *
>(
ID->getClassInterface());
4157 llvm::Constant *Protocols =
4158 EmitProtocolList(
"OBJC_CLASS_PROTOCOLS_" +
ID->getName(),
4159 Interface->all_referenced_protocol_begin(),
4160 Interface->all_referenced_protocol_end());
4162 if (
ID->hasNonZeroConstructors() ||
ID->hasDestructors())
4165 bool hasMRCWeak =
false;
4180 enum { InstanceMethods, ClassMethods, NumMethodLists };
4181 SmallVector<const ObjCMethodDecl *, 16> Methods[NumMethodLists];
4182 for (
const auto *MD :
ID->methods()) {
4183 if (!MD->isDirectMethod())
4184 Methods[unsigned(MD->isClassMethod())].push_back(MD);
4187 for (
const auto *PID :
ID->property_impls()) {
4189 if (PID->getPropertyDecl()->isDirectProperty())
4191 if (ObjCMethodDecl *MD = PID->getGetterMethodDecl())
4192 if (GetMethodDefinition(MD))
4193 Methods[InstanceMethods].push_back(MD);
4194 if (ObjCMethodDecl *MD = PID->getSetterMethodDecl())
4195 if (GetMethodDefinition(MD))
4196 Methods[InstanceMethods].push_back(MD);
4200 ConstantInitBuilder builder(CGM);
4201 auto values = builder.beginStruct(ObjCTypes.ClassTy);
4202 values.add(EmitMetaClass(ID, Protocols, Methods[ClassMethods]));
4203 if (ObjCInterfaceDecl *Super =
Interface->getSuperClass()) {
4205 LazySymbols.insert(Super->getIdentifier());
4207 values.add(GetClassName(Super->getObjCRuntimeNameAsString()));
4209 values.addNullPointer(ObjCTypes.ClassPtrTy);
4211 values.add(GetClassName(
ID->getObjCRuntimeNameAsString()));
4213 values.addInt(ObjCTypes.LongTy, 0);
4214 values.addInt(ObjCTypes.LongTy, Flags);
4215 values.addInt(ObjCTypes.LongTy,
Size.getQuantity());
4216 values.add(EmitIvarList(ID,
false));
4217 values.add(emitMethodList(
ID->getName(), MethodListType::InstanceMethods,
4218 Methods[InstanceMethods]));
4220 values.addNullPointer(ObjCTypes.CachePtrTy);
4221 values.add(Protocols);
4223 values.add(EmitClassExtension(ID, Size, hasMRCWeak,
4226 std::string Name(
"OBJC_CLASS_");
4228 const char *Section =
"__OBJC,__class,regular,no_dead_strip";
4230 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
4232 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4233 "Forward metaclass reference has incorrect type.");
4234 values.finishAndSetAsInitializer(GV);
4235 GV->setSection(Section);
4239 GV = CreateMetadataVar(Name, values, Section, CGM.
getPointerAlign(),
true);
4240 DefinedClasses.push_back(GV);
4241 ImplementedClasses.push_back(
Interface);
4243 MethodDefinitions.clear();
4247CGObjCMac::EmitMetaClass(
const ObjCImplementationDecl *ID,
4248 llvm::Constant *Protocols,
4249 ArrayRef<const ObjCMethodDecl *> Methods) {
4256 ConstantInitBuilder builder(CGM);
4257 auto values = builder.beginStruct(ObjCTypes.ClassTy);
4259 const ObjCInterfaceDecl *Root =
ID->getClassInterface();
4260 while (
const ObjCInterfaceDecl *Super = Root->
getSuperClass())
4266 if (ObjCInterfaceDecl *Super =
ID->getClassInterface()->getSuperClass()) {
4267 values.add(GetClassName(Super->getObjCRuntimeNameAsString()));
4269 values.addNullPointer(ObjCTypes.ClassPtrTy);
4271 values.add(GetClassName(
ID->getObjCRuntimeNameAsString()));
4273 values.addInt(ObjCTypes.LongTy, 0);
4274 values.addInt(ObjCTypes.LongTy, Flags);
4275 values.addInt(ObjCTypes.LongTy, Size);
4276 values.add(EmitIvarList(ID,
true));
4278 emitMethodList(
ID->getName(), MethodListType::ClassMethods, Methods));
4280 values.addNullPointer(ObjCTypes.CachePtrTy);
4281 values.add(Protocols);
4283 values.addNullPointer(ObjCTypes.Int8PtrTy);
4288 std::string Name(
"OBJC_METACLASS_");
4289 Name +=
ID->getName();
4292 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
4294 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4295 "Forward metaclass reference has incorrect type.");
4296 values.finishAndSetAsInitializer(GV);
4300 llvm::GlobalValue::PrivateLinkage);
4302 GV->setSection(
"__OBJC,__meta_class,regular,no_dead_strip");
4308llvm::Constant *CGObjCMac::EmitMetaClassRef(
const ObjCInterfaceDecl *ID) {
4309 std::string Name =
"OBJC_METACLASS_" +
ID->getNameAsString();
4319 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
4321 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
4322 llvm::GlobalValue::PrivateLinkage,
nullptr,
4325 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4326 "Forward metaclass reference has incorrect type.");
4330llvm::Value *CGObjCMac::EmitSuperClassRef(
const ObjCInterfaceDecl *ID) {
4331 std::string Name =
"OBJC_CLASS_" +
ID->getNameAsString();
4332 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
4335 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
4336 llvm::GlobalValue::PrivateLinkage,
nullptr,
4339 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4340 "Forward class metadata reference has incorrect type.");
4355llvm::Constant *CGObjCMac::EmitClassExtension(
const ObjCImplementationDecl *ID,
4356 CharUnits InstanceSize,
4360 llvm::Constant *layout;
4362 layout = llvm::ConstantPointerNull::get(CGM.
Int8PtrTy);
4369 llvm::Constant *propertyList =
4370 EmitPropertyList((isMetaclass ? Twine(
"_OBJC_$_CLASS_PROP_LIST_")
4371 : Twine(
"_OBJC_$_PROP_LIST_")) +
4373 ID,
ID->getClassInterface(), ObjCTypes, isMetaclass);
4376 if (layout->isNullValue() && propertyList->isNullValue()) {
4377 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
4381 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
4383 ConstantInitBuilder builder(CGM);
4384 auto values = builder.beginStruct(ObjCTypes.ClassExtensionTy);
4385 values.addInt(ObjCTypes.IntTy, size);
4387 values.add(propertyList);
4389 return CreateMetadataVar(
"OBJC_CLASSEXT_" +
ID->getName(), values,
4390 "__OBJC,__class_ext,regular,no_dead_strip",
4406llvm::Constant *CGObjCMac::EmitIvarList(
const ObjCImplementationDecl *ID,
4414 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
4416 const ObjCInterfaceDecl *OID =
ID->getClassInterface();
4418 ConstantInitBuilder builder(CGM);
4419 auto ivarList = builder.beginStruct();
4420 auto countSlot = ivarList.addPlaceholder();
4421 auto ivars = ivarList.beginArray(ObjCTypes.IvarTy);
4426 if (!IVD->getDeclName())
4429 auto ivar = ivars.beginStruct(ObjCTypes.IvarTy);
4430 ivar.add(GetMethodVarName(IVD->getIdentifier()));
4431 ivar.add(GetMethodVarType(IVD));
4432 ivar.addInt(ObjCTypes.IntTy, ComputeIvarBaseOffset(CGM, OID, IVD));
4433 ivar.finishAndAddTo(ivars);
4437 auto count = ivars.size();
4441 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
4444 ivars.finishAndAddTo(ivarList);
4445 ivarList.fillPlaceholderWithInt(countSlot, ObjCTypes.IntTy, count);
4447 llvm::GlobalVariable *GV;
4448 GV = CreateMetadataVar(
"OBJC_INSTANCE_VARIABLES_" +
ID->getName(), ivarList,
4449 "__OBJC,__instance_vars,regular,no_dead_strip",
4460void CGObjCMac::emitMethodDescriptionConstant(ConstantArrayBuilder &builder,
4461 const ObjCMethodDecl *MD) {
4462 auto description = builder.
beginStruct(ObjCTypes.MethodDescriptionTy);
4463 description.add(GetMethodVarName(MD->
getSelector()));
4464 description.add(GetMethodVarType(MD));
4465 description.finishAndAddTo(builder);
4475void CGObjCMac::emitMethodConstant(ConstantArrayBuilder &builder,
4476 const ObjCMethodDecl *MD) {
4477 llvm::Function *fn = GetMethodDefinition(MD);
4478 assert(fn &&
"no definition registered for method");
4480 auto method = builder.
beginStruct(ObjCTypes.MethodTy);
4482 method.add(GetMethodVarType(MD));
4484 method.finishAndAddTo(builder);
4501CGObjCMac::emitMethodList(Twine name, MethodListType MLT,
4502 ArrayRef<const ObjCMethodDecl *> methods) {
4505 bool forProtocol =
false;
4507 case MethodListType::CategoryInstanceMethods:
4508 prefix =
"OBJC_CATEGORY_INSTANCE_METHODS_";
4509 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
4510 forProtocol =
false;
4512 case MethodListType::CategoryClassMethods:
4513 prefix =
"OBJC_CATEGORY_CLASS_METHODS_";
4514 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
4515 forProtocol =
false;
4517 case MethodListType::InstanceMethods:
4518 prefix =
"OBJC_INSTANCE_METHODS_";
4519 section =
"__OBJC,__inst_meth,regular,no_dead_strip";
4520 forProtocol =
false;
4522 case MethodListType::ClassMethods:
4523 prefix =
"OBJC_CLASS_METHODS_";
4524 section =
"__OBJC,__cls_meth,regular,no_dead_strip";
4525 forProtocol =
false;
4527 case MethodListType::ProtocolInstanceMethods:
4528 prefix =
"OBJC_PROTOCOL_INSTANCE_METHODS_";
4529 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
4532 case MethodListType::ProtocolClassMethods:
4533 prefix =
"OBJC_PROTOCOL_CLASS_METHODS_";
4534 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
4537 case MethodListType::OptionalProtocolInstanceMethods:
4538 prefix =
"OBJC_PROTOCOL_INSTANCE_METHODS_OPT_";
4539 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
4542 case MethodListType::OptionalProtocolClassMethods:
4543 prefix =
"OBJC_PROTOCOL_CLASS_METHODS_OPT_";
4544 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
4550 if (methods.empty())
4551 return llvm::Constant::getNullValue(
4552 forProtocol ? ObjCTypes.MethodDescriptionListPtrTy
4553 : ObjCTypes.MethodListPtrTy);
4558 ConstantInitBuilder builder(CGM);
4560 values.addInt(ObjCTypes.IntTy, methods.size());
4561 auto methodArray = values.beginArray(ObjCTypes.MethodDescriptionTy);
4562 for (
auto MD : methods) {
4563 emitMethodDescriptionConstant(methodArray, MD);
4565 methodArray.finishAndAddTo(values);
4567 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
4573 ConstantInitBuilder builder(CGM);
4575 values.addNullPointer(ObjCTypes.Int8PtrTy);
4576 values.addInt(ObjCTypes.IntTy, methods.size());
4577 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
4578 for (
auto MD : methods) {
4580 emitMethodConstant(methodArray, MD);
4582 methodArray.finishAndAddTo(values);
4584 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
4589llvm::Function *CGObjCCommonMac::GenerateMethod(
const ObjCMethodDecl *OMD,
4590 const ObjCContainerDecl *CD) {
4595 DirectMethodInfo &Info = GenerateDirectMethod(OMD, CD);
4596 Method = Info.Implementation;
4598 auto Name = getSymbolNameForMethod(OMD);
4600 CodeGenTypes &Types = CGM.
getTypes();
4601 llvm::FunctionType *MethodTy =
4603 Method = llvm::Function::Create(
4604 MethodTy, llvm::GlobalValue::InternalLinkage, Name, &CGM.
getModule());
4607 MethodDefinitions.insert(std::make_pair(OMD,
Method));
4613CGObjCCommonMac::DirectMethodInfo &
4614CGObjCCommonMac::GenerateDirectMethod(
const ObjCMethodDecl *OMD,
4615 const ObjCContainerDecl *CD) {
4620 auto Cached = DirectMethodDefinitions.find(COMD);
4621 if (Cached != DirectMethodDefinitions.end()) {
4623 return Cached->second;
4626 CodeGenTypes &Types = CGM.
getTypes();
4627 llvm::FunctionType *MethodTy =
4630 getSymbolNameForMethod(OMD,
false,
4632 std::string ThunkName = Name +
"_thunk";
4635 auto ReplaceFunction = [](llvm::Function *OldFn, llvm::Function *NewFn) {
4636 NewFn->takeName(OldFn);
4637 OldFn->replaceAllUsesWith(NewFn);
4638 OldFn->eraseFromParent();
4643 llvm::Function *
Fn = CGM.
getModule().getFunction(Name);
4647 Fn = llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,
4649 return DirectMethodDefinitions.insert({COMD, DirectMethodInfo(Fn)})
4655 if (
Fn->getFunctionType() == MethodTy) {
4657 Fn->setLinkage(llvm::GlobalValue::ExternalLinkage);
4660 DirectMethodInfo Info(Fn);
4661 if (llvm::Function *Thunk = CGM.
getModule().getFunction(ThunkName))
4664 return DirectMethodDefinitions.insert({COMD, Info}).first->second;
4670 llvm::Function *NewFn = llvm::Function::Create(
4671 MethodTy, llvm::GlobalValue::ExternalLinkage,
"", &CGM.
getModule());
4672 ReplaceFunction(Fn, NewFn);
4675 DirectMethodInfo Info(NewFn);
4676 if (llvm::Function *OldThunk = CGM.
getModule().getFunction(ThunkName)) {
4677 llvm::Function *NewThunk = GenerateObjCDirectThunk(OMD, CD, NewFn);
4678 ReplaceFunction(OldThunk, NewThunk);
4679 Info.Thunk = NewThunk;
4682 if (Cached != DirectMethodDefinitions.end()) {
4683 Cached->second = Info;
4684 return Cached->second;
4686 return DirectMethodDefinitions.insert({COMD, Info}).first->second;
4752CGObjCCommonMac::GenerateObjCDirectThunk(
const ObjCMethodDecl *OMD,
4754 llvm::Function *Implementation) {
4757 "Should only generate thunk when optimization enabled");
4758 assert(Implementation &&
"Implementation must exist");
4760 llvm::FunctionType *ThunkTy = Implementation->getFunctionType();
4761 std::string ThunkName = Implementation->getName().str() +
"_thunk";
4764 llvm::Function *Thunk =
4765 llvm::Function::Create(ThunkTy, llvm::GlobalValue::LinkOnceODRLinkage,
4772 Thunk->setVisibility(llvm::GlobalValue::HiddenVisibility);
4773 Thunk->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4792 GenerateDirectMethodsPreconditionCheck(CGF, Thunk, OMD, CD);
4797 for (
auto &Arg : Thunk->args())
4798 Args.push_back(&Arg);
4801 llvm::CallInst *
Call = CGF.
Builder.CreateCall(Implementation, Args);
4802 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
4809 llvm::AttributeList Attrs;
4813 Call->setAttributes(Attrs);
4814 Call->setCallingConv(
static_cast<llvm::CallingConv::ID
>(
CallingConv));
4819 if (ThunkTy->getReturnType()->isVoidTy())
4829llvm::Function *CGObjCCommonMac::GetDirectMethodCallee(
4831 bool ReceiverCanBeNull,
bool ClassObjectCanBeUnrealized) {
4836 DirectMethodInfo Info = GenerateDirectMethod(OMD, CD);
4842 return Info.Implementation;
4846 auto getOrCreateThunk = [&]() {
4848 Info.Thunk = GenerateObjCDirectThunk(OMD, CD, Info.Implementation);
4858 return ReceiverCanBeNull ? getOrCreateThunk() : Info.Implementation;
4861 "OMD should either be a class method or instance method");
4865 return (ReceiverCanBeNull || ClassObjectCanBeUnrealized)
4866 ? getOrCreateThunk()
4867 : Info.Implementation;
4871CGObjCCommonMac::GenerateClassRealization(CodeGenFunction &CGF,
4872 llvm::Value *classObject,
4873 const ObjCInterfaceDecl *OID) {
4880 RValue result = GeneratePossiblySpecializedMessageSend(
4881 CGF, ReturnValueSlot(), ResultType, SelfSel, classObject, Args, OID,
4887void CGObjCCommonMac::GenerateDirectMethodsPreconditionCheck(
4888 CodeGenFunction &CGF, llvm::Function *Fn,
const ObjCMethodDecl *OMD,
4889 const ObjCContainerDecl *CD) {
4891 bool ReceiverCanBeNull =
true;
4893 auto selfValue = Builder.CreateLoad(selfAddr);
4908 "GenerateDirectMethod() should be called with the Class Interface");
4919 llvm::Value *realizedClass = GenerateClassRealization(CGF, selfValue, OID);
4920 Builder.CreateStore(realizedClass, selfAddr);
4925 ReceiverCanBeNull = isWeakLinkedClass(OID);
4929 if (ReceiverCanBeNull) {
4930 llvm::BasicBlock *SelfIsNilBlock =
4932 llvm::BasicBlock *ContBlock =
4937 auto Zero = llvm::ConstantPointerNull::get(selfTy);
4940 Builder.CreateCondBr(Builder.CreateICmpEQ(selfValue,
Zero), SelfIsNilBlock,
4941 ContBlock, MDHelper.createUnlikelyBranchWeights());
4947 Builder.SetInsertPoint(SelfIsNilBlock);
4948 if (!retTy->isVoidType()) {
4956 Builder.SetInsertPoint(ContBlock);
4960void CGObjCCommonMac::GenerateDirectMethodPrologue(
4961 CodeGenFunction &CGF, llvm::Function *Fn,
const ObjCMethodDecl *OMD,
4962 const ObjCContainerDecl *CD) {
4965 GenerateDirectMethodsPreconditionCheck(CGF, Fn, OMD, CD);
4974 Builder.CreateStore(GetSelector(CGF, OMD),
4979llvm::Function *CGObjCCommonMac::GenerateMethodSelectorStub(
4980 Selector Sel, StringRef ClassName,
const ObjCCommonTypesHelper &ObjCTypes) {
4981 assert((!ClassName.data() || !ClassName.empty()) &&
4982 "class name cannot be an empty string");
4983 auto Key = std::make_pair(Sel, ClassName);
4984 auto I = MethodSelectorStubs.find(Key);
4986 if (I != MethodSelectorStubs.end())
4989 auto *FnTy = llvm::FunctionType::get(
4990 ObjCTypes.ObjectPtrTy, {ObjCTypes.ObjectPtrTy, ObjCTypes.SelectorPtrTy},
4994 if (ClassName.data())
4995 FnName = (
"objc_msgSendClass$" + Sel.
getAsString() +
"$_OBJC_CLASS_$_" +
4996 llvm::Twine(ClassName))
5004 MethodSelectorStubs.insert(std::make_pair(Key, Fn));
5008llvm::GlobalVariable *
5009CGObjCCommonMac::CreateMetadataVar(Twine Name, ConstantStructBuilder &
Init,
5010 StringRef Section, CharUnits Align,
5012 llvm::GlobalValue::LinkageTypes
LT =
5014 llvm::GlobalVariable *GV =
5015 Init.finishAndCreateGlobal(Name, Align,
false, LT);
5016 if (!Section.empty())
5017 GV->setSection(Section);
5023llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
5024 llvm::Constant *
Init,
5028 llvm::Type *Ty =
Init->getType();
5029 llvm::GlobalValue::LinkageTypes
LT =
5031 llvm::GlobalVariable *GV =
5032 new llvm::GlobalVariable(CGM.
getModule(), Ty,
false, LT,
Init, Name);
5033 if (!Section.empty())
5034 GV->setSection(Section);
5041llvm::GlobalVariable *
5042CGObjCCommonMac::CreateCStringLiteral(StringRef Name, ObjCLabelType
Type,
5043 bool ForceNonFragileABI,
5044 bool NullTerminate) {
5047 case ObjCLabelType::ClassName:
5048 Label =
"OBJC_CLASS_NAME_";
5050 case ObjCLabelType::MethodVarName:
5051 Label =
"OBJC_METH_VAR_NAME_";
5053 case ObjCLabelType::MethodVarType:
5054 Label =
"OBJC_METH_VAR_TYPE_";
5056 case ObjCLabelType::PropertyName:
5057 Label =
"OBJC_PROP_NAME_ATTR_";
5059 case ObjCLabelType::LayoutBitMap:
5060 Label =
"OBJC_LAYOUT_BITMAP_";
5064 bool NonFragile = ForceNonFragileABI || isNonFragileABI();
5068 case ObjCLabelType::ClassName:
5069 Section = NonFragile ?
"__TEXT,__objc_classname,cstring_literals"
5070 :
"__TEXT,__cstring,cstring_literals";
5072 case ObjCLabelType::MethodVarName:
5073 Section = NonFragile ?
"__TEXT,__objc_methname,cstring_literals"
5074 :
"__TEXT,__cstring,cstring_literals";
5076 case ObjCLabelType::MethodVarType:
5077 Section = NonFragile ?
"__TEXT,__objc_methtype,cstring_literals"
5078 :
"__TEXT,__cstring,cstring_literals";
5080 case ObjCLabelType::PropertyName:
5081 Section = NonFragile ?
"__TEXT,__objc_methname,cstring_literals"
5082 :
"__TEXT,__cstring,cstring_literals";
5084 case ObjCLabelType::LayoutBitMap:
5085 Section =
"__TEXT,__cstring,cstring_literals";
5089 llvm::Constant *
Value =
5090 llvm::ConstantDataArray::getString(VMContext, Name, NullTerminate);
5091 llvm::GlobalVariable *GV =
new llvm::GlobalVariable(
5093 true, llvm::GlobalValue::PrivateLinkage,
Value, Label);
5094 if (CGM.
getTriple().isOSBinFormatMachO())
5095 GV->setSection(Section);
5096 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
5103llvm::Function *CGObjCMac::ModuleInitFunction() {
5109llvm::FunctionCallee CGObjCMac::GetPropertyGetFunction() {
5110 return ObjCTypes.getGetPropertyFn();
5113llvm::FunctionCallee CGObjCMac::GetPropertySetFunction() {
5114 return ObjCTypes.getSetPropertyFn();
5117llvm::FunctionCallee CGObjCMac::GetOptimizedPropertySetFunction(
bool atomic,
5119 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
5122llvm::FunctionCallee CGObjCMac::GetGetStructFunction() {
5123 return ObjCTypes.getCopyStructFn();
5126llvm::FunctionCallee CGObjCMac::GetSetStructFunction() {
5127 return ObjCTypes.getCopyStructFn();
5130llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectGetFunction() {
5131 return ObjCTypes.getCppAtomicObjectFunction();
5134llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectSetFunction() {
5135 return ObjCTypes.getCppAtomicObjectFunction();
5138llvm::FunctionCallee CGObjCMac::EnumerationMutationFunction() {
5139 return ObjCTypes.getEnumerationMutationFn();
5142void CGObjCMac::EmitTryStmt(CodeGenFunction &CGF,
const ObjCAtTryStmt &S) {
5143 return EmitTryOrSynchronizedStmt(CGF, S);
5146void CGObjCMac::EmitSynchronizedStmt(CodeGenFunction &CGF,
5147 const ObjCAtSynchronizedStmt &S) {
5148 return EmitTryOrSynchronizedStmt(CGF, S);
5152struct PerformFragileFinally final : EHScopeStack::Cleanup {
5157 ObjCTypesHelper &ObjCTypes;
5158 PerformFragileFinally(
const Stmt *S, Address SyncArgSlot,
5159 Address CallTryExitVar, Address ExceptionData,
5160 ObjCTypesHelper *ObjCTypes)
5161 : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
5162 ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
5164 void Emit(CodeGenFunction &CGF, Flags flags)
override {
5167 llvm::BasicBlock *FinallyCallExit =
5169 llvm::BasicBlock *FinallyNoCallExit =
5172 FinallyCallExit, FinallyNoCallExit);
5181 if (
const ObjCAtFinallyStmt *FinallyStmt =
5184 if (flags.isForEHCleanup())
5189 llvm::Value *CurCleanupDest =
5192 CGF.
EmitStmt(FinallyStmt->getFinallyBody());
5211class FragileHazards {
5212 CodeGenFunction &CGF;
5213 SmallVector<llvm::Value *, 20> Locals;
5214 llvm::DenseSet<llvm::BasicBlock *> BlocksBeforeTry;
5216 llvm::InlineAsm *ReadHazard;
5217 llvm::InlineAsm *WriteHazard;
5219 llvm::FunctionType *GetAsmFnType();
5221 void collectLocals();
5222 void emitReadHazard(CGBuilderTy &Builder);
5225 FragileHazards(CodeGenFunction &CGF);
5227 void emitWriteHazard();
5228 void emitHazardsInNewBlocks();
5237FragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) {
5244 for (llvm::BasicBlock &BB : *CGF.
CurFn)
5245 BlocksBeforeTry.insert(&BB);
5247 llvm::FunctionType *AsmFnTy = GetAsmFnType();
5255 std::string Constraint;
5256 for (
unsigned I = 0, E = Locals.size(); I != E; ++I) {
5262 ReadHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
5270 std::string Constraint;
5271 for (
unsigned I = 0, E = Locals.size(); I != E; ++I) {
5274 Constraint +=
"=*m";
5277 WriteHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
5282void FragileHazards::emitWriteHazard() {
5287 for (
auto Pair : llvm::enumerate(Locals))
5290 llvm::Attribute::get(
5295void FragileHazards::emitReadHazard(
CGBuilderTy &Builder) {
5296 assert(!Locals.empty());
5297 llvm::CallInst *call = Builder.CreateCall(ReadHazard, Locals);
5298 call->setDoesNotThrow();
5300 for (
auto Pair : llvm::enumerate(Locals))
5303 llvm::Attribute::get(
5304 Builder.getContext(), llvm::Attribute::ElementType,
5310void FragileHazards::emitHazardsInNewBlocks() {
5317 for (llvm::BasicBlock &BB : *CGF.
CurFn) {
5318 if (BlocksBeforeTry.count(&BB))
5322 for (llvm::BasicBlock::iterator BI = BB.begin(), BE = BB.end(); BI != BE;
5324 llvm::Instruction &I = *BI;
5343 Builder.SetInsertPoint(&BB, BI);
5344 emitReadHazard(Builder);
5351 if (llvm::Value *Ptr =
V.getBasePointer())
5355void FragileHazards::collectLocals() {
5357 llvm::DenseSet<llvm::Value *> AllocasToIgnore;
5363 llvm::BasicBlock &Entry = CGF.
CurFn->getEntryBlock();
5364 for (llvm::Instruction &I : Entry)
5366 Locals.push_back(&I);
5369llvm::FunctionType *FragileHazards::GetAsmFnType() {
5370 SmallVector<llvm::Type *, 16> tys(Locals.size());
5371 for (
unsigned i = 0, e = Locals.size(); i != e; ++i)
5372 tys[i] = Locals[i]->getType();
5373 return llvm::FunctionType::get(CGF.
VoidTy, tys,
false);
5484void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
5505 llvm::Value *SyncArg =
5507 SyncArg = CGF.
Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
5518 ObjCTypes.ExceptionDataTy, CGF.
getPointerAlign(),
"exceptiondata.ptr");
5524 FragileHazards Hazards(CGF);
5543 SyncArgSlot, CallTryExitVar,
5544 ExceptionData, &ObjCTypes);
5550 ExceptionData.emitRawPointer(CGF));
5553 llvm::Constant *
Zero = llvm::ConstantInt::get(CGF.
Builder.getInt32Ty(), 0);
5556 ObjCTypes.ExceptionDataTy, ExceptionData.emitRawPointer(CGF), GEPIndexes,
5559 ObjCTypes.getSetJmpFn(), SetJmpBuffer,
"setjmp_result");
5560 SetJmpResult->setCanReturnTwice();
5566 llvm::Value *DidCatch =
5567 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
5568 CGF.
Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
5576 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.
Builder.saveAndClearIP();
5582 Hazards.emitWriteHazard();
5596 ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF),
5607 llvm::BasicBlock *CatchBlock =
nullptr;
5608 llvm::BasicBlock *CatchHandler =
nullptr;
5619 ExceptionData.emitRawPointer(CGF));
5622 ObjCTypes.getSetJmpFn(), SetJmpBuffer,
"setjmp.result");
5623 SetJmpResult->setCanReturnTwice();
5625 llvm::Value *Threw =
5626 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
5630 CGF.
Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
5640 bool AllMatched =
false;
5641 for (
const ObjCAtCatchStmt *CatchStmt : AtTryStmt->
catch_stmts()) {
5642 const VarDecl *CatchParam = CatchStmt->getCatchParamDecl();
5643 const ObjCObjectPointerType *OPT =
nullptr;
5649 OPT = CatchParam->
getType()->
getAs<ObjCObjectPointerType>();
5668 EmitInitOfCatchParam(CGF, Caught, CatchParam);
5671 CGF.
EmitStmt(CatchStmt->getCatchBody());
5674 CatchVarCleanups.ForceCleanup();
5680 assert(OPT &&
"Unexpected non-object pointer type in @catch");
5684 ObjCInterfaceDecl *IDecl = ObjTy->getInterface();
5685 assert(IDecl &&
"Catch parameter must have Objective-C type!");
5688 llvm::Value *
Class = EmitClassRef(CGF, IDecl);
5690 llvm::Value *matchArgs[] = {
Class, Caught};
5692 ObjCTypes.getExceptionMatchFn(), matchArgs,
"match");
5698 MatchedBlock, NextCatchBlock);
5711 llvm::Value *Tmp = CGF.
Builder.CreateBitCast(
5713 EmitInitOfCatchParam(CGF, Tmp, CatchParam);
5715 CGF.
EmitStmt(CatchStmt->getCatchBody());
5718 CatchVarCleanups.ForceCleanup();
5729 if (Caught->use_empty())
5730 Caught->eraseFromParent();
5746 assert(PropagatingExnVar.
isValid());
5748 ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF),
5759 Hazards.emitHazardsInNewBlocks();
5762 CGF.
Builder.restoreIP(TryFallthroughIP);
5769 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
5773 llvm::Value *PropagatingExn;
5774 if (PropagatingExnVar.
isValid()) {
5780 ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF));
5781 PropagatingExn = Caught;
5786 CGF.
Builder.CreateUnreachable();
5789 CGF.
Builder.restoreIP(SavedIP);
5792void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
5793 const ObjCAtThrowStmt &S,
5794 bool ClearInsertionPoint) {
5795 llvm::Value *ExceptionAsObject;
5800 CGF.
Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
5803 "Unexpected rethrow outside @catch block.");
5807 CGF.
EmitRuntimeCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
5808 ->setDoesNotReturn();
5809 CGF.
Builder.CreateUnreachable();
5812 if (ClearInsertionPoint)
5813 CGF.
Builder.ClearInsertionPoint();
5819llvm::Value *CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
5822 llvm::Value *AddrWeakObjVal = CGF.
Builder.CreateBitCast(
5825 ObjCTypes.getGcReadWeakFn(), AddrWeakObjVal,
"weakread");
5826 read_weak = CGF.
Builder.CreateBitCast(read_weak, DestTy);
5833void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
5834 llvm::Value *src,
Address dst) {
5835 llvm::Type *SrcTy = src->getType();
5838 assert(Size <= 8 && "does not support size > 8
");
5839 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
5840 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
5841 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5843 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5844 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
5845 ObjCTypes.PtrObjectPtrTy);
5846 llvm::Value *args[] = {src, dstVal};
5847 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), args,
5854void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
5855 llvm::Value *src, Address dst,
5857 llvm::Type *SrcTy = src->getType();
5858 if (!isa<llvm::PointerType>(SrcTy)) {
5859 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
5860 assert(Size <= 8 && "does
not support size > 8
");
5861 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
5862 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
5863 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5865 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5866 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
5867 ObjCTypes.PtrObjectPtrTy);
5868 llvm::Value *args[] = {src, dstVal};
5870 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), args,
5873 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(), args,
5874 "threadlocalassign
");
5880void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
5881 llvm::Value *src, Address dst,
5882 llvm::Value *ivarOffset) {
5883 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset
is NULL");
5884 llvm::Type *SrcTy = src->getType();
5885 if (!isa<llvm::PointerType>(SrcTy)) {
5886 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
5887 assert(Size <= 8 && "does
not support size > 8
");
5888 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
5889 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
5890 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5892 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5893 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
5894 ObjCTypes.PtrObjectPtrTy);
5895 llvm::Value *args[] = {src, dstVal, ivarOffset};
5896 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
5902void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
5903 llvm::Value *src, Address dst) {
5904 llvm::Type *SrcTy = src->getType();
5905 if (!isa<llvm::PointerType>(SrcTy)) {
5906 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
5907 assert(Size <= 8 && "does
not support size > 8
");
5908 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
5909 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
5910 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5912 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5913 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
5914 ObjCTypes.PtrObjectPtrTy);
5915 llvm::Value *args[] = {src, dstVal};
5916 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), args,
5920void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
5921 Address DestPtr, Address SrcPtr,
5922 llvm::Value *size) {
5923 llvm::Value *args[] = {DestPtr.emitRawPointer(CGF),
5924 SrcPtr.emitRawPointer(CGF), size};
5925 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
5930LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
5932 llvm::Value *BaseValue,
5933 const ObjCIvarDecl *Ivar,
5934 unsigned CVRQualifiers) {
5935 const ObjCInterfaceDecl *ID =
5936 ObjectTy->castAs<ObjCObjectType>()->getInterface();
5937 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
5938 EmitIvarOffset(CGF, ID, Ivar));
5941llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
5942 const ObjCInterfaceDecl *Interface,
5943 const ObjCIvarDecl *Ivar) {
5944 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
5945 return llvm::ConstantInt::get(
5946 CGM.getTypes().ConvertType(CGM.getContext().LongTy), Offset);
5949/* *** Private Interface *** */
5951std::string CGObjCCommonMac::GetSectionName(StringRef Section,
5952 StringRef MachOAttributes) {
5953 switch (CGM.getTriple().getObjectFormat()) {
5954 case llvm::Triple::UnknownObjectFormat:
5955 llvm_unreachable("unexpected
object file format
");
5956 case llvm::Triple::MachO: {
5957 if (MachOAttributes.empty())
5958 return ("__DATA,
" + Section).str();
5959 return ("__DATA,
" + Section + ",
" + MachOAttributes).str();
5961 case llvm::Triple::ELF:
5962 assert(Section.starts_with("__
") && "expected the name to begin with __
");
5963 return Section.substr(2).str();
5964 case llvm::Triple::COFF:
5965 assert(Section.starts_with("__
") && "expected the name to begin with __
");
5966 return (".
" + Section.substr(2) + "$B
").str();
5967 case llvm::Triple::Wasm:
5968 case llvm::Triple::GOFF:
5969 case llvm::Triple::SPIRV:
5970 case llvm::Triple::XCOFF:
5971 case llvm::Triple::DXContainer:
5972 llvm::report_fatal_error(
5973 "Objective-
C support
is unimplemented
for object file format
");
5976 llvm_unreachable("Unhandled llvm::Triple::ObjectFormatType
enum");
5988enum ImageInfoFlags {
5989 eImageInfo_FixAndContinue = (1 << 0), // This flag is no longer set by clang.
5990 eImageInfo_GarbageCollected = (1 << 1),
5991 eImageInfo_GCOnly = (1 << 2),
5992 eImageInfo_OptimizedByDyld = (1 << 3), // This flag is set by the dyld shared cache.
5994 eImageInfo_SignedClassRO = (1 << 4), // Reused (was _CorrectedSynthesize)
5995 eImageInfo_ImageIsSimulated = (1 << 5),
5996 eImageInfo_ClassProperties = (1 << 6)
6000void CGObjCCommonMac::EmitImageInfo() {
6001 unsigned version = 0; // Version is unused?
6002 std::string Section =
6004 ? "__OBJC,__image_info,regular
"
6005 : GetSectionName("__objc_imageinfo
", "regular,no_dead_strip
");
6007 // Generate module-level named metadata to convey this information to the
6008 // linker and code-gen.
6009 llvm::Module &Mod = CGM.getModule();
6011 // Add the ObjC ABI version to the module flags.
6012 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Version
", ObjCABI);
6013 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Image Info Version
",
6015 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Image Info Section
",
6016 llvm::MDString::get(VMContext, Section));
6018 auto Int8Ty = llvm::Type::getInt8Ty(VMContext);
6019 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
6020 // Non-GC overrides those files which specify GC.
6021 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Garbage Collection
",
6022 llvm::ConstantInt::get(Int8Ty, 0));
6024 // Add the ObjC garbage collection value.
6026 llvm::Module::Error, "Objective-
C Garbage Collection
",
6027 llvm::ConstantInt::get(Int8Ty, (uint8_t)eImageInfo_GarbageCollected));
6029 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
6030 // Add the ObjC GC Only value.
6031 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C GC Only
",
6034 // Require that GC be specified and set to eImageInfo_GarbageCollected.
6035 llvm::Metadata *Ops[2] = {
6036 llvm::MDString::get(VMContext, "Objective-
C Garbage Collection
"),
6037 llvm::ConstantAsMetadata::get(
6038 llvm::ConstantInt::get(Int8Ty, eImageInfo_GarbageCollected))};
6039 Mod.addModuleFlag(llvm::Module::Require, "Objective-
C GC Only
",
6040 llvm::MDNode::get(VMContext, Ops));
6044 // Indicate whether we're compiling this to run on a simulator.
6045 if (CGM.getTarget().getTriple().isSimulatorEnvironment())
6046 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Is Simulated
",
6047 eImageInfo_ImageIsSimulated);
6049 // Indicate whether we are generating class properties.
6050 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Class Properties
",
6051 eImageInfo_ClassProperties);
6053 // Indicate whether we want enforcement of pointer signing for class_ro_t
6055 if (CGM.getLangOpts().PointerAuthObjcClassROPointers)
6056 Mod.addModuleFlag(llvm::Module::Error,
6057 "Objective-
C Enforce ClassRO
Pointer Signing
",
6058 eImageInfo_SignedClassRO);
6060 Mod.addModuleFlag(llvm::Module::Error,
6061 "Objective-
C Enforce ClassRO
Pointer Signing
",
6062 llvm::ConstantInt::get(Int8Ty, 0));
6065// struct objc_module {
6066// unsigned long version;
6067// unsigned long size;
6072// FIXME: Get from somewhere
6073static const int ModuleVersion = 7;
6075void CGObjCMac::EmitModuleInfo() {
6076 uint64_t Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ModuleTy);
6078 ConstantInitBuilder builder(CGM);
6079 auto values = builder.beginStruct(ObjCTypes.ModuleTy);
6080 values.addInt(ObjCTypes.LongTy, ModuleVersion);
6081 values.addInt(ObjCTypes.LongTy, Size);
6082 // This used to be the filename, now it is unused. <rdr://4327263>
6083 values.add(GetClassName(StringRef("")));
6084 values.add(EmitModuleSymbols());
6085 CreateMetadataVar("OBJC_MODULES
", values,
6086 "__OBJC,__module_info,regular,no_dead_strip
",
6087 CGM.getPointerAlign(), true);
6090llvm::Constant *CGObjCMac::EmitModuleSymbols() {
6091 unsigned NumClasses = DefinedClasses.size();
6092 unsigned NumCategories = DefinedCategories.size();
6094 // Return null if no symbols were defined.
6095 if (!NumClasses && !NumCategories)
6096 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
6098 ConstantInitBuilder builder(CGM);
6099 auto values = builder.beginStruct();
6100 values.addInt(ObjCTypes.LongTy, 0);
6101 values.addNullPointer(ObjCTypes.SelectorPtrTy);
6102 values.addInt(ObjCTypes.ShortTy, NumClasses);
6103 values.addInt(ObjCTypes.ShortTy, NumCategories);
6105 // The runtime expects exactly the list of defined classes followed
6106 // by the list of defined categories, in a single array.
6107 auto array = values.beginArray(ObjCTypes.Int8PtrTy);
6108 for (unsigned i = 0; i < NumClasses; i++) {
6109 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
6111 if (ObjCImplementationDecl *IMP = ID->getImplementation())
6112 // We are implementing a weak imported interface. Give it external linkage
6113 if (ID->isWeakImported() && !IMP->isWeakImported())
6114 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
6116 array.add(DefinedClasses[i]);
6118 for (unsigned i = 0; i < NumCategories; i++)
6119 array.add(DefinedCategories[i]);
6121 array.finishAndAddTo(values);
6123 llvm::GlobalVariable *GV = CreateMetadataVar(
6124 "OBJC_SYMBOLS
", values, "__OBJC,__symbols,regular,no_dead_strip
",
6125 CGM.getPointerAlign(), true);
6129llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF,
6130 IdentifierInfo *II) {
6131 LazySymbols.insert(II);
6133 llvm::GlobalVariable *&Entry = ClassReferences[II];
6137 CreateMetadataVar("OBJC_CLASS_REFERENCES_
", GetClassName(II->getName()),
6138 "__OBJC,__cls_refs,literal_pointers,no_dead_strip
",
6139 CGM.getPointerAlign(), true);
6142 return CGF.Builder.CreateAlignedLoad(Entry->getValueType(), Entry,
6143 CGF.getPointerAlign());
6146llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF,
6147 const ObjCInterfaceDecl *ID) {
6148 // If the class has the objc_runtime_visible attribute, we need to
6149 // use the Objective-C runtime to get the class.
6150 if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
6151 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
6153 IdentifierInfo *RuntimeName =
6154 &CGM.getContext().Idents.get(ID->getObjCRuntimeNameAsString());
6155 return EmitClassRefFromId(CGF, RuntimeName);
6158llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
6159 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool
");
6160 return EmitClassRefFromId(CGF, II);
6163llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel) {
6164 return CGF.Builder.CreateLoad(EmitSelectorAddr(Sel));
6167ConstantAddress CGObjCMac::EmitSelectorAddr(Selector Sel) {
6168 CharUnits Align = CGM.getPointerAlign();
6170 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
6172 Entry = CreateMetadataVar(
6173 "OBJC_SELECTOR_REFERENCES_
", GetMethodVarName(Sel),
6174 "__OBJC,__message_refs,literal_pointers,no_dead_strip
", Align, true);
6175 Entry->setExternallyInitialized(true);
6178 return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align);
6181llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) {
6182 llvm::GlobalVariable *&Entry = ClassNames[RuntimeName];
6184 Entry = CreateCStringLiteral(RuntimeName, ObjCLabelType::ClassName);
6185 return getConstantGEP(VMContext, Entry, 0, 0);
6188llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
6189 return MethodDefinitions.lookup(MD);
6195CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
6196 const ObjCCommonTypesHelper &ObjCTypes) {
6197 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
6200void IvarLayoutBuilder::visitRecord(const RecordType *RT, CharUnits offset) {
6201 const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
6203 // If this is a union, remember that we had one, because it might mess
6204 // up the ordering of layout entries.
6206 IsDisordered = true;
6208 const ASTRecordLayout *recLayout = nullptr;
6209 visitAggregate(RD->field_begin(), RD->field_end(), offset,
6210 [&](const FieldDecl *field) -> CharUnits {
6212 recLayout = &CGM.getContext().getASTRecordLayout(RD);
6214 recLayout->getFieldOffset(field->getFieldIndex());
6215 return CGM.getContext().toCharUnitsFromBits(offsetInBits);
6219template <class Iterator, class GetOffsetFn>
6220void IvarLayoutBuilder::visitAggregate(Iterator begin, Iterator end,
6221 CharUnits aggregateOffset,
6222 const GetOffsetFn &getOffset) {
6223 for (; begin != end; ++begin) {
6224 auto field = *begin;
6226 // Skip over bitfields.
6227 if (field->isBitField()) {
6231 // Compute the offset of the field within the aggregate.
6232 CharUnits fieldOffset = aggregateOffset + getOffset(field);
6234 visitField(field, fieldOffset);
6239void IvarLayoutBuilder::visitField(const FieldDecl *field,
6240 CharUnits fieldOffset) {
6241 QualType fieldType = field->getType();
6243 // Drill down into arrays.
6244 uint64_t numElts = 1;
6245 if (auto arrayType = CGM.getContext().getAsIncompleteArrayType(fieldType)) {
6247 fieldType = arrayType->getElementType();
6249 // Unlike incomplete arrays, constant arrays can be nested.
6250 while (auto arrayType = CGM.getContext().getAsConstantArrayType(fieldType)) {
6251 numElts *= arrayType->getZExtSize();
6252 fieldType = arrayType->getElementType();
6255 assert(!fieldType->isArrayType() && "ivar of non-constant array
type?
");
6257 // If we ended up with a zero-sized array, we've done what we can do within
6258 // the limits of this layout encoding.
6262 // Recurse if the base element type is a record type.
6263 if (const auto *recType = fieldType->getAsCanonical<RecordType>()) {
6264 size_t oldEnd = IvarsInfo.size();
6266 visitRecord(recType, fieldOffset);
6268 // If we have an array, replicate the first entry's layout information.
6269 auto numEltEntries = IvarsInfo.size() - oldEnd;
6270 if (numElts != 1 && numEltEntries != 0) {
6271 CharUnits eltSize = CGM.getContext().getTypeSizeInChars(recType);
6272 for (uint64_t eltIndex = 1; eltIndex != numElts; ++eltIndex) {
6273 // Copy the last numEltEntries onto the end of the array, adjusting
6274 // each for the element size.
6275 for (size_t i = 0; i != numEltEntries; ++i) {
6276 auto firstEntry = IvarsInfo[oldEnd + i];
6277 IvarsInfo.push_back(IvarInfo(firstEntry.Offset + eltIndex * eltSize,
6278 firstEntry.SizeInWords));
6286 // Classify the element type.
6287 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), fieldType);
6289 // If it matches what we're looking for, add an entry.
6290 if ((ForStrongLayout && GCAttr == Qualifiers::Strong) ||
6291 (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
6292 assert(CGM.getContext().getTypeSizeInChars(fieldType) ==
6293 CGM.getPointerSize());
6294 IvarsInfo.push_back(IvarInfo(fieldOffset, numElts));
6302IvarLayoutBuilder::buildBitmap(CGObjCCommonMac &CGObjC,
6303 llvm::SmallVectorImpl<unsigned char> &buffer) {
6304 // The bitmap is a series of skip/scan instructions, aligned to word
6305 // boundaries. The skip is performed first.
6306 const unsigned char MaxNibble = 0xF;
6307 const unsigned char SkipMask = 0xF0, SkipShift = 4;
6308 const unsigned char ScanMask = 0x0F, ScanShift = 0;
6310 assert(!IvarsInfo.empty() && "generating bitmap
for no data
");
6312 // Sort the ivar info on byte position in case we encounterred a
6313 // union nested in the ivar list.
6315 // This isn't a stable sort, but our algorithm should handle it fine.
6316 llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end());
6318 assert(llvm::is_sorted(IvarsInfo));
6320 assert(IvarsInfo.back().Offset < InstanceEnd);
6322 assert(buffer.empty());
6324 // Skip the next N words.
6325 auto skip = [&](unsigned numWords) {
6326 assert(numWords > 0);
6328 // Try to merge into the previous byte. Since scans happen second, we
6329 // can't do this if it includes a scan.
6330 if (!buffer.empty() && !(buffer.back() & ScanMask)) {
6331 unsigned lastSkip = buffer.back() >> SkipShift;
6332 if (lastSkip < MaxNibble) {
6333 unsigned claimed = std::min(MaxNibble - lastSkip, numWords);
6334 numWords -= claimed;
6335 lastSkip += claimed;
6336 buffer.back() = (lastSkip << SkipShift);
6340 while (numWords >= MaxNibble) {
6341 buffer.push_back(MaxNibble << SkipShift);
6342 numWords -= MaxNibble;
6345 buffer.push_back(numWords << SkipShift);
6349 // Scan the next N words.
6350 auto scan = [&](unsigned numWords) {
6351 assert(numWords > 0);
6353 // Try to merge into the previous byte. Since scans happen second, we can
6354 // do this even if it includes a skip.
6355 if (!buffer.empty()) {
6356 unsigned lastScan = (buffer.back() & ScanMask) >> ScanShift;
6357 if (lastScan < MaxNibble) {
6358 unsigned claimed = std::min(MaxNibble - lastScan, numWords);
6359 numWords -= claimed;
6360 lastScan += claimed;
6361 buffer.back() = (buffer.back() & SkipMask) | (lastScan << ScanShift);
6365 while (numWords >= MaxNibble) {
6366 buffer.push_back(MaxNibble << ScanShift);
6367 numWords -= MaxNibble;
6370 buffer.push_back(numWords << ScanShift);
6374 // One past the end of the last scan.
6375 unsigned endOfLastScanInWords = 0;
6376 const CharUnits WordSize = CGM.getPointerSize();
6378 // Consider all the scan requests.
6379 for (auto &request : IvarsInfo) {
6380 CharUnits beginOfScan = request.Offset - InstanceBegin;
6382 // Ignore scan requests that don't start at an even multiple of the
6383 // word size. We can't encode them.
6384 if (!beginOfScan.isMultipleOf(WordSize))
6387 // Ignore scan requests that start before the instance start.
6388 // This assumes that scans never span that boundary. The boundary
6389 // isn't the true start of the ivars, because in the fragile-ARC case
6390 // it's rounded up to word alignment, but the test above should leave
6391 // us ignoring that possibility.
6392 if (beginOfScan.isNegative()) {
6393 assert(request.Offset + request.SizeInWords * WordSize <= InstanceBegin);
6397 unsigned beginOfScanInWords = beginOfScan / WordSize;
6398 unsigned endOfScanInWords = beginOfScanInWords + request.SizeInWords;
6400 // If the scan starts some number of words after the last one ended,
6402 if (beginOfScanInWords > endOfLastScanInWords) {
6403 skip(beginOfScanInWords - endOfLastScanInWords);
6405 // Otherwise, start scanning where the last left off.
6407 beginOfScanInWords = endOfLastScanInWords;
6409 // If that leaves us with nothing to scan, ignore this request.
6410 if (beginOfScanInWords >= endOfScanInWords)
6414 // Scan to the end of the request.
6415 assert(beginOfScanInWords < endOfScanInWords);
6416 scan(endOfScanInWords - beginOfScanInWords);
6417 endOfLastScanInWords = endOfScanInWords;
6421 return llvm::ConstantPointerNull::get(CGM.Int8PtrTy);
6423 // For GC layouts, emit a skip to the end of the allocation so that we
6424 // have precise information about the entire thing. This isn't useful
6425 // or necessary for the ARC-style layout strings.
6426 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
6427 unsigned lastOffsetInWords =
6428 (InstanceEnd - InstanceBegin + WordSize - CharUnits::One()) / WordSize;
6429 if (lastOffsetInWords > endOfLastScanInWords) {
6430 skip(lastOffsetInWords - endOfLastScanInWords);
6434 // Null terminate the string.
6435 buffer.push_back(0);
6437 auto *Entry = CGObjC.CreateCStringLiteral(
6438 reinterpret_cast<char *>(buffer.data()), ObjCLabelType::LayoutBitMap);
6439 return getConstantGEP(CGM.getLLVMContext(), Entry, 0, 0);
6459CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD,
6460 CharUnits beginOffset, CharUnits endOffset,
6461 bool ForStrongLayout, bool HasMRCWeakIvars) {
6462 // If this is MRC, and we're either building a strong layout or there
6463 // are no weak ivars, bail out early.
6464 llvm::Type *PtrTy = CGM.Int8PtrTy;
6465 if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
6466 !CGM.getLangOpts().ObjCAutoRefCount &&
6467 (ForStrongLayout || !HasMRCWeakIvars))
6468 return llvm::Constant::getNullValue(PtrTy);
6470 const ObjCInterfaceDecl *OI = OMD->getClassInterface();
6471 SmallVector<const ObjCIvarDecl *, 32> ivars;
6473 // GC layout strings include the complete object layout, possibly
6474 // inaccurately in the non-fragile ABI; the runtime knows how to fix this
6477 // ARC layout strings only include the class's ivars. In non-fragile
6478 // runtimes, that means starting at InstanceStart, rounded up to word
6479 // alignment. In fragile runtimes, there's no InstanceStart, so it means
6480 // starting at the offset of the first ivar, rounded up to word alignment.
6482 // MRC weak layout strings follow the ARC style.
6483 CharUnits baseOffset;
6484 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
6485 for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin(); IVD;
6486 IVD = IVD->getNextIvar())
6487 ivars.push_back(IVD);
6489 if (isNonFragileABI()) {
6490 baseOffset = beginOffset; // InstanceStart
6491 } else if (!ivars.empty()) {
6493 CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivars[0]));
6495 baseOffset = CharUnits::Zero();
6498 baseOffset = baseOffset.alignTo(CGM.getPointerAlign());
6500 CGM.getContext().DeepCollectObjCIvars(OI, true, ivars);
6502 baseOffset = CharUnits::Zero();
6506 return llvm::Constant::getNullValue(PtrTy);
6508 IvarLayoutBuilder builder(CGM, baseOffset, endOffset, ForStrongLayout);
6510 builder.visitAggregate(ivars.begin(), ivars.end(), CharUnits::Zero(),
6511 [&](const ObjCIvarDecl *ivar) -> CharUnits {
6512 return CharUnits::fromQuantity(
6513 ComputeIvarBaseOffset(CGM, OMD, ivar));
6516 if (!builder.hasBitmapData())
6517 return llvm::Constant::getNullValue(PtrTy);
6519 llvm::SmallVector<unsigned char, 4> buffer;
6520 llvm::Constant *C = builder.buildBitmap(*this, buffer);
6522 if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
6523 printf("\n%s ivar layout
for class '%s':
",
6524 ForStrongLayout ? "strong
" : "weak
",
6525 OMD->getClassInterface()->getName().str().c_str());
6526 builder.dump(buffer);
6531llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
6532 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
6533 // FIXME: Avoid std::string in "Sel.
getAsString()
"
6536 CreateCStringLiteral(Sel.getAsString(), ObjCLabelType::MethodVarName);
6537 return getConstantGEP(VMContext, Entry, 0, 0);
6540// FIXME: Merge into a single cstring creation function.
6541llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
6542 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
6545llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
6546 std::string TypeStr;
6547 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
6549 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
6551 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType);
6552 return getConstantGEP(VMContext, Entry, 0, 0);
6555llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D,
6557 std::string TypeStr =
6558 CGM.getContext().getObjCEncodingForMethodDecl(D, Extended);
6560 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
6562 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType);
6563 return getConstantGEP(VMContext, Entry, 0, 0);
6566// FIXME: Merge into a single cstring creation function.
6567llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
6568 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
6570 Entry = CreateCStringLiteral(Ident->getName(), ObjCLabelType::PropertyName);
6571 return getConstantGEP(VMContext, Entry, 0, 0);
6574// FIXME: Merge into a single cstring creation function.
6575// FIXME: This Decl should be more precise.
6577CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
6578 const Decl *Container) {
6579 std::string TypeStr =
6580 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container);
6581 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
6584void CGObjCMac::FinishModule() {
6587 // Emit the dummy bodies for any protocols which were referenced but
6589 for (auto &entry : Protocols) {
6590 llvm::GlobalVariable *global = entry.second;
6591 if (global->hasInitializer())
6594 ConstantInitBuilder builder(CGM);
6595 auto values = builder.beginStruct(ObjCTypes.ProtocolTy);
6596 values.addNullPointer(ObjCTypes.ProtocolExtensionPtrTy);
6597 values.add(GetClassName(entry.first->getName()));
6598 values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
6599 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy);
6600 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy);
6601 values.finishAndSetAsInitializer(global);
6602 CGM.addCompilerUsedGlobal(global);
6605 // Add assembler directives to add lazy undefined symbol references
6606 // for classes which are referenced but not defined. This is
6607 // important for correct linker interaction.
6609 // FIXME: It would be nice if we had an LLVM construct for this.
6610 if ((!LazySymbols.empty() || !DefinedSymbols.empty()) &&
6611 CGM.getTriple().isOSBinFormatMachO()) {
6612 SmallString<256> Asm;
6613 llvm::raw_svector_ostream OS(Asm);
6614 for (const auto *Sym : DefinedSymbols)
6615 OS << "\t.objc_class_name_
" << Sym->getName() << "=0\n
"
6616 << "\t.globl .objc_class_name_
" << Sym->getName() << "\n
";
6617 for (const auto *Sym : LazySymbols)
6618 OS << "\t.lazy_reference .objc_class_name_
" << Sym->getName() << "\n
";
6619 for (const auto &Category : DefinedCategoryNames)
6620 OS << "\t.objc_category_name_
" << Category << "=0\n
"
6621 << "\t.globl .objc_category_name_
" << Category << "\n
";
6623 CGM.getModule().appendModuleInlineAsm(OS.str());
6627CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
6628 : CGObjCCommonMac(cgm), ObjCTypes(cgm), ObjCEmptyCacheVar(nullptr),
6629 ObjCEmptyVtableVar(nullptr) {
6635ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
6636 : VMContext(cgm.getLLVMContext()), CGM(cgm) {
6637 CodeGen::CodeGenTypes &Types = CGM.getTypes();
6638 ASTContext &Ctx = CGM.getContext();
6639 unsigned ProgramAS = CGM.getDataLayout().getProgramAddressSpace();
6641 ShortTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.ShortTy));
6643 LongTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.LongTy));
6644 Int8PtrTy = CGM.Int8PtrTy;
6645 Int8PtrProgramASTy = llvm::PointerType::get(CGM.getLLVMContext(), ProgramAS);
6646 Int8PtrPtrTy = CGM.Int8PtrPtrTy;
6648 // arm64 targets use "int" ivar offset variables. All others,
6649 // including OS X x86_64 and Windows x86_64, use "long" ivar offsets.
6650 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::aarch64)
6651 IvarOffsetVarTy = IntTy;
6653 IvarOffsetVarTy = LongTy;
6655 ObjectPtrTy = cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCIdType()));
6656 PtrObjectPtrTy = llvm::PointerType::getUnqual(VMContext);
6658 cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCSelType()));
6660 // I'm not sure I like this. The implicit coordination is a bit
6661 // gross. We should solve this in a reasonable fashion because this
6662 // is a pretty common task (match some runtime data structure with
6663 // an LLVM data structure).
6665 // FIXME: This is leaked.
6666 // FIXME: Merge with rewriter code?
6668 // struct _objc_super {
6672 RecordDecl *RD = RecordDecl::Create(
6673 Ctx, TagTypeKind::Struct, Ctx.getTranslationUnitDecl(), SourceLocation(),
6674 SourceLocation(), &Ctx.Idents.get("_objc_super
"));
6675 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
6676 nullptr, Ctx.getObjCIdType(), nullptr, nullptr,
6677 false, ICIS_NoInit));
6678 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
6679 nullptr, Ctx.getObjCClassType(), nullptr,
6680 nullptr, false, ICIS_NoInit));
6681 RD->completeDefinition();
6683 SuperCTy = Ctx.getCanonicalTagType(RD);
6684 SuperPtrCTy = Ctx.getPointerType(SuperCTy);
6686 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
6687 SuperPtrTy = llvm::PointerType::getUnqual(VMContext);
6691 // char *attributes;
6693 PropertyTy = llvm::StructType::create("struct._prop_t
", Int8PtrTy, Int8PtrTy);
6695 // struct _prop_list_t {
6696 // uint32_t entsize; // sizeof(struct _prop_t)
6697 // uint32_t count_of_properties;
6698 // struct _prop_t prop_list[count_of_properties];
6700 PropertyListTy = llvm::StructType::create(
6701 "struct._prop_list_t
", IntTy, IntTy, llvm::ArrayType::get(PropertyTy, 0));
6702 // struct _prop_list_t *
6703 PropertyListPtrTy = llvm::PointerType::getUnqual(VMContext);
6705 // struct _objc_method {
6707 // char *method_type;
6710 MethodTy = llvm::StructType::create("struct._objc_method
", SelectorPtrTy,
6711 Int8PtrTy, Int8PtrProgramASTy);
6713 // struct _objc_cache *
6714 CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache
");
6715 CachePtrTy = llvm::PointerType::getUnqual(VMContext);
6718ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
6719 : ObjCCommonTypesHelper(cgm) {
6720 // struct _objc_method_description {
6724 MethodDescriptionTy = llvm::StructType::create(
6725 "struct._objc_method_description
", SelectorPtrTy, Int8PtrTy);
6727 // struct _objc_method_description_list {
6729 // struct _objc_method_description[1];
6731 MethodDescriptionListTy =
6732 llvm::StructType::create("struct._objc_method_description_list
", IntTy,
6733 llvm::ArrayType::get(MethodDescriptionTy, 0));
6735 // struct _objc_method_description_list *
6736 MethodDescriptionListPtrTy = llvm::PointerType::getUnqual(VMContext);
6738 // Protocol description structures
6740 // struct _objc_protocol_extension {
6741 // uint32_t size; // sizeof(struct _objc_protocol_extension)
6742 // struct _objc_method_description_list *optional_instance_methods;
6743 // struct _objc_method_description_list *optional_class_methods;
6744 // struct _objc_property_list *instance_properties;
6745 // const char ** extendedMethodTypes;
6746 // struct _objc_property_list *class_properties;
6748 ProtocolExtensionTy = llvm::StructType::create(
6749 "struct._objc_protocol_extension
", IntTy, MethodDescriptionListPtrTy,
6750 MethodDescriptionListPtrTy, PropertyListPtrTy, Int8PtrPtrTy,
6753 // struct _objc_protocol_extension *
6754 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(VMContext);
6756 // Handle construction of Protocol and ProtocolList types
6758 // struct _objc_protocol {
6759 // struct _objc_protocol_extension *isa;
6760 // char *protocol_name;
6761 // struct _objc_protocol **_objc_protocol_list;
6762 // struct _objc_method_description_list *instance_methods;
6763 // struct _objc_method_description_list *class_methods;
6765 ProtocolTy = llvm::StructType::create(
6766 {ProtocolExtensionPtrTy, Int8PtrTy,
6767 llvm::PointerType::getUnqual(VMContext), MethodDescriptionListPtrTy,
6768 MethodDescriptionListPtrTy},
6769 "struct._objc_protocol
");
6772 llvm::StructType::create({llvm::PointerType::getUnqual(VMContext), LongTy,
6773 llvm::ArrayType::get(ProtocolTy, 0)},
6774 "struct._objc_protocol_list
");
6776 // struct _objc_protocol_list *
6777 ProtocolListPtrTy = llvm::PointerType::getUnqual(VMContext);
6779 ProtocolPtrTy = llvm::PointerType::getUnqual(VMContext);
6781 // Class description structures
6783 // struct _objc_ivar {
6788 IvarTy = llvm::StructType::create("struct._objc_ivar
", Int8PtrTy, Int8PtrTy,
6791 // struct _objc_ivar_list *
6792 IvarListTy = llvm::StructType::create(VMContext, "struct._objc_ivar_list
");
6793 IvarListPtrTy = llvm::PointerType::getUnqual(VMContext);
6795 // struct _objc_method_list *
6797 llvm::StructType::create(VMContext, "struct._objc_method_list
");
6798 MethodListPtrTy = llvm::PointerType::getUnqual(VMContext);
6800 // struct _objc_class_extension *
6801 ClassExtensionTy = llvm::StructType::create(
6802 "struct._objc_class_extension
", IntTy, Int8PtrTy, PropertyListPtrTy);
6803 ClassExtensionPtrTy = llvm::PointerType::getUnqual(VMContext);
6805 // struct _objc_class {
6807 // Class super_class;
6811 // long instance_size;
6812 // struct _objc_ivar_list *ivars;
6813 // struct _objc_method_list *methods;
6814 // struct _objc_cache *cache;
6815 // struct _objc_protocol_list *protocols;
6816 // char *ivar_layout;
6817 // struct _objc_class_ext *ext;
6819 ClassTy = llvm::StructType::create(
6820 {llvm::PointerType::getUnqual(VMContext),
6821 llvm::PointerType::getUnqual(VMContext), Int8PtrTy, LongTy, LongTy,
6822 LongTy, IvarListPtrTy, MethodListPtrTy, CachePtrTy, ProtocolListPtrTy,
6823 Int8PtrTy, ClassExtensionPtrTy},
6824 "struct._objc_class
");
6826 ClassPtrTy = llvm::PointerType::getUnqual(VMContext);
6828 // struct _objc_category {
6829 // char *category_name;
6830 // char *class_name;
6831 // struct _objc_method_list *instance_method;
6832 // struct _objc_method_list *class_method;
6833 // struct _objc_protocol_list *protocols;
6834 // uint32_t size; // sizeof(struct _objc_category)
6835 // struct _objc_property_list *instance_properties;// category's @property
6836 // struct _objc_property_list *class_properties;
6838 CategoryTy = llvm::StructType::create(
6839 "struct._objc_category
", Int8PtrTy, Int8PtrTy, MethodListPtrTy,
6840 MethodListPtrTy, ProtocolListPtrTy, IntTy, PropertyListPtrTy,
6843 // Global metadata structures
6845 // struct _objc_symtab {
6846 // long sel_ref_cnt;
6848 // short cls_def_cnt;
6849 // short cat_def_cnt;
6850 // char *defs[cls_def_cnt + cat_def_cnt];
6852 SymtabTy = llvm::StructType::create("struct._objc_symtab
", LongTy,
6853 SelectorPtrTy, ShortTy, ShortTy,
6854 llvm::ArrayType::get(Int8PtrTy, 0));
6855 SymtabPtrTy = llvm::PointerType::getUnqual(VMContext);
6857 // struct _objc_module {
6859 // long size; // sizeof(struct _objc_module)
6861 // struct _objc_symtab* symtab;
6863 ModuleTy = llvm::StructType::create("struct._objc_module
", LongTy, LongTy,
6864 Int8PtrTy, SymtabPtrTy);
6866 // FIXME: This is the size of the setjmp buffer and should be target
6867 // specific. 18 is what's used on 32-bit X86.
6868 uint64_t SetJmpBufferSize = 18;
6871 llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4);
6873 ExceptionDataTy = llvm::StructType::create(
6874 "struct._objc_exception_data
",
6875 llvm::ArrayType::get(CGM.Int32Ty, SetJmpBufferSize), StackPtrTy);
6878ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(
6879 CodeGen::CodeGenModule &cgm)
6880 : ObjCCommonTypesHelper(cgm) {
6881 // struct _method_list_t {
6882 // uint32_t entsize; // sizeof(struct _objc_method)
6883 // uint32_t method_count;
6884 // struct _objc_method method_list[method_count];
6887 llvm::StructType::create("struct.__method_list_t
", IntTy, IntTy,
6888 llvm::ArrayType::get(MethodTy, 0));
6889 // struct method_list_t *
6890 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6892 // struct _protocol_t {
6894 // const char * const protocol_name;
6895 // const struct _protocol_list_t * protocol_list; // super protocols
6896 // const struct method_list_t * const instance_methods;
6897 // const struct method_list_t * const class_methods;
6898 // const struct method_list_t *optionalInstanceMethods;
6899 // const struct method_list_t *optionalClassMethods;
6900 // const struct _prop_list_t * properties;
6901 // const uint32_t size; // sizeof(struct _protocol_t)
6902 // const uint32_t flags; // = 0
6903 // const char ** extendedMethodTypes;
6904 // const char *demangledName;
6905 // const struct _prop_list_t * class_properties;
6908 ProtocolnfABITy = llvm::StructType::create(
6909 "struct._protocol_t
", ObjectPtrTy, Int8PtrTy,
6910 llvm::PointerType::getUnqual(VMContext), MethodListnfABIPtrTy,
6911 MethodListnfABIPtrTy, MethodListnfABIPtrTy, MethodListnfABIPtrTy,
6912 PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy, Int8PtrTy,
6915 // struct _protocol_t*
6916 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6918 // struct _protocol_list_t {
6919 // long protocol_count; // Note, this is 32/64 bit
6920 // struct _protocol_t *[protocol_count];
6922 ProtocolListnfABITy = llvm::StructType::create(
6923 {LongTy, llvm::ArrayType::get(ProtocolnfABIPtrTy, 0)},
6924 "struct._objc_protocol_list
");
6926 // struct _objc_protocol_list*
6927 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6930 // unsigned [long] int *offset; // pointer to ivar offset location
6933 // uint32_t alignment;
6936 IvarnfABITy = llvm::StructType::create(
6937 "struct._ivar_t
", llvm::PointerType::getUnqual(VMContext), Int8PtrTy,
6938 Int8PtrTy, IntTy, IntTy);
6940 // struct _ivar_list_t {
6941 // uint32 entsize; // sizeof(struct _ivar_t)
6943 // struct _iver_t list[count];
6946 llvm::StructType::create("struct._ivar_list_t
", IntTy, IntTy,
6947 llvm::ArrayType::get(IvarnfABITy, 0));
6949 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6951 // struct _class_ro_t {
6952 // uint32_t const flags;
6953 // uint32_t const instanceStart;
6954 // uint32_t const instanceSize;
6955 // uint32_t const reserved; // only when building for 64bit targets
6956 // const uint8_t * const ivarLayout;
6957 // const char *const name;
6958 // const struct _method_list_t * const baseMethods;
6959 // const struct _objc_protocol_list *const baseProtocols;
6960 // const struct _ivar_list_t *const ivars;
6961 // const uint8_t * const weakIvarLayout;
6962 // const struct _prop_list_t * const properties;
6965 // FIXME. Add 'reserved' field in 64bit abi mode!
6966 ClassRonfABITy = llvm::StructType::create(
6967 "struct._class_ro_t
", IntTy, IntTy, IntTy, Int8PtrTy, Int8PtrTy,
6968 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, IvarListnfABIPtrTy,
6969 Int8PtrTy, PropertyListPtrTy);
6971 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
6972 ImpnfABITy = CGM.DefaultPtrTy;
6974 // struct _class_t {
6975 // struct _class_t *isa;
6976 // struct _class_t * const superclass;
6979 // struct class_ro_t *ro;
6982 ClassnfABITy = llvm::StructType::create(
6983 {llvm::PointerType::getUnqual(VMContext),
6984 llvm::PointerType::getUnqual(VMContext), CachePtrTy,
6985 llvm::PointerType::getUnqual(VMContext),
6986 llvm::PointerType::getUnqual(VMContext)},
6989 // LLVM for struct _class_t *
6990 ClassnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6992 // struct _category_t {
6993 // const char * const name;
6994 // struct _class_t *const cls;
6995 // const struct _method_list_t * const instance_methods;
6996 // const struct _method_list_t * const class_methods;
6997 // const struct _protocol_list_t * const protocols;
6998 // const struct _prop_list_t * const properties;
6999 // const struct _prop_list_t * const class_properties;
7000 // const uint32_t size;
7002 CategorynfABITy = llvm::StructType::create(
7003 "struct._category_t
", Int8PtrTy, ClassnfABIPtrTy, MethodListnfABIPtrTy,
7004 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, PropertyListPtrTy,
7005 PropertyListPtrTy, IntTy);
7007 // New types for nonfragile abi messaging.
7008 CodeGen::CodeGenTypes &Types = CGM.getTypes();
7009 ASTContext &Ctx = CGM.getContext();
7011 // MessageRefTy - LLVM for:
7012 // struct _message_ref_t {
7017 // First the clang type for struct _message_ref_t
7018 RecordDecl *RD = RecordDecl::Create(
7019 Ctx, TagTypeKind::Struct, Ctx.getTranslationUnitDecl(), SourceLocation(),
7020 SourceLocation(), &Ctx.Idents.get("_message_ref_t
"));
7021 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
7022 nullptr, Ctx.VoidPtrTy, nullptr, nullptr, false,
7024 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
7025 nullptr, Ctx.getObjCSelType(), nullptr, nullptr,
7026 false, ICIS_NoInit));
7027 RD->completeDefinition();
7029 MessageRefCTy = Ctx.getCanonicalTagType(RD);
7030 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy);
7031 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy));
7033 // MessageRefPtrTy - LLVM for struct _message_ref_t*
7034 MessageRefPtrTy = llvm::PointerType::getUnqual(VMContext);
7036 // SuperMessageRefTy - LLVM for:
7037 // struct _super_message_ref_t {
7038 // SUPER_IMP messenger;
7041 SuperMessageRefTy = llvm::StructType::create("struct._super_message_ref_t
",
7042 ImpnfABITy, SelectorPtrTy);
7044 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
7045 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(VMContext);
7047 // struct objc_typeinfo {
7048 // const void** vtable; // objc_ehtype_vtable + 2
7049 // const char* name; // c++ typeinfo string
7052 EHTypeTy = llvm::StructType::create("struct._objc_typeinfo
",
7053 llvm::PointerType::getUnqual(VMContext),
7054 Int8PtrTy, ClassnfABIPtrTy);
7055 EHTypePtrTy = llvm::PointerType::getUnqual(VMContext);
7058llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
7059 FinishNonFragileABIModule();
7064void CGObjCNonFragileABIMac::AddModuleClassList(
7065 ArrayRef<llvm::GlobalValue *> Container, StringRef SymbolName,
7066 StringRef SectionName) {
7067 unsigned NumClasses = Container.size();
7072 SmallVector<llvm::Constant *, 8> Symbols(NumClasses);
7073 for (unsigned i = 0; i < NumClasses; i++)
7074 Symbols[i] = Container[i];
7076 llvm::Constant *Init = llvm::ConstantArray::get(
7077 llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Symbols.size()), Symbols);
7079 // Section name is obtained by calling GetSectionName, which returns
7080 // sections in the __DATA segment on MachO.
7081 assert((!CGM.getTriple().isOSBinFormatMachO() ||
7082 SectionName.starts_with("__DATA
")) &&
7083 "SectionName expected to start with __DATA on
MachO");
7084 llvm::GlobalVariable *GV = new llvm::GlobalVariable(
7085 CGM.getModule(), Init->getType(), false,
7086 llvm::GlobalValue::PrivateLinkage, Init, SymbolName);
7087 GV->setAlignment(CGM.getDataLayout().getABITypeAlign(Init->getType()));
7088 GV->setSection(SectionName);
7089 CGM.addCompilerUsedGlobal(GV);
7092void CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
7093 // nonfragile abi has no module definition.
7095 // Build list of all implemented class addresses in array
7096 // L_OBJC_LABEL_CLASS_$.
7098 for (unsigned i = 0, NumClasses = ImplementedClasses.size(); i < NumClasses;
7100 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
7102 if (ObjCImplementationDecl *IMP = ID->getImplementation())
7103 // We are implementing a weak imported interface. Give it external linkage
7104 if (ID->isWeakImported() && !IMP->isWeakImported()) {
7105 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
7106 DefinedMetaClasses[i]->setLinkage(
7107 llvm::GlobalVariable::ExternalLinkage);
7112 DefinedClasses, "OBJC_LABEL_CLASS_$
",
7113 GetSectionName("__objc_classlist
", "regular,no_dead_strip
"));
7116 DefinedNonLazyClasses, "OBJC_LABEL_NONLAZY_CLASS_$
",
7117 GetSectionName("__objc_nlclslist
", "regular,no_dead_strip
"));
7119 // Build list of all implemented category addresses in array
7120 // L_OBJC_LABEL_CATEGORY_$.
7121 AddModuleClassList(DefinedCategories, "OBJC_LABEL_CATEGORY_$
",
7122 GetSectionName("__objc_catlist
", "regular,no_dead_strip
"));
7124 DefinedStubCategories, "OBJC_LABEL_STUB_CATEGORY_$
",
7125 GetSectionName("__objc_catlist2
", "regular,no_dead_strip
"));
7127 DefinedNonLazyCategories, "OBJC_LABEL_NONLAZY_CATEGORY_$
",
7128 GetSectionName("__objc_nlcatlist
", "regular,no_dead_strip
"));
7137bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
7138 // At various points we've experimented with using vtable-based
7139 // dispatch for all methods.
7140 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
7141 case CodeGenOptions::Legacy:
7143 case CodeGenOptions::NonLegacy:
7145 case CodeGenOptions::Mixed:
7149 // If so, see whether this selector is in the white-list of things which must
7150 // use the new dispatch convention. We lazily build a dense set for this.
7151 if (VTableDispatchMethods.empty()) {
7152 VTableDispatchMethods.insert(GetNullarySelector("alloc
"));
7153 VTableDispatchMethods.insert(GetNullarySelector("class"));
7154 VTableDispatchMethods.insert(GetNullarySelector("self
"));
7155 VTableDispatchMethods.insert(GetNullarySelector("isFlipped
"));
7156 VTableDispatchMethods.insert(GetNullarySelector("length"));
7157 VTableDispatchMethods.insert(GetNullarySelector("count
"));
7159 // These are vtable-based if GC is disabled.
7160 // Optimistically use vtable dispatch for hybrid compiles.
7161 if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) {
7162 VTableDispatchMethods.insert(GetNullarySelector("retain
"));
7163 VTableDispatchMethods.insert(GetNullarySelector("release
"));
7164 VTableDispatchMethods.insert(GetNullarySelector("autorelease
"));
7167 VTableDispatchMethods.insert(GetUnarySelector("allocWithZone
"));
7168 VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass
"));
7169 VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector
"));
7170 VTableDispatchMethods.insert(GetUnarySelector("objectForKey
"));
7171 VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex
"));
7172 VTableDispatchMethods.insert(GetUnarySelector("isEqualToString
"));
7173 VTableDispatchMethods.insert(GetUnarySelector("isEqual
"));
7175 // These are vtable-based if GC is enabled.
7176 // Optimistically use vtable dispatch for hybrid compiles.
7177 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
7178 VTableDispatchMethods.insert(GetNullarySelector("hash
"));
7179 VTableDispatchMethods.insert(GetUnarySelector("addObject
"));
7181 // "countByEnumeratingWithState:objects:count
"
7182 const IdentifierInfo *KeyIdents[] = {
7183 &CGM.getContext().Idents.get("countByEnumeratingWithState
"),
7184 &CGM.getContext().Idents.get("objects
"),
7185 &CGM.getContext().Idents.get("count
")};
7186 VTableDispatchMethods.insert(
7187 CGM.getContext().Selectors.getSelector(3, KeyIdents));
7191 return VTableDispatchMethods.count(Sel);
7209llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassRoTInitializer(
7210 unsigned flags, unsigned InstanceStart, unsigned InstanceSize,
7211 const ObjCImplementationDecl *ID) {
7212 std::string ClassName = std::string(ID->getObjCRuntimeNameAsString());
7214 CharUnits beginInstance = CharUnits::fromQuantity(InstanceStart);
7215 CharUnits endInstance = CharUnits::fromQuantity(InstanceSize);
7217 bool hasMRCWeak = false;
7218 if (CGM.getLangOpts().ObjCAutoRefCount)
7219 flags |= NonFragileABI_Class_CompiledByARC;
7220 else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))
7221 flags |= NonFragileABI_Class_HasMRCWeakIvars;
7223 ConstantInitBuilder builder(CGM);
7224 auto values = builder.beginStruct(ObjCTypes.ClassRonfABITy);
7226 values.addInt(ObjCTypes.IntTy, flags);
7227 values.addInt(ObjCTypes.IntTy, InstanceStart);
7228 values.addInt(ObjCTypes.IntTy, InstanceSize);
7229 values.add((flags & NonFragileABI_Class_Meta)
7230 ? GetIvarLayoutName(nullptr, ObjCTypes)
7231 : BuildStrongIvarLayout(ID, beginInstance, endInstance));
7232 values.add(GetClassName(ID->getObjCRuntimeNameAsString()));
7234 // const struct _method_list_t * const baseMethods;
7235 SmallVector<const ObjCMethodDecl *, 16> methods;
7236 if (flags & NonFragileABI_Class_Meta) {
7237 for (const auto *MD : ID->class_methods())
7238 if (!MD->isDirectMethod())
7239 methods.push_back(MD);
7241 for (const auto *MD : ID->instance_methods())
7242 if (!MD->isDirectMethod())
7243 methods.push_back(MD);
7246 llvm::Constant *MethListPtr = emitMethodList(
7247 ID->getObjCRuntimeNameAsString(),
7248 (flags & NonFragileABI_Class_Meta) ? MethodListType::ClassMethods
7249 : MethodListType::InstanceMethods,
7252 const PointerAuthSchema &MethListSchema =
7253 CGM.getCodeGenOpts().PointerAuth.ObjCMethodListPointer;
7254 if (!MethListPtr->isNullValue())
7255 values.addSignedPointer(MethListPtr, MethListSchema, GlobalDecl(),
7258 values.add(MethListPtr);
7260 const ObjCInterfaceDecl *OID = ID->getClassInterface();
7261 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer
");
7262 values.add(EmitProtocolList("_OBJC_CLASS_PROTOCOLS_$_
" +
7263 OID->getObjCRuntimeNameAsString(),
7264 OID->all_referenced_protocol_begin(),
7265 OID->all_referenced_protocol_end()));
7267 if (flags & NonFragileABI_Class_Meta) {
7268 values.addNullPointer(ObjCTypes.IvarListnfABIPtrTy);
7269 values.add(GetIvarLayoutName(nullptr, ObjCTypes));
7270 values.add(EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_
" +
7271 ID->getObjCRuntimeNameAsString(),
7272 ID, ID->getClassInterface(), ObjCTypes, true));
7274 values.add(EmitIvarList(ID));
7275 values.add(BuildWeakIvarLayout(ID, beginInstance, endInstance, hasMRCWeak));
7276 values.add(EmitPropertyList("_OBJC_$_PROP_LIST_
" +
7277 ID->getObjCRuntimeNameAsString(),
7278 ID, ID->getClassInterface(), ObjCTypes, false));
7281 llvm::SmallString<64> roLabel;
7282 llvm::raw_svector_ostream(roLabel)
7283 << ((flags & NonFragileABI_Class_Meta) ? "_OBJC_METACLASS_RO_$_
"
7284 : "_OBJC_CLASS_RO_$_
")
7287 return finishAndCreateGlobal(values, roLabel, CGM);
7300llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassObject(
7301 const ObjCInterfaceDecl *CI, bool isMetaclass, llvm::Constant *IsAGV,
7302 llvm::Constant *SuperClassGV, llvm::Constant *ClassRoGV,
7303 bool HiddenVisibility) {
7304 ConstantInitBuilder builder(CGM);
7305 auto values = builder.beginStruct(ObjCTypes.ClassnfABITy);
7306 const PointerAuthOptions &PointerAuthOpts = CGM.getCodeGenOpts().PointerAuth;
7307 values.addSignedPointer(IsAGV, PointerAuthOpts.ObjCIsaPointers, GlobalDecl(),
7310 values.addSignedPointer(SuperClassGV, PointerAuthOpts.ObjCSuperPointers,
7311 GlobalDecl(), QualType());
7313 values.addNullPointer(ObjCTypes.ClassnfABIPtrTy);
7315 values.add(ObjCEmptyCacheVar);
7316 values.add(ObjCEmptyVtableVar);
7318 values.addSignedPointer(ClassRoGV, PointerAuthOpts.ObjCClassROPointers,
7319 GlobalDecl(), QualType());
7321 llvm::GlobalVariable *GV = cast<llvm::GlobalVariable>(
7322 GetClassGlobal(CI, isMetaclass, ForDefinition));
7323 values.finishAndSetAsInitializer(GV);
7325 if (CGM.getTriple().isOSBinFormatMachO())
7326 GV->setSection("__DATA, __objc_data
");
7327 GV->setAlignment(CGM.getDataLayout().getABITypeAlign(ObjCTypes.ClassnfABITy));
7328 if (!CGM.getTriple().isOSBinFormatCOFF())
7329 if (HiddenVisibility)
7330 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
7331 if (CGM.getCodeGenOpts().ObjCMsgSendClassSelectorStubs && !isMetaclass)
7332 CGM.addUsedGlobal(GV);
7336bool CGObjCNonFragileABIMac::ImplementationIsNonLazy(
7337 const ObjCImplDecl *OD) const {
7338 return OD->getClassMethod(GetNullarySelector("load
")) != nullptr ||
7339 OD->getClassInterface()->hasAttr<ObjCNonLazyClassAttr>() ||
7340 OD->hasAttr<ObjCNonLazyClassAttr>();
7343void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
7344 uint32_t &InstanceStart,
7345 uint32_t &InstanceSize) {
7346 const ASTRecordLayout &RL =
7347 CGM.getContext().getASTObjCInterfaceLayout(OID->getClassInterface());
7349 // InstanceSize is really instance end.
7350 InstanceSize = RL.getDataSize().getQuantity();
7352 // If there are no fields, the start is the same as the end.
7353 if (!RL.getFieldCount())
7354 InstanceStart = InstanceSize;
7356 InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth();
7359static llvm::GlobalValue::DLLStorageClassTypes getStorage(CodeGenModule &CGM,
7361 IdentifierInfo &II = CGM.getContext().Idents.get(Name);
7362 TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl();
7363 DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl);
7365 const VarDecl *VD = nullptr;
7366 for (const auto *Result : DC->lookup(&II))
7367 if ((VD = dyn_cast<VarDecl>(Result)))
7371 return llvm::GlobalValue::DLLImportStorageClass;
7372 if (VD->hasAttr<DLLExportAttr>())
7373 return llvm::GlobalValue::DLLExportStorageClass;
7374 if (VD->hasAttr<DLLImportAttr>())
7375 return llvm::GlobalValue::DLLImportStorageClass;
7376 return llvm::GlobalValue::DefaultStorageClass;
7379void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
7380 if (!ObjCEmptyCacheVar) {
7381 ObjCEmptyCacheVar = new llvm::GlobalVariable(
7382 CGM.getModule(), ObjCTypes.CacheTy, false,
7383 llvm::GlobalValue::ExternalLinkage, nullptr, "_objc_empty_cache
");
7384 if (CGM.getTriple().isOSBinFormatCOFF())
7385 ObjCEmptyCacheVar->setDLLStorageClass(
7386 getStorage(CGM, "_objc_empty_cache
"));
7388 // Only OS X with deployment version <10.9 use the empty vtable symbol
7389 const llvm::Triple &Triple = CGM.getTarget().getTriple();
7390 if (Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 9))
7391 ObjCEmptyVtableVar = new llvm::GlobalVariable(
7392 CGM.getModule(), ObjCTypes.ImpnfABITy, false,
7393 llvm::GlobalValue::ExternalLinkage, nullptr, "_objc_empty_vtable
");
7395 ObjCEmptyVtableVar = llvm::ConstantPointerNull::get(CGM.DefaultPtrTy);
7398 // FIXME: Is this correct (that meta class size is never computed)?
7399 uint32_t InstanceStart =
7400 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy);
7401 uint32_t InstanceSize = InstanceStart;
7402 uint32_t flags = NonFragileABI_Class_Meta;
7404 llvm::Constant *SuperClassGV, *IsAGV;
7406 const auto *CI = ID->getClassInterface();
7407 assert(CI && "CGObjCNonFragileABIMac::GenerateClass -
class is 0
");
7409 // Build the flags for the metaclass.
7410 bool classIsHidden = (CGM.getTriple().isOSBinFormatCOFF())
7411 ? !CI->hasAttr<DLLExportAttr>()
7412 : CI->getVisibility() == HiddenVisibility;
7414 flags |= NonFragileABI_Class_Hidden;
7416 // FIXME: why is this flag set on the metaclass?
7417 // ObjC metaclasses have no fields and don't really get constructed.
7418 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
7419 flags |= NonFragileABI_Class_HasCXXStructors;
7420 if (!ID->hasNonZeroConstructors())
7421 flags |= NonFragileABI_Class_HasCXXDestructorOnly;
7424 if (!CI->getSuperClass()) {
7426 flags |= NonFragileABI_Class_Root;
7428 SuperClassGV = GetClassGlobal(CI, /*metaclass*/ false, NotForDefinition);
7429 IsAGV = GetClassGlobal(CI, /*metaclass*/ true, NotForDefinition);
7431 // Has a root. Current class is not a root.
7432 const ObjCInterfaceDecl *Root = ID->getClassInterface();
7433 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
7436 const auto *Super = CI->getSuperClass();
7437 IsAGV = GetClassGlobal(Root, /*metaclass*/ true, NotForDefinition);
7438 SuperClassGV = GetClassGlobal(Super, /*metaclass*/ true, NotForDefinition);
7441 llvm::GlobalVariable *CLASS_RO_GV =
7442 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
7444 llvm::GlobalVariable *MetaTClass = BuildClassObject(
7445 CI, /*metaclass*/ true, IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden);
7446 CGM.setGVProperties(MetaTClass, CI);
7447 DefinedMetaClasses.push_back(MetaTClass);
7449 // Metadata for the class
7452 flags |= NonFragileABI_Class_Hidden;
7454 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
7455 flags |= NonFragileABI_Class_HasCXXStructors;
7457 // Set a flag to enable a runtime optimization when a class has
7458 // fields that require destruction but which don't require
7459 // anything except zero-initialization during construction. This
7460 // is most notably true of __strong and __weak types, but you can
7461 // also imagine there being C++ types with non-trivial default
7462 // constructors that merely set all fields to null.
7463 if (!ID->hasNonZeroConstructors())
7464 flags |= NonFragileABI_Class_HasCXXDestructorOnly;
7467 if (hasObjCExceptionAttribute(CGM.getContext(), CI))
7468 flags |= NonFragileABI_Class_Exception;
7470 if (!CI->getSuperClass()) {
7471 flags |= NonFragileABI_Class_Root;
7472 SuperClassGV = nullptr;
7474 // Has a root. Current class is not a root.
7475 const auto *Super = CI->getSuperClass();
7476 SuperClassGV = GetClassGlobal(Super, /*metaclass*/ false, NotForDefinition);
7479 GetClassSizeInfo(ID, InstanceStart, InstanceSize);
7481 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
7483 llvm::GlobalVariable *ClassMD =
7484 BuildClassObject(CI, /*metaclass*/ false, MetaTClass, SuperClassGV,
7485 CLASS_RO_GV, classIsHidden);
7486 CGM.setGVProperties(ClassMD, CI);
7487 DefinedClasses.push_back(ClassMD);
7488 ImplementedClasses.push_back(CI);
7490 // Determine if this class is also "non-lazy
".
7491 if (ImplementationIsNonLazy(ID))
7492 DefinedNonLazyClasses.push_back(ClassMD);
7494 // Force the definition of the EHType if necessary.
7495 if (flags & NonFragileABI_Class_Exception)
7496 (void)GetInterfaceEHType(CI, ForDefinition);
7497 // Make sure method definition entries are all clear for next implementation.
7498 MethodDefinitions.clear();
7510CGObjCNonFragileABIMac::GenerateProtocolRef(CodeGenFunction &CGF,
7511 const ObjCProtocolDecl *PD) {
7513 // This routine is called for @protocol only. So, we must build definition
7514 // of protocol's meta-data (not a reference to it!)
7515 assert(!PD->isNonRuntimeProtocol() &&
7516 "attempting to get a protocol ref to a
static protocol.
");
7517 llvm::Constant *Init = GetOrEmitProtocol(PD);
7519 std::string ProtocolName("_OBJC_PROTOCOL_REFERENCE_$_
");
7520 ProtocolName += PD->getObjCRuntimeNameAsString();
7522 CharUnits Align = CGF.getPointerAlign();
7524 llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);
7526 return CGF.Builder.CreateAlignedLoad(PTGV->getValueType(), PTGV, Align);
7527 PTGV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
7528 llvm::GlobalValue::WeakAnyLinkage, Init,
7531 GetSectionName("__objc_protorefs
", "coalesced,no_dead_strip
"));
7532 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
7533 PTGV->setAlignment(Align.getAsAlign());
7534 if (!CGM.getTriple().isOSBinFormatMachO())
7535 PTGV->setComdat(CGM.getModule().getOrInsertComdat(ProtocolName));
7536 CGM.addUsedGlobal(PTGV);
7537 return CGF.Builder.CreateAlignedLoad(PTGV->getValueType(), PTGV, Align);
7552void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
7553 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
7554 const char *Prefix = "_OBJC_$_CATEGORY_
";
7556 llvm::SmallString<64> ExtCatName(Prefix);
7557 ExtCatName += Interface->getObjCRuntimeNameAsString();
7558 ExtCatName += "_$_
";
7559 ExtCatName += OCD->getNameAsString();
7561 ConstantInitBuilder builder(CGM);
7562 auto values = builder.beginStruct(ObjCTypes.CategorynfABITy);
7563 values.add(GetClassName(OCD->getIdentifier()->getName()));
7564 // meta-class entry symbol
7565 values.add(GetClassGlobal(Interface, /*metaclass*/ false, NotForDefinition));
7566 std::string listName =
7567 (Interface->getObjCRuntimeNameAsString() + "_$_
" + OCD->getName()).str();
7569 SmallVector<const ObjCMethodDecl *, 16> instanceMethods;
7570 SmallVector<const ObjCMethodDecl *, 8> classMethods;
7571 for (const auto *MD : OCD->methods()) {
7572 if (MD->isDirectMethod())
7574 if (MD->isInstanceMethod()) {
7575 instanceMethods.push_back(MD);
7577 classMethods.push_back(MD);
7581 llvm::Constant *InstanceMethodList = emitMethodList(
7582 listName, MethodListType::CategoryInstanceMethods, instanceMethods);
7583 const PointerAuthSchema &MethListSchema =
7584 CGM.getCodeGenOpts().PointerAuth.ObjCMethodListPointer;
7585 if (!InstanceMethodList->isNullValue())
7586 values.addSignedPointer(InstanceMethodList, MethListSchema, GlobalDecl(),
7589 values.add(InstanceMethodList);
7591 llvm::Constant *ClassMethodList = emitMethodList(
7592 listName, MethodListType::CategoryClassMethods, classMethods);
7593 if (!ClassMethodList->isNullValue())
7594 values.addSignedPointer(ClassMethodList, MethListSchema, GlobalDecl(),
7597 values.add(ClassMethodList);
7599 // Keep track of whether we have actual metadata to emit.
7600 bool isEmptyCategory =
7601 InstanceMethodList->isNullValue() && ClassMethodList->isNullValue();
7603 const ObjCCategoryDecl *Category =
7604 Interface->FindCategoryDeclaration(OCD->getIdentifier());
7606 SmallString<256> ExtName;
7607 llvm::raw_svector_ostream(ExtName)
7608 << Interface->getObjCRuntimeNameAsString() << "_$_
" << OCD->getName();
7610 EmitProtocolList("_OBJC_CATEGORY_PROTOCOLS_$_
" +
7611 Interface->getObjCRuntimeNameAsString() + "_$_
" +
7612 Category->getName(),
7613 Category->protocol_begin(), Category->protocol_end());
7614 auto propertyList = EmitPropertyList("_OBJC_$_PROP_LIST_
" + ExtName.str(),
7615 OCD, Category, ObjCTypes, false);
7616 auto classPropertyList =
7617 EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_
" + ExtName.str(), OCD,
7618 Category, ObjCTypes, true);
7619 values.add(protocolList);
7620 values.add(propertyList);
7621 values.add(classPropertyList);
7622 isEmptyCategory &= protocolList->isNullValue() &&
7623 propertyList->isNullValue() &&
7624 classPropertyList->isNullValue();
7626 values.addNullPointer(ObjCTypes.ProtocolListnfABIPtrTy);
7627 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
7628 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
7631 if (isEmptyCategory) {
7632 // Empty category, don't emit any metadata.
7634 MethodDefinitions.clear();
7639 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.CategorynfABITy);
7640 values.addInt(ObjCTypes.IntTy, Size);
7642 llvm::GlobalVariable *GCATV =
7643 finishAndCreateGlobal(values, ExtCatName.str(), CGM);
7644 CGM.addCompilerUsedGlobal(GCATV);
7645 if (Interface->hasAttr<ObjCClassStubAttr>())
7646 DefinedStubCategories.push_back(GCATV);
7648 DefinedCategories.push_back(GCATV);
7650 // Determine if this category is also "non-lazy
".
7651 if (ImplementationIsNonLazy(OCD))
7652 DefinedNonLazyCategories.push_back(GCATV);
7653 // method definition entries must be clear for next implementation.
7654 MethodDefinitions.clear();
7666void CGObjCNonFragileABIMac::emitMethodConstant(ConstantArrayBuilder &builder,
7667 const ObjCMethodDecl *MD,
7669 auto method = builder.beginStruct(ObjCTypes.MethodTy);
7670 method.add(GetMethodVarName(MD->getSelector()));
7671 method.add(GetMethodVarType(MD));
7674 // Protocol methods have no implementation. So, this entry is always NULL.
7675 method.addNullPointer(ObjCTypes.Int8PtrProgramASTy);
7677 llvm::Function *fn = GetMethodDefinition(MD);
7678 assert(fn && "no definition
for method?
");
7679 if (const PointerAuthSchema &Schema =
7680 CGM.getCodeGenOpts().PointerAuth.ObjCMethodListFunctionPointers) {
7681 llvm::Constant *Bitcast =
7682 llvm::ConstantExpr::getBitCast(fn, ObjCTypes.Int8PtrProgramASTy);
7683 method.addSignedPointer(Bitcast, Schema, GlobalDecl(), QualType());
7688 method.finishAndAddTo(builder);
7699llvm::Constant *CGObjCNonFragileABIMac::emitMethodList(
7700 Twine name, MethodListType kind, ArrayRef<const ObjCMethodDecl *> methods) {
7701 // Return null for empty list.
7702 if (methods.empty())
7703 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
7708 case MethodListType::CategoryInstanceMethods:
7709 prefix = "_OBJC_$_CATEGORY_INSTANCE_METHODS_
";
7710 forProtocol = false;
7712 case MethodListType::CategoryClassMethods:
7713 prefix = "_OBJC_$_CATEGORY_CLASS_METHODS_
";
7714 forProtocol = false;
7716 case MethodListType::InstanceMethods:
7717 prefix = "_OBJC_$_INSTANCE_METHODS_
";
7718 forProtocol = false;
7720 case MethodListType::ClassMethods:
7721 prefix = "_OBJC_$_CLASS_METHODS_
";
7722 forProtocol = false;
7725 case MethodListType::ProtocolInstanceMethods:
7726 prefix = "_OBJC_$_PROTOCOL_INSTANCE_METHODS_
";
7729 case MethodListType::ProtocolClassMethods:
7730 prefix = "_OBJC_$_PROTOCOL_CLASS_METHODS_
";
7733 case MethodListType::OptionalProtocolInstanceMethods:
7734 prefix = "_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_
";
7737 case MethodListType::OptionalProtocolClassMethods:
7738 prefix = "_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_
";
7743 ConstantInitBuilder builder(CGM);
7744 auto values = builder.beginStruct();
7746 // sizeof(struct _objc_method)
7747 unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.MethodTy);
7748 values.addInt(ObjCTypes.IntTy, Size);
7750 values.addInt(ObjCTypes.IntTy, methods.size());
7751 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
7752 for (auto MD : methods)
7753 emitMethodConstant(methodArray, MD, forProtocol);
7754 methodArray.finishAndAddTo(values);
7756 llvm::GlobalVariable *GV = finishAndCreateGlobal(values, prefix + name, CGM);
7757 CGM.addCompilerUsedGlobal(GV);
7763llvm::GlobalVariable *
7764CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
7765 const ObjCIvarDecl *Ivar) {
7766 const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
7767 llvm::SmallString<64> Name("OBJC_IVAR_$_
");
7768 Name += Container->getObjCRuntimeNameAsString();
7770 Name += Ivar->getName();
7771 llvm::GlobalVariable *IvarOffsetGV = CGM.getModule().getGlobalVariable(Name);
7772 if (!IvarOffsetGV) {
7773 IvarOffsetGV = new llvm::GlobalVariable(
7774 CGM.getModule(), ObjCTypes.IvarOffsetVarTy, false,
7775 llvm::GlobalValue::ExternalLinkage, nullptr, Name.str());
7776 if (CGM.getTriple().isOSBinFormatCOFF()) {
7777 bool IsPrivateOrPackage =
7778 Ivar->getAccessControl() == ObjCIvarDecl::Private ||
7779 Ivar->getAccessControl() == ObjCIvarDecl::Package;
7781 const ObjCInterfaceDecl *ContainingID = Ivar->getContainingInterface();
7783 if (ContainingID->hasAttr<DLLImportAttr>())
7784 IvarOffsetGV->setDLLStorageClass(
7785 llvm::GlobalValue::DLLImportStorageClass);
7786 else if (ContainingID->hasAttr<DLLExportAttr>() && !IsPrivateOrPackage)
7787 IvarOffsetGV->setDLLStorageClass(
7788 llvm::GlobalValue::DLLExportStorageClass);
7791 return IvarOffsetGV;
7795CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
7796 const ObjCIvarDecl *Ivar,
7797 unsigned long int Offset) {
7798 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
7799 IvarOffsetGV->setInitializer(
7800 llvm::ConstantInt::get(ObjCTypes.IvarOffsetVarTy, Offset));
7801 IvarOffsetGV->setAlignment(
7802 CGM.getDataLayout().getABITypeAlign(ObjCTypes.IvarOffsetVarTy));
7804 if (!CGM.getTriple().isOSBinFormatCOFF()) {
7805 // FIXME: This matches gcc, but shouldn't the visibility be set on the use
7806 // as well (i.e., in ObjCIvarOffsetVariable).
7807 if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
7808 Ivar->getAccessControl() == ObjCIvarDecl::Package ||
7809 ID->getVisibility() == HiddenVisibility)
7810 IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
7812 IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility);
7815 // If ID's layout is known, then make the global constant. This serves as a
7816 // useful assertion: we'll never use this variable to calculate ivar offsets,
7817 // so if the runtime tries to patch it then we should crash.
7818 if (isClassLayoutKnownStatically(ID))
7819 IvarOffsetGV->setConstant(true);
7821 if (CGM.getTriple().isOSBinFormatMachO())
7822 IvarOffsetGV->setSection("__DATA, __objc_ivar
");
7823 return IvarOffsetGV;
7844CGObjCNonFragileABIMac::EmitIvarList(const ObjCImplementationDecl *ID) {
7846 ConstantInitBuilder builder(CGM);
7847 auto ivarList = builder.beginStruct();
7848 ivarList.addInt(ObjCTypes.IntTy,
7849 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.IvarnfABITy));
7850 auto ivarCountSlot = ivarList.addPlaceholder();
7851 auto ivars = ivarList.beginArray(ObjCTypes.IvarnfABITy);
7853 const ObjCInterfaceDecl *OID = ID->getClassInterface();
7854 assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface
");
7856 // FIXME. Consolidate this with similar code in GenerateClass.
7858 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin(); IVD;
7859 IVD = IVD->getNextIvar()) {
7860 // Ignore unnamed bit-fields.
7861 if (!IVD->getDeclName())
7864 auto ivar = ivars.beginStruct(ObjCTypes.IvarnfABITy);
7865 ivar.add(EmitIvarOffsetVar(ID->getClassInterface(), IVD,
7866 ComputeIvarBaseOffset(CGM, ID, IVD)));
7867 ivar.add(GetMethodVarName(IVD->getIdentifier()));
7868 ivar.add(GetMethodVarType(IVD));
7869 llvm::Type *FieldTy = CGM.getTypes().ConvertTypeForMem(IVD->getType());
7870 unsigned Size = CGM.getDataLayout().getTypeAllocSize(FieldTy);
7872 CGM.getContext().getPreferredTypeAlign(IVD->getType().getTypePtr()) >>
7874 Align = llvm::Log2_32(Align);
7875 ivar.addInt(ObjCTypes.IntTy, Align);
7876 // NOTE. Size of a bitfield does not match gcc's, because of the
7877 // way bitfields are treated special in each. But I am told that
7878 // 'size' for bitfield ivars is ignored by the runtime so it does
7879 // not matter. If it matters, there is enough info to get the
7881 ivar.addInt(ObjCTypes.IntTy, Size);
7882 ivar.finishAndAddTo(ivars);
7884 // Return null for empty list.
7885 if (ivars.empty()) {
7888 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
7891 auto ivarCount = ivars.size();
7892 ivars.finishAndAddTo(ivarList);
7893 ivarList.fillPlaceholderWithInt(ivarCountSlot, ObjCTypes.IntTy, ivarCount);
7895 const char *Prefix = "_OBJC_$_INSTANCE_VARIABLES_
";
7896 llvm::GlobalVariable *GV = finishAndCreateGlobal(
7897 ivarList, Prefix + OID->getObjCRuntimeNameAsString(), CGM);
7898 CGM.addCompilerUsedGlobal(GV);
7903CGObjCNonFragileABIMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {
7904 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
7906 assert(!PD->isNonRuntimeProtocol() &&
7907 "attempting to GetOrEmit a non-runtime protocol
");
7909 // We use the initializer as a marker of whether this is a forward
7910 // reference or not. At module finalization we add the empty
7911 // contents for protocols which were referenced but never defined.
7912 llvm::SmallString<64> Protocol;
7913 llvm::raw_svector_ostream(Protocol)
7914 << "_OBJC_PROTOCOL_$_
" << PD->getObjCRuntimeNameAsString();
7916 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
7917 false, llvm::GlobalValue::ExternalLinkage,
7919 if (!CGM.getTriple().isOSBinFormatMachO())
7920 Entry->setComdat(CGM.getModule().getOrInsertComdat(Protocol));
7947CGObjCNonFragileABIMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
7948 llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
7950 // Early exit if a defining object has already been generated.
7951 if (Entry && Entry->hasInitializer())
7954 // Use the protocol definition, if there is one.
7955 assert(PD->hasDefinition() &&
7956 "emitting protocol metadata without definition
");
7957 PD = PD->getDefinition();
7959 auto methodLists = ProtocolMethodLists::get(PD);
7961 ConstantInitBuilder builder(CGM);
7962 auto values = builder.beginStruct(ObjCTypes.ProtocolnfABITy);
7965 values.addNullPointer(ObjCTypes.ObjectPtrTy);
7966 values.add(GetClassName(PD->getObjCRuntimeNameAsString()));
7967 values.add(EmitProtocolList("_OBJC_$_PROTOCOL_REFS_
" +
7968 PD->getObjCRuntimeNameAsString(),
7969 PD->protocol_begin(), PD->protocol_end()));
7970 values.add(methodLists.emitMethodList(
7971 this, PD, ProtocolMethodLists::RequiredInstanceMethods));
7972 values.add(methodLists.emitMethodList(
7973 this, PD, ProtocolMethodLists::RequiredClassMethods));
7974 values.add(methodLists.emitMethodList(
7975 this, PD, ProtocolMethodLists::OptionalInstanceMethods));
7976 values.add(methodLists.emitMethodList(
7977 this, PD, ProtocolMethodLists::OptionalClassMethods));
7979 EmitPropertyList("_OBJC_$_PROP_LIST_
" + PD->getObjCRuntimeNameAsString(),
7980 nullptr, PD, ObjCTypes, false));
7982 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
7983 values.addInt(ObjCTypes.IntTy, Size);
7984 values.addInt(ObjCTypes.IntTy, 0);
7985 values.add(EmitProtocolMethodTypes(
7986 "_OBJC_$_PROTOCOL_METHOD_TYPES_
" + PD->getObjCRuntimeNameAsString(),
7987 methodLists.emitExtendedTypesArray(this), ObjCTypes));
7989 // const char *demangledName;
7990 values.addNullPointer(ObjCTypes.Int8PtrTy);
7992 values.add(EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_
" +
7993 PD->getObjCRuntimeNameAsString(),
7994 nullptr, PD, ObjCTypes, true));
7997 // Already created, fix the linkage and update the initializer.
7998 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
7999 values.finishAndSetAsInitializer(Entry);
8001 llvm::SmallString<64> symbolName;
8002 llvm::raw_svector_ostream(symbolName)
8003 << "_OBJC_PROTOCOL_$_
" << PD->getObjCRuntimeNameAsString();
8005 Entry = values.finishAndCreateGlobal(symbolName, CGM.getPointerAlign(),
8007 llvm::GlobalValue::WeakAnyLinkage);
8008 if (!CGM.getTriple().isOSBinFormatMachO())
8009 Entry->setComdat(CGM.getModule().getOrInsertComdat(symbolName));
8011 Protocols[PD->getIdentifier()] = Entry;
8013 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
8014 CGM.addUsedGlobal(Entry);
8016 // Use this protocol meta-data to build protocol list table in section
8017 // __DATA, __objc_protolist
8018 llvm::SmallString<64> ProtocolRef;
8019 llvm::raw_svector_ostream(ProtocolRef)
8020 << "_OBJC_LABEL_PROTOCOL_$_
" << PD->getObjCRuntimeNameAsString();
8022 llvm::GlobalVariable *PTGV = new llvm::GlobalVariable(
8023 CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy, false,
8024 llvm::GlobalValue::WeakAnyLinkage, Entry, ProtocolRef);
8025 if (!CGM.getTriple().isOSBinFormatMachO())
8026 PTGV->setComdat(CGM.getModule().getOrInsertComdat(ProtocolRef));
8028 CGM.getDataLayout().getABITypeAlign(ObjCTypes.ProtocolnfABIPtrTy));
8030 GetSectionName("__objc_protolist
", "coalesced,no_dead_strip
"));
8031 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
8032 CGM.addUsedGlobal(PTGV);
8044llvm::Constant *CGObjCNonFragileABIMac::EmitProtocolList(
8045 Twine Name, ObjCProtocolDecl::protocol_iterator begin,
8046 ObjCProtocolDecl::protocol_iterator end) {
8047 // Just return null for empty protocol lists
8048 auto Protocols = GetRuntimeProtocolList(begin, end);
8049 if (Protocols.empty())
8050 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
8052 SmallVector<llvm::Constant *, 16> ProtocolRefs;
8053 ProtocolRefs.reserve(Protocols.size());
8055 for (const auto *PD : Protocols)
8056 ProtocolRefs.push_back(GetProtocolRef(PD));
8058 // If all of the protocols in the protocol list are objc_non_runtime_protocol
8060 if (ProtocolRefs.size() == 0)
8061 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
8063 // FIXME: We shouldn't need to do this lookup here, should we?
8064 SmallString<256> TmpName;
8065 Name.toVector(TmpName);
8066 llvm::GlobalVariable *GV =
8067 CGM.getModule().getGlobalVariable(TmpName.str(), true);
8071 ConstantInitBuilder builder(CGM);
8072 auto values = builder.beginStruct();
8073 auto countSlot = values.addPlaceholder();
8075 // A null-terminated array of protocols.
8076 auto array = values.beginArray(ObjCTypes.ProtocolnfABIPtrTy);
8077 for (auto const &proto : ProtocolRefs)
8079 auto count = array.size();
8080 array.addNullPointer(ObjCTypes.ProtocolnfABIPtrTy);
8082 array.finishAndAddTo(values);
8083 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
8085 GV = finishAndCreateGlobal(values, Name, CGM);
8086 CGM.addCompilerUsedGlobal(GV);
8096LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
8097 CodeGen::CodeGenFunction &CGF, QualType ObjectTy, llvm::Value *BaseValue,
8098 const ObjCIvarDecl *Ivar, unsigned CVRQualifiers) {
8099 ObjCInterfaceDecl *ID = ObjectTy->castAs<ObjCObjectType>()->getInterface();
8100 llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
8101 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
8106CGObjCNonFragileABIMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
8107 const ObjCInterfaceDecl *Interface,
8108 const ObjCIvarDecl *Ivar) {
8109 llvm::Value *IvarOffsetValue;
8110 if (isClassLayoutKnownStatically(Interface)) {
8111 IvarOffsetValue = llvm::ConstantInt::get(
8112 ObjCTypes.IvarOffsetVarTy,
8113 ComputeIvarBaseOffset(CGM, Interface->getImplementation(), Ivar));
8115 llvm::GlobalVariable *GV = ObjCIvarOffsetVariable(Interface, Ivar);
8116 IvarOffsetValue = CGF.Builder.CreateAlignedLoad(GV->getValueType(), GV,
8117 CGF.getSizeAlign(), "ivar
");
8118 if (IsIvarOffsetKnownIdempotent(CGF, Ivar))
8119 cast<llvm::LoadInst>(IvarOffsetValue)
8120 ->setMetadata(llvm::LLVMContext::MD_invariant_load,
8121 llvm::MDNode::get(VMContext, {}));
8124 // This could be 32bit int or 64bit integer depending on the architecture.
8125 // Cast it to 64bit integer value, if it is a 32bit integer ivar offset value
8126 // as this is what caller always expects.
8127 if (ObjCTypes.IvarOffsetVarTy == ObjCTypes.IntTy)
8128 IvarOffsetValue = CGF.Builder.CreateIntCast(
8129 IvarOffsetValue, ObjCTypes.LongTy, true, "ivar.conv
");
8130 return IvarOffsetValue;
8133static void appendSelectorForMessageRefTable(std::string &buffer,
8134 Selector selector) {
8135 if (selector.isUnarySelector()) {
8136 buffer += selector.getNameForSlot(0);
8140 for (unsigned i = 0, e = selector.getNumArgs(); i != e; ++i) {
8141 buffer += selector.getNameForSlot(i);
8156RValue CGObjCNonFragileABIMac::EmitVTableMessageSend(
8157 CodeGenFunction &CGF, ReturnValueSlot returnSlot, QualType resultType,
8158 Selector selector, llvm::Value *arg0, QualType arg0Type, bool isSuper,
8159 const CallArgList &formalArgs, const ObjCMethodDecl *method) {
8160 // Compute the actual arguments.
8163 // First argument: the receiver / super-call structure.
8165 arg0 = CGF.Builder.CreateBitCast(arg0, ObjCTypes.ObjectPtrTy);
8166 args.add(RValue::get(arg0), arg0Type);
8168 // Second argument: a pointer to the message ref structure. Leave
8169 // the actual argument value blank for now.
8170 args.add(RValue::get(nullptr), ObjCTypes.MessageRefCPtrTy);
8172 llvm::append_range(args, formalArgs);
8174 MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);
8176 NullReturnState nullReturn;
8178 // Find the function to call and the mangled name for the message
8179 // ref structure. Using a different mangled name wouldn't actually
8180 // be a problem; it would just be a waste.
8182 // The runtime currently never uses vtable dispatch for anything
8183 // except normal, non-super message-sends.
8184 // FIXME: don't use this for that.
8185 llvm::FunctionCallee fn = nullptr;
8186 std::string messageRefName("_
");
8187 if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
8189 fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
8190 messageRefName += "objc_msgSendSuper2_stret_fixup
";
8192 nullReturn.init(CGF, arg0);
8193 fn = ObjCTypes.getMessageSendStretFixupFn();
8194 messageRefName += "objc_msgSend_stret_fixup
";
8196 } else if (!isSuper && CGM.ReturnTypeUsesFPRet(resultType)) {
8197 fn = ObjCTypes.getMessageSendFpretFixupFn();
8198 messageRefName += "objc_msgSend_fpret_fixup
";
8201 fn = ObjCTypes.getMessageSendSuper2FixupFn();
8202 messageRefName += "objc_msgSendSuper2_fixup
";
8204 fn = ObjCTypes.getMessageSendFixupFn();
8205 messageRefName += "objc_msgSend_fixup
";
8208 assert(fn && "CGObjCNonFragileABIMac::EmitMessageSend
");
8209 messageRefName += '_';
8211 // Append the selector name, except use underscores anywhere we
8212 // would have used colons.
8213 appendSelectorForMessageRefTable(messageRefName, selector);
8215 llvm::GlobalVariable *messageRef =
8216 CGM.getModule().getGlobalVariable(messageRefName);
8218 // Build the message ref structure.
8219 ConstantInitBuilder builder(CGM);
8220 auto values = builder.beginStruct();
8221 values.add(cast<llvm::Constant>(fn.getCallee()));
8222 values.add(GetMethodVarName(selector));
8223 messageRef = values.finishAndCreateGlobal(
8224 messageRefName, CharUnits::fromQuantity(16),
8225 /*constant*/ false, llvm::GlobalValue::WeakAnyLinkage);
8226 messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility);
8227 messageRef->setSection(GetSectionName("__objc_msgrefs
", "coalesced
"));
8230 bool requiresnullCheck = false;
8231 if (CGM.getLangOpts().ObjCAutoRefCount && method)
8232 for (const auto *ParamDecl : method->parameters()) {
8233 if (ParamDecl->isDestroyedInCallee()) {
8234 if (!nullReturn.NullBB)
8235 nullReturn.init(CGF, arg0);
8236 requiresnullCheck = true;
8242 Address(CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy),
8243 ObjCTypes.MessageRefTy, CGF.getPointerAlign());
8245 // Update the message ref argument.
8246 args[1].setRValue(RValue::get(mref, CGF));
8248 // Load the function to call from the message ref table.
8249 Address calleeAddr = CGF.Builder.CreateStructGEP(mref, 0);
8250 llvm::Value *calleePtr = CGF.Builder.CreateLoad(calleeAddr, "msgSend_fn
");
8252 calleePtr = CGF.Builder.CreateBitCast(calleePtr, MSI.MessengerType);
8253 CGCallee callee(CGCalleeInfo(), calleePtr);
8255 RValue result = CGF.EmitCall(MSI.CallInfo, callee, returnSlot, args);
8256 return nullReturn.complete(CGF, returnSlot, result, resultType, formalArgs,
8257 requiresnullCheck ? method : nullptr);
8261CodeGen::RValue CGObjCNonFragileABIMac::GenerateMessageSend(
8262 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
8263 Selector Sel, llvm::Value *Receiver, const CallArgList &CallArgs,
8264 const ObjCInterfaceDecl *Class, const ObjCMethodDecl *Method) {
8265 return isVTableDispatchedSelector(Sel)
8266 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel, Receiver,
8267 CGF.getContext().getObjCIdType(), false,
8269 : EmitMessageSend(CGF, Return, ResultType, Sel, Receiver,
8270 CGF.getContext().getObjCIdType(), false,
8271 CallArgs, Method, Class, ObjCTypes);
8275CGObjCNonFragileABIMac::GetClassGlobal(const ObjCInterfaceDecl *ID,
8277 ForDefinition_t isForDefinition) {
8279 (metaclass ? getMetaclassSymbolPrefix() : getClassSymbolPrefix());
8280 return GetClassGlobal((prefix + ID->getObjCRuntimeNameAsString()).str(),
8281 isForDefinition, ID->isWeakImported(),
8283 CGM.getTriple().isOSBinFormatCOFF() &&
8284 ID->hasAttr<DLLImportAttr>());
8288CGObjCNonFragileABIMac::GetClassGlobal(StringRef Name,
8289 ForDefinition_t IsForDefinition,
8290 bool Weak, bool DLLImport) {
8291 llvm::GlobalValue::LinkageTypes L =
8292 Weak ? llvm::GlobalValue::ExternalWeakLinkage
8293 : llvm::GlobalValue::ExternalLinkage;
8295 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
8296 if (!GV || GV->getValueType() != ObjCTypes.ClassnfABITy) {
8297 auto *NewGV = new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, L,
8301 NewGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
8304 GV->replaceAllUsesWith(NewGV);
8305 GV->eraseFromParent();
8308 CGM.getModule().insertGlobalVariable(GV);
8311 assert(GV->getLinkage() == L);
8316CGObjCNonFragileABIMac::GetClassGlobalForClassRef(const ObjCInterfaceDecl *ID) {
8317 llvm::Constant *ClassGV =
8318 GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition);
8320 if (!ID->hasAttr<ObjCClassStubAttr>())
8323 ClassGV = llvm::ConstantExpr::getPointerCast(ClassGV, ObjCTypes.Int8PtrTy);
8325 // Stub classes are pointer-aligned. Classrefs pointing at stub classes
8326 // must set the least significant bit set to 1.
8327 auto *Idx = llvm::ConstantInt::get(CGM.Int32Ty, 1);
8328 return llvm::ConstantExpr::getPtrAdd(ClassGV, Idx);
8332CGObjCNonFragileABIMac::EmitLoadOfClassRef(CodeGenFunction &CGF,
8333 const ObjCInterfaceDecl *ID,
8334 llvm::GlobalVariable *Entry) {
8335 if (ID && ID->hasAttr<ObjCClassStubAttr>()) {
8336 // Classrefs pointing at Objective-C stub classes must be loaded by calling
8337 // a special runtime function.
8338 return CGF.EmitRuntimeCall(ObjCTypes.getLoadClassrefFn(), Entry,
8339 "load_classref_result
");
8342 CharUnits Align = CGF.getPointerAlign();
8343 return CGF.Builder.CreateAlignedLoad(Entry->getValueType(), Entry, Align);
8346llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(
8347 CodeGenFunction &CGF, IdentifierInfo *II, const ObjCInterfaceDecl *ID) {
8348 llvm::GlobalVariable *&Entry = ClassReferences[II];
8351 llvm::Constant *ClassGV;
8353 ClassGV = GetClassGlobalForClassRef(ID);
8355 ClassGV = GetClassGlobal((getClassSymbolPrefix() + II->getName()).str(),
8357 assert(ClassGV->getType() == ObjCTypes.ClassnfABIPtrTy &&
8358 "classref was emitted with the wrong
type?
");
8361 std::string SectionName =
8362 GetSectionName("__objc_classrefs
", "regular,no_dead_strip
");
8363 Entry = new llvm::GlobalVariable(
8364 CGM.getModule(), ClassGV->getType(), false,
8365 getLinkageTypeForObjCMetadata(CGM, SectionName), ClassGV,
8366 "OBJC_CLASSLIST_REFERENCES_$_
");
8367 Entry->setAlignment(CGF.getPointerAlign().getAsAlign());
8368 if (!ID || !ID->hasAttr<ObjCClassStubAttr>())
8369 Entry->setSection(SectionName);
8371 CGM.addCompilerUsedGlobal(Entry);
8374 return EmitLoadOfClassRef(CGF, ID, Entry);
8377llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CodeGenFunction &CGF,
8378 const ObjCInterfaceDecl *ID) {
8379 // If the class has the objc_runtime_visible attribute, we need to
8380 // use the Objective-C runtime to get the class.
8381 if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
8382 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
8384 return EmitClassRefFromId(CGF, ID->getIdentifier(), ID);
8388CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
8389 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool
");
8390 return EmitClassRefFromId(CGF, II, nullptr);
8394CGObjCNonFragileABIMac::EmitSuperClassRef(CodeGenFunction &CGF,
8395 const ObjCInterfaceDecl *ID) {
8396 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
8399 llvm::Constant *ClassGV = GetClassGlobalForClassRef(ID);
8400 std::string SectionName =
8401 GetSectionName("__objc_superrefs
", "regular,no_dead_strip
");
8402 Entry = new llvm::GlobalVariable(CGM.getModule(), ClassGV->getType(), false,
8403 llvm::GlobalValue::PrivateLinkage, ClassGV,
8404 "OBJC_CLASSLIST_SUP_REFS_$_
");
8405 Entry->setAlignment(CGF.getPointerAlign().getAsAlign());
8406 Entry->setSection(SectionName);
8407 CGM.addCompilerUsedGlobal(Entry);
8410 return EmitLoadOfClassRef(CGF, ID, Entry);
8416llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(
8417 CodeGenFunction &CGF, const ObjCInterfaceDecl *ID, bool Weak) {
8418 CharUnits Align = CGF.getPointerAlign();
8419 llvm::GlobalVariable *&Entry = MetaClassReferences[ID->getIdentifier()];
8421 auto MetaClassGV = GetClassGlobal(ID, /*metaclass*/ true, NotForDefinition);
8422 std::string SectionName =
8423 GetSectionName("__objc_superrefs
", "regular,no_dead_strip
");
8424 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
8425 false, llvm::GlobalValue::PrivateLinkage,
8426 MetaClassGV, "OBJC_CLASSLIST_SUP_REFS_$_
");
8427 Entry->setAlignment(Align.getAsAlign());
8428 Entry->setSection(SectionName);
8429 CGM.addCompilerUsedGlobal(Entry);
8432 return CGF.Builder.CreateAlignedLoad(ObjCTypes.ClassnfABIPtrTy, Entry, Align);
8437llvm::Value *CGObjCNonFragileABIMac::GetClass(CodeGenFunction &CGF,
8438 const ObjCInterfaceDecl *ID) {
8439 if (ID->isWeakImported()) {
8440 auto ClassGV = GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition);
8442 assert(!isa<llvm::GlobalVariable>(ClassGV) ||
8443 cast<llvm::GlobalVariable>(ClassGV)->hasExternalWeakLinkage());
8446 return EmitClassRef(CGF, ID);
8452CodeGen::RValue CGObjCNonFragileABIMac::GenerateMessageSendSuper(
8453 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
8454 Selector Sel, const ObjCInterfaceDecl *Class, bool isCategoryImpl,
8455 llvm::Value *Receiver, bool IsClassMessage,
8456 const CodeGen::CallArgList &CallArgs, const ObjCMethodDecl *Method) {
8458 // Create and init a super structure; this is a (receiver, class)
8459 // pair we will pass to objc_msgSendSuper.
8460 RawAddress ObjCSuper = CGF.CreateTempAlloca(
8461 ObjCTypes.SuperTy, CGF.getPointerAlign(), "objc_super
");
8463 llvm::Value *ReceiverAsObject =
8464 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
8465 CGF.Builder.CreateStore(ReceiverAsObject,
8466 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
8468 // If this is a class message the metaclass is passed as the target.
8469 llvm::Value *Target;
8471 Target = EmitMetaClassRef(CGF, Class, Class->isWeakImported());
8473 Target = EmitSuperClassRef(CGF, Class);
8475 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
8477 llvm::Type *ClassTy =
8478 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
8479 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
8480 CGF.Builder.CreateStore(Target, CGF.Builder.CreateStructGEP(ObjCSuper, 1));
8482 return (isVTableDispatchedSelector(Sel))
8483 ? EmitVTableMessageSend(
8484 CGF, Return, ResultType, Sel, ObjCSuper.getPointer(),
8485 ObjCTypes.SuperPtrCTy, true, CallArgs, Method)
8486 : EmitMessageSend(CGF, Return, ResultType, Sel,
8487 ObjCSuper.getPointer(), ObjCTypes.SuperPtrCTy,
8488 true, CallArgs, Method, Class, ObjCTypes);
8491llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CodeGenFunction &CGF,
8493 Address Addr = EmitSelectorAddr(Sel);
8495 llvm::LoadInst *LI = CGF.Builder.CreateLoad(Addr);
8496 LI->setMetadata(llvm::LLVMContext::MD_invariant_load,
8497 llvm::MDNode::get(VMContext, {}));
8501ConstantAddress CGObjCNonFragileABIMac::EmitSelectorAddr(Selector Sel) {
8502 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
8503 CharUnits Align = CGM.getPointerAlign();
8505 std::string SectionName =
8506 GetSectionName("__objc_selrefs
", "literal_pointers,no_dead_strip
");
8507 Entry = new llvm::GlobalVariable(
8508 CGM.getModule(), ObjCTypes.SelectorPtrTy, false,
8509 getLinkageTypeForObjCMetadata(CGM, SectionName), GetMethodVarName(Sel),
8510 "OBJC_SELECTOR_REFERENCES_
");
8511 Entry->setExternallyInitialized(true);
8512 Entry->setSection(SectionName);
8513 Entry->setAlignment(Align.getAsAlign());
8514 CGM.addCompilerUsedGlobal(Entry);
8517 return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align);
8523void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
8524 llvm::Value *src, Address dst,
8525 llvm::Value *ivarOffset) {
8526 llvm::Type *SrcTy = src->getType();
8527 if (!isa<llvm::PointerType>(SrcTy)) {
8528 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
8529 assert(Size <= 8 && "does
not support size > 8
");
8530 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
8531 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
8532 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
8534 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
8535 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
8536 ObjCTypes.PtrObjectPtrTy);
8537 llvm::Value *args[] = {src, dstVal, ivarOffset};
8538 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
8544void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
8545 CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dst) {
8546 llvm::Type *SrcTy = src->getType();
8547 if (!isa<llvm::PointerType>(SrcTy)) {
8548 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
8549 assert(Size <= 8 && "does
not support size > 8
");
8550 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
8551 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
8552 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
8554 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
8555 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
8556 ObjCTypes.PtrObjectPtrTy);
8557 llvm::Value *args[] = {src, dstVal};
8558 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), args,
8562void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
8563 CodeGen::CodeGenFunction &CGF, Address DestPtr, Address SrcPtr,
8564 llvm::Value *Size) {
8565 llvm::Value *args[] = {DestPtr.emitRawPointer(CGF),
8566 SrcPtr.emitRawPointer(CGF), Size};
8567 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
8574CGObjCNonFragileABIMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
8575 Address AddrWeakObj) {
8576 llvm::Type *DestTy = AddrWeakObj.getElementType();
8577 llvm::Value *AddrWeakObjVal = CGF.Builder.CreateBitCast(
8578 AddrWeakObj.emitRawPointer(CGF), ObjCTypes.PtrObjectPtrTy);
8579 llvm::Value *read_weak = CGF.EmitNounwindRuntimeCall(
8580 ObjCTypes.getGcReadWeakFn(), AddrWeakObjVal, "weakread
");
8581 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
8588void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
8589 llvm::Value *src, Address dst) {
8590 llvm::Type *SrcTy = src->getType();
8591 if (!isa<llvm::PointerType>(SrcTy)) {
8592 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
8593 assert(Size <= 8 && "does
not support size > 8
");
8594 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
8595 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
8596 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
8598 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
8599 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
8600 ObjCTypes.PtrObjectPtrTy);
8601 llvm::Value *args[] = {src, dstVal};
8602 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), args,
8609void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
8610 llvm::Value *src, Address dst,
8612 llvm::Type *SrcTy = src->getType();
8613 if (!isa<llvm::PointerType>(SrcTy)) {
8614 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
8615 assert(Size <= 8 && "does
not support size > 8
");
8616 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
8617 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
8618 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
8620 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
8621 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
8622 ObjCTypes.PtrObjectPtrTy);
8623 llvm::Value *args[] = {src, dstVal};
8625 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), args,
8628 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(), args,
8629 "threadlocalassign
");
8632void CGObjCNonFragileABIMac::EmitSynchronizedStmt(
8633 CodeGen::CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S) {
8634 EmitAtSynchronizedStmt(CGF, S, ObjCTypes.getSyncEnterFn(),
8635 ObjCTypes.getSyncExitFn());
8638llvm::Constant *CGObjCNonFragileABIMac::GetEHType(QualType T) {
8639 // There's a particular fixed type info for 'id'.
8640 if (T->isObjCIdType() || T->isObjCQualifiedIdType()) {
8641 auto *IDEHType = CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id
");
8643 IDEHType = new llvm::GlobalVariable(
8644 CGM.getModule(), ObjCTypes.EHTypeTy, false,
8645 llvm::GlobalValue::ExternalLinkage, nullptr, "OBJC_EHTYPE_id
");
8646 if (CGM.getTriple().isOSBinFormatCOFF())
8647 IDEHType->setDLLStorageClass(getStorage(CGM, "OBJC_EHTYPE_id
"));
8652 // All other types should be Objective-C interface pointer types.
8653 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
8656 const ObjCInterfaceType *IT = PT->getInterfaceType();
8657 assert(IT && "Invalid
@catch type.
");
8659 return GetInterfaceEHType(IT->getDecl(), NotForDefinition);
8662void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
8663 const ObjCAtTryStmt &S) {
8664 EmitTryCatchStmt(CGF, S, ObjCTypes.getObjCBeginCatchFn(),
8665 ObjCTypes.getObjCEndCatchFn(),
8666 ObjCTypes.getExceptionRethrowFn());
8670void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
8671 const ObjCAtThrowStmt &S,
8672 bool ClearInsertionPoint) {
8673 if (const Expr *ThrowExpr = S.getThrowExpr()) {
8674 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
8675 Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
8676 llvm::CallBase *Call =
8677 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception);
8678 Call->setDoesNotReturn();
8680 llvm::CallBase *Call =
8681 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionRethrowFn());
8682 Call->setDoesNotReturn();
8685 CGF.Builder.CreateUnreachable();
8686 if (ClearInsertionPoint)
8687 CGF.Builder.ClearInsertionPoint();
8691CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
8692 ForDefinition_t IsForDefinition) {
8693 llvm::GlobalVariable *&Entry = EHTypeReferences[ID->getIdentifier()];
8694 StringRef ClassName = ID->getObjCRuntimeNameAsString();
8696 // If we don't need a definition, return the entry if found or check
8697 // if we use an external reference.
8698 if (!IsForDefinition) {
8702 // If this type (or a super class) has the __objc_exception__
8703 // attribute, emit an external reference.
8704 if (hasObjCExceptionAttribute(CGM.getContext(), ID)) {
8705 std::string EHTypeName = ("OBJC_EHTYPE_$_
" + ClassName).str();
8706 Entry = new llvm::GlobalVariable(
8707 CGM.getModule(), ObjCTypes.EHTypeTy, false,
8708 llvm::GlobalValue::ExternalLinkage, nullptr, EHTypeName);
8709 CGM.setGVProperties(Entry, ID);
8714 // Otherwise we need to either make a new entry or fill in the initializer.
8715 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition
");
8717 std::string VTableName = "objc_ehtype_vtable
";
8718 auto *VTableGV = CGM.getModule().getGlobalVariable(VTableName);
8720 VTableGV = new llvm::GlobalVariable(
8721 CGM.getModule(), ObjCTypes.Int8PtrTy, false,
8722 llvm::GlobalValue::ExternalLinkage, nullptr, VTableName);
8723 if (CGM.getTriple().isOSBinFormatCOFF())
8724 VTableGV->setDLLStorageClass(getStorage(CGM, VTableName));
8727 llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2);
8728 llvm::Constant *VTablePtr = llvm::ConstantExpr::getInBoundsGetElementPtr(
8729 VTableGV->getValueType(), VTableGV, VTableIdx);
8731 ConstantInitBuilder builder(CGM);
8732 auto values = builder.beginStruct(ObjCTypes.EHTypeTy);
8733 const PointerAuthSchema &TypeInfoSchema =
8734 CGM.getCodeGenOpts().PointerAuth.CXXTypeInfoVTablePointer;
8735 values.addSignedPointer(VTablePtr, TypeInfoSchema, GlobalDecl(), QualType());
8737 values.add(GetClassName(ClassName));
8738 values.add(GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition));
8740 llvm::GlobalValue::LinkageTypes L = IsForDefinition
8741 ? llvm::GlobalValue::ExternalLinkage
8742 : llvm::GlobalValue::WeakAnyLinkage;
8744 values.finishAndSetAsInitializer(Entry);
8745 Entry->setAlignment(CGM.getPointerAlign().getAsAlign());
8747 Entry = values.finishAndCreateGlobal("OBJC_EHTYPE_$_
" + ClassName,
8748 CGM.getPointerAlign(),
8749 /*constant*/ false, L);
8750 if (hasObjCExceptionAttribute(CGM.getContext(), ID))
8751 CGM.setGVProperties(Entry, ID);
8753 assert(Entry->getLinkage() == L);
8755 if (!CGM.getTriple().isOSBinFormatCOFF())
8756 if (ID->getVisibility() == HiddenVisibility)
8757 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
8759 if (IsForDefinition)
8760 if (CGM.getTriple().isOSBinFormatMachO())
8761 Entry->setSection("__DATA,__objc_const
");
8768CodeGen::CGObjCRuntime *
8769CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
8770 switch (CGM.getLangOpts().ObjCRuntime.getKind()) {
8771 case ObjCRuntime::FragileMacOSX:
8772 return new CGObjCMac(CGM);
8774 case ObjCRuntime::MacOSX:
8775 case ObjCRuntime::iOS:
8776 case ObjCRuntime::WatchOS:
8777 return new CGObjCNonFragileABIMac(CGM);
8779 case ObjCRuntime::GNUstep:
8780 case ObjCRuntime::GCC:
8781 case ObjCRuntime::ObjFW:
8782 llvm_unreachable("these runtimes are
not Mac runtimes
");
8784 llvm_unreachable("bad runtime
");
8787// Public wrapper function for external compilers (e.g., Swift) to access
8788// the Mac runtime's GetDirectMethodCallee functionality.
8789llvm::Function *clang::CodeGen::getObjCDirectMethodCallee(
8790 CodeGenModule &CGM, const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD,
8791 bool ReceiverCanBeNull, bool ClassObjectCanBeUnrealized) {
8792 // This function should only be called when targeting Darwin platforms,
8793 // which always use the Mac runtime.
8794 assert(CGM.getLangOpts().ObjCRuntime.isNeXTFamily() &&
8796 CGObjCCommonMac *MacRuntime =
8797 static_cast<CGObjCCommonMac *>(&CGM.getObjCRuntime());
8798 return MacRuntime->GetDirectMethodCallee(OMD, CD, ReceiverCanBeNull,
8799 ClassObjectCanBeUnrealized);
Defines the clang::ASTContext interface.
@ FragileABI_Class_Meta
Is a meta-class.
@ FragileABI_Class_Hidden
Has hidden visibility.
@ FragileABI_Class_Factory
Apparently: is not a meta-class.
@ FragileABI_Class_HasCXXStructors
Has a non-trivial constructor or destructor.
@ FragileABI_Class_HasMRCWeakIvars
Class implementation was compiled under MRC and has MRC weak ivars.
@ FragileABI_Class_CompiledByARC
Class implementation was compiled under ARC.
static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT, bool pointee=false)
static bool hasWeakMember(QualType type)
static std::string getBlockLayoutInfoString(const SmallVectorImpl< CGObjCCommonMac::RUN_SKIP > &RunSkipBlockVars, bool HasCopyDisposeHelpers)
static llvm::StringMapEntry< llvm::GlobalVariable * > & GetConstantStringEntry(llvm::StringMap< llvm::GlobalVariable * > &Map, const StringLiteral *Literal, unsigned &StringLength)
static llvm::GlobalValue::LinkageTypes getLinkageTypeForObjCMetadata(CodeGenModule &CGM, StringRef Section)
static void addIfPresent(llvm::DenseSet< llvm::Value * > &S, Address V)
@ kCFTaggedObjectID_Integer
static void PushProtocolProperties(llvm::SmallPtrSet< const IdentifierInfo *, 16 > &PropertySet, SmallVectorImpl< const ObjCPropertyDecl * > &Properties, const ObjCProtocolDecl *Proto, bool IsClassProperty)
static llvm::GlobalVariable * finishAndCreateGlobal(ConstantInitBuilder::StructBuilder &Builder, const llvm::Twine &Name, CodeGenModule &CGM)
A helper function to create an internal or private global variable.
static bool hasMRCWeakIvars(CodeGenModule &CGM, const ObjCImplementationDecl *ID)
For compatibility, we only want to set the "HasMRCWeakIvars" flag (and actually fill in a layout stri...
@ NonFragileABI_Class_HasCXXDestructorOnly
Class has non-trivial destructors, but zero-initialization is okay.
@ NonFragileABI_Class_Hidden
Has hidden visibility.
@ NonFragileABI_Class_HasCXXStructors
Has a non-trivial constructor or destructor.
@ NonFragileABI_Class_Exception
Has the exception attribute.
@ NonFragileABI_Class_HasIvarReleaser
(Obsolete) ARC-specific: this class has a .release_ivars method
@ NonFragileABI_Class_Root
Is a root class.
@ NonFragileABI_Class_Meta
Is a meta-class.
@ NonFragileABI_Class_HasMRCWeakIvars
Class implementation was compiled under MRC and has MRC weak ivars.
@ NonFragileABI_Class_CompiledByARC
Class implementation was compiled under ARC.
static llvm::Constant * getConstantGEP(llvm::LLVMContext &VMContext, llvm::GlobalVariable *C, unsigned idx0, unsigned idx1)
getConstantGEP() - Help routine to construct simple GEPs.
static bool hasObjCExceptionAttribute(ASTContext &Context, const ObjCInterfaceDecl *OID)
hasObjCExceptionAttribute - Return true if this class or any super class has the objc_exception attri...
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
Result
Implement __builtin_bit_cast and related operations.
Defines the clang::LangOptions interface.
llvm::MachO::Target Target
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
Defines the Objective-C statement AST node classes.
__SIZE_TYPE__ size_t
The unsigned integer type of the result of the sizeof operator.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CanQualType getCanonicalParamType(QualType T) const
Return the canonical parameter type corresponding to the specific potentially non-canonical one.
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
QualType getObjCClassType() const
Represents the Objective-C Class type.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const LangOptions & getLangOpts() const
SelectorTable & Selectors
CanQualType getCanonicalSizeType() const
const ASTRecordLayout & getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const
Get or compute information about the layout of the specified Objective-C interface.
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
QualType getObjCIdType() const
Represents the Objective-CC id type.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType getObjCClassRedefinitionType() const
Retrieve the type that Class has been defined to, which may be different from the built-in Class if C...
QualType getObjCIdRedefinitionType() const
Retrieve the type that id has been defined to, which may be different from the built-in id if id has ...
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
CanQualType getNSUIntegerType() const
CharUnits getSize() const
getSize - Get the record size in characters.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
QualType withConst() const
Retrieves a version of this type with const applied.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
PointerAuthOptions PointerAuth
Configuration for pointer-signing.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
llvm::Type * getElementType() const
Return the type of the values stored in this address.
unsigned getIndex() const
CharUnits getOffset() const
const BlockDecl * getBlockDecl() const
llvm::StructType * StructureType
CharUnits BlockHeaderForcedGapOffset
bool NeedsCopyDispose
True if the block has captures that would necessitate custom copy or dispose helper functions if the ...
CharUnits BlockHeaderForcedGapSize
const Capture & getCapture(const VarDecl *var) const
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::Value * CreateIsNull(Address Addr, const Twine &Name="")
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
CGFunctionInfo - Class to encapsulate the information about a function definition.
Implements runtime-specific code generation functions.
static void destroyCalleeDestroyedArguments(CodeGenFunction &CGF, const ObjCMethodDecl *method, const CallArgList &callArgs)
Destroy the callee-destroyed arguments of the given method, if it has any.
void add(RValue rvalue, QualType type)
void addFrom(const CallArgList &other)
Add all the arguments from another CallArgList to this one.
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)
The given basic block lies in the current EH scope, but may be a target of a potentially scope-crossi...
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
llvm::Type * ConvertType(QualType T)
bool CurFuncIsThunk
In C++, whether we are code generating a thunk.
void EmitAutoVarDecl(const VarDecl &D)
EmitAutoVarDecl - Emit an auto variable declaration.
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void FinishObjCDirectPreconditionThunk()
Finish an Objective-C direct method thunk.
llvm::Value * EmitObjCThrowOperand(const Expr *expr)
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
void StartObjCDirectPreconditionThunk(const ObjCMethodDecl *OMD, llvm::Function *Fn, const CGFunctionInfo &FI)
Start an Objective-C direct method thunk.
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
JumpDest ReturnBlock
ReturnBlock - Unified return block.
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
RawAddress getNormalCleanupDestSlot()
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})
EmitStmt - Emit the code for the statement.
bool AutoreleaseResult
In ARC, whether we should autorelease the return value.
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
RawAddress NormalCleanupDest
i32s containing the indexes of the cleanup destinations.
SmallVector< llvm::Value *, 8 > ObjCEHValueStack
ObjCEHValueStack - Stack of Objective-C exception values, used for rethrows.
void EmitVarDecl(const VarDecl &D)
EmitVarDecl - Emit a local variable declaration.
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
llvm::Value * EmitFromMemory(llvm::Value *Value, QualType Ty)
EmitFromMemory - Change a scalar value from its memory representation to its value representation.
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
llvm::LLVMContext & getLLVMContext()
void PopCleanupBlock(bool FallThroughIsBranchThrough=false, bool ForDeactivation=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
This class organizes the cross-function state that is used while generating LLVM code.
llvm::Module & getModule() const
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
void addCompilerUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.compiler.used metadata.
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
bool ReturnTypeUsesFPRet(QualType ResultType)
Return true iff the given type uses 'fpret' when used as a return type.
bool isObjCDirectPreconditionThunkEnabled() const
Check if the precondition thunk optimization is enabled.
bool shouldHavePreconditionThunk(const ObjCMethodDecl *OMD) const
Check if a direct method should use precondition thunks at call sites.
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
const llvm::DataLayout & getDataLayout() const
bool ReturnTypeUsesFP2Ret(QualType ResultType)
Return true iff the given type uses 'fp2ret' when used as a return type.
const llvm::Triple & getTriple() const
bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI)
Return true iff the given type uses an argument slot when 'sret' is used as a return type.
llvm::Constant * CreateRuntimeVariable(llvm::Type *Ty, StringRef Name)
Create a new runtime global variable with the specified type and name.
void ConstructAttributeList(StringRef Name, const CGFunctionInfo &Info, CGCalleeInfo CalleeInfo, llvm::AttributeList &Attrs, unsigned &CallingConv, bool AttrOnCallSite, bool IsThunk)
Get the LLVM attributes and calling convention to use for a particular function type.
ConstantAddress GetAddrOfConstantCFString(const StringLiteral *Literal)
Return a pointer to a constant CFString object for the given string.
ASTContext & getContext() const
bool shouldHavePreconditionInline(const ObjCMethodDecl *OMD) const
Check if a direct method should have inline precondition checks at call sites.
bool ReturnTypeUsesSRet(const CGFunctionInfo &FI)
Return true iff the given type uses 'sret' when used as a return type.
const CodeGenOptions & getCodeGenOpts() const
llvm::LLVMContext & getLLVMContext()
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info, llvm::Function *F, bool IsThunk)
Set the LLVM function attributes (sext, zext, etc).
void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F)
Set the LLVM function attributes which only apply to a function definition.
ConstantAddress GetAddrOfConstantCString(const std::string &Str, StringRef GlobalName=".str")
Returns a pointer to a character array containing the literal and a terminating '\0' character.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
const CGFunctionInfo & arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD)
Objective-C methods are C functions with some implicit parameters.
llvm::Constant * getPointer() const
StructBuilder beginStruct(llvm::StructType *ty=nullptr)
FunctionArgList - Type for representing both the decl and type of parameters to a function.
static RValue get(llvm::Value *V)
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
llvm::Value * getPointer() const
SourceLocation getLocation() const
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
GlobalDecl - represents a global declaration.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
clang::ObjCRuntime ObjCRuntime
std::string ObjCConstantIntegerNumberClass
std::string ObjCConstantDoubleNumberClass
std::string ObjCConstantArrayClass
std::string ObjCConstantStringClass
std::string ObjCConstantDictionaryClass
std::string ObjCConstantFloatNumberClass
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
const Expr * getThrowExpr() const
const ObjCAtFinallyStmt * getFinallyStmt() const
Retrieve the @finally statement, if any.
catch_range catch_stmts()
ObjCContainerDecl - Represents a container for method declarations.
method_range methods() const
prop_range properties() const
const ObjCInterfaceDecl * getClassInterface() const
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Represents an ObjC class declaration.
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for class's metadata.
ObjCInterfaceDecl * getSuperClass() const
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...
ObjCIvarDecl - Represents an ObjC instance variable.
ObjCInterfaceDecl * getContainingInterface()
Return the class interface that this ivar is logically contained in; this is either the interface whe...
ObjCIvarDecl * getNextIvar()
ObjCMethodDecl - Represents an instance or class method declaration.
ImplicitParamDecl * getSelfDecl() const
param_const_iterator param_end() const
param_const_iterator param_begin() const
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
ObjCMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Selector getSelector() const
ImplicitParamDecl * getCmdDecl() const
bool isInstanceMethod() const
QualType getReturnType() const
bool isClassMethod() const
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
bool isObjCIdType() const
True if this is equivalent to the 'id' type, i.e.
Represents an Objective-C protocol declaration.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for protocol's metadata.
ObjCProtocolList::iterator protocol_iterator
protocol_iterator protocol_begin() const
protocol_range protocols() const
protocol_iterator protocol_end() const
bool hasConstantEmptyCollections() const
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
bool hasConstantCFBooleans() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
bool isObjCGCStrong() const
true when Type is objc's strong.
bool isObjCGCWeak() const
true when Type is objc's weak.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
field_range fields() const
RecordDecl * getDefinitionOrSelf() const
Selector getSelector(unsigned NumArgs, const IdentifierInfo **IIV)
Can create any sort of selector.
std::string getAsString() const
Derive the full selector name (e.g.
StringLiteral - This represents a string literal expression, e.g.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
unsigned getCharWidth() const
bool isBlockPointerType() const
CanQualType getCanonicalTypeUnqualified() const
bool isObjCQualifiedIdType() const
bool isObjCIdType() const
bool isObjCObjectPointerType() const
bool isObjCQualifiedClassType() const
bool isObjCClassType() const
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
const T * castAsCanonical() const
Return this type's canonical type cast to the specified type.
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
llvm::Function * getObjCDirectMethodCallee(CodeGenModule &CGM, const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD, bool ReceiverCanBeNull, bool ClassObjectCanBeUnrealized)
Get the appropriate callee for an ObjC direct method.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, BlockDecl > blockDecl
Matches block declarations.
bool LT(InterpState &S, CodePtr OpPC)
@ Address
A pointer to a ValueDecl.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
@ Match
This is not an overload because the signature exactly matches an existing declaration.
bool isa(CodeGen::Address addr)
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
Selector GetUnarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing an unary selector.
Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
@ Type
The name was classified as a type.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
U cast(CodeGen::Address addr)
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ HiddenVisibility
Objects with "hidden" visibility are not seen by the dynamic linker.
CLINKAGE int printf(__constant const char *st,...) __attribute__((format(printf
float __ovld __cnfn length(float)
Return the length of vector p, i.e., sqrt(p.x2 + p.y 2 + ...)
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 uint32_t
A jump destination is an abstract label, branching to which may require a jump out through normal cle...
llvm::BasicBlock * getBlock() const
llvm::IntegerType * Int64Ty
llvm::CallingConv::ID getRuntimeCC() const
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::IntegerType * IntTy
int
llvm::PointerType * Int8PtrTy
CharUnits getPointerAlign() const
llvm::PointerType * DefaultPtrTy
PointerAuthSchema ObjCIsaPointers
The ABI for Objective-C isa pointers.