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);
1979 if (OID->
hasAttr<ObjCExceptionAttr>())
1986static llvm::GlobalValue::LinkageTypes
1988 if (CGM.
getTriple().isOSBinFormatMachO() &&
1989 (Section.empty() || Section.starts_with(
"__DATA")))
1990 return llvm::GlobalValue::InternalLinkage;
1991 return llvm::GlobalValue::PrivateLinkage;
1995static llvm::GlobalVariable *
1998 std::string SectionName;
1999 if (CGM.
getTriple().isOSBinFormatMachO())
2000 SectionName =
"__DATA, __objc_const";
2001 auto *GV = Builder.finishAndCreateGlobal(
2004 GV->setSection(SectionName);
2011 : CGObjCCommonMac(cgm), ObjCTypes(cgm) {
2020 return EmitClassRef(CGF, ID);
2024llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF, Selector Sel) {
2025 return EmitSelector(CGF, Sel);
2027Address CGObjCMac::GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) {
2028 return EmitSelectorAddr(Sel);
2030llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF,
2031 const ObjCMethodDecl *
Method) {
2032 return EmitSelector(CGF,
Method->getSelector());
2035llvm::Constant *CGObjCMac::GetEHType(QualType
T) {
2047 llvm_unreachable(
"asking for catch type for ObjC type in fragile runtime");
2070CGObjCCommonMac::GenerateConstantString(
const StringLiteral *SL) {
2073 : GenerateConstantNSString(SL));
2076ConstantAddress CGObjCCommonMac::GenerateConstantNumber(
const bool Value,
2077 const QualType &Ty) {
2078 return GenerateConstantNSNumber(
Value, Ty);
2082CGObjCCommonMac::GenerateConstantNumber(
const llvm::APSInt &
Value,
2083 const QualType &Ty) {
2084 return GenerateConstantNSNumber(
Value, Ty);
2088CGObjCCommonMac::GenerateConstantNumber(
const llvm::APFloat &
Value,
2089 const QualType &Ty) {
2090 return GenerateConstantNSNumber(
Value, Ty);
2093ConstantAddress CGObjCCommonMac::GenerateConstantArray(
2094 const ArrayRef<llvm::Constant *> &Objects) {
2095 return GenerateConstantNSArray(Objects);
2098ConstantAddress CGObjCCommonMac::GenerateConstantDictionary(
2099 const ObjCDictionaryLiteral *E,
2100 ArrayRef<std::pair<llvm::Constant *, llvm::Constant *>> KeysAndObjects) {
2101 return GenerateConstantNSDictionary(E, KeysAndObjects);
2104static llvm::StringMapEntry<llvm::GlobalVariable *> &
2107 StringRef String = Literal->getString();
2108 StringLength = String.size();
2109 return *Map.insert(std::make_pair(String,
nullptr)).first;
2112llvm::Constant *CGObjCMac::getNSConstantStringClassRef() {
2113 if (llvm::Value *
V = ConstantStringClassRef)
2117 std::string str = StringClass.empty() ?
"_NSConstantStringClassReference"
2118 :
"_" + StringClass +
"ClassReference";
2120 llvm::Type *PTy = llvm::ArrayType::get(CGM.
IntTy, 0);
2122 ConstantStringClassRef = GV;
2126llvm::Constant *CGObjCMac::getNSConstantArrayClassRef() {
2127 llvm_unreachable(
"constant array literals not supported for fragile ABI");
2130llvm::Constant *CGObjCMac::getNSConstantDictionaryClassRef() {
2131 llvm_unreachable(
"constant dictionary literals not supported for fragile "
2135llvm::Constant *CGObjCMac::getNSConstantIntegerNumberClassRef() {
2136 llvm_unreachable(
"constant number literals not supported for fragile ABI");
2139llvm::Constant *CGObjCMac::getNSConstantFloatNumberClassRef() {
2140 llvm_unreachable(
"constant number literals not supported for fragile ABI");
2143llvm::Constant *CGObjCMac::getNSConstantDoubleNumberClassRef() {
2144 llvm_unreachable(
"constant number literals not supported for fragile ABI");
2147llvm::Constant *CGObjCNonFragileABIMac::getNSConstantStringClassRef() {
2148 if (llvm::Value *
V = ConstantStringClassRef)
2152 std::string str = StringClass.empty() ?
"OBJC_CLASS_$_NSConstantString"
2153 :
"OBJC_CLASS_$_" + StringClass;
2155 ConstantStringClassRef = GV;
2159llvm::Constant *CGObjCNonFragileABIMac::getNSConstantArrayClassRef() {
2160 if (llvm::Value *
V = ConstantArrayClassRef)
2164 std::string Str = ArrayClass.empty() ?
"OBJC_CLASS_$_NSConstantArray"
2165 :
"OBJC_CLASS_$_" + ArrayClass;
2168 ConstantArrayClassRef = GV;
2172llvm::Constant *CGObjCNonFragileABIMac::getNSConstantDictionaryClassRef() {
2173 if (llvm::Value *
V = ConstantDictionaryClassRef)
2176 const std::string &DictionaryClass =
2178 std::string Str = DictionaryClass.empty()
2179 ?
"OBJC_CLASS_$_NSConstantDictionary"
2180 :
"OBJC_CLASS_$_" + DictionaryClass;
2183 ConstantDictionaryClassRef = GV;
2187llvm::Constant *CGObjCNonFragileABIMac::getNSConstantIntegerNumberClassRef() {
2188 if (llvm::Value *
V = ConstantIntegerNumberClassRef)
2191 const std::string &NumberClass =
2193 std::string Str = NumberClass.empty() ?
"OBJC_CLASS_$_NSConstantIntegerNumber"
2194 :
"OBJC_CLASS_$_" + NumberClass;
2197 ConstantIntegerNumberClassRef = GV;
2201llvm::Constant *CGObjCNonFragileABIMac::getNSConstantFloatNumberClassRef() {
2202 if (llvm::Value *
V = ConstantFloatNumberClassRef)
2205 const std::string &NumberClass =
2207 std::string Str = NumberClass.empty() ?
"OBJC_CLASS_$_NSConstantFloatNumber"
2208 :
"OBJC_CLASS_$_" + NumberClass;
2211 ConstantFloatNumberClassRef = GV;
2215llvm::Constant *CGObjCNonFragileABIMac::getNSConstantDoubleNumberClassRef() {
2216 if (llvm::Value *
V = ConstantDoubleNumberClassRef)
2219 const std::string &NumberClass =
2221 std::string Str = NumberClass.empty() ?
"OBJC_CLASS_$_NSConstantDoubleNumber"
2222 :
"OBJC_CLASS_$_" + NumberClass;
2225 ConstantDoubleNumberClassRef = GV;
2230CGObjCCommonMac::GenerateConstantNSString(
const StringLiteral *Literal) {
2231 unsigned StringLength = 0;
2232 llvm::StringMapEntry<llvm::GlobalVariable *> &Entry =
2235 if (
auto *
C = Entry.second)
2236 return ConstantAddress(
C,
C->getValueType(),
2240 llvm::Constant *
Class = getNSConstantStringClassRef();
2243 if (!NSConstantStringType) {
2247 NSConstantStringType =
2249 "struct.__builtin_NSString");
2252 ConstantInitBuilder Builder(CGM);
2253 auto Fields = Builder.beginStruct(NSConstantStringType);
2256 Fields.addSignedPointer(
Class,
2258 GlobalDecl(), QualType());
2262 llvm::ConstantDataArray::getString(VMContext, Entry.first());
2264 llvm::GlobalValue::LinkageTypes
Linkage = llvm::GlobalValue::PrivateLinkage;
2265 bool isConstant = !CGM.
getLangOpts().WritableStrings;
2267 auto *GV =
new llvm::GlobalVariable(CGM.
getModule(),
C->getType(), isConstant,
2269 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2272 GV->setAlignment(llvm::Align(1));
2276 Fields.addInt(CGM.
IntTy, StringLength);
2280 GV = Fields.finishAndCreateGlobal(
"_unnamed_nsstring_", Alignment,
2282 llvm::GlobalVariable::PrivateLinkage);
2283 const char *NSStringSection =
"__OBJC,__cstring_object,regular,no_dead_strip";
2284 const char *NSStringNonFragileABISection =
2285 "__DATA,__objc_stringobj,regular,no_dead_strip";
2288 ? NSStringNonFragileABISection
2292 return ConstantAddress(GV, GV->getValueType(), Alignment);
2296ConstantAddress CGObjCCommonMac::GenerateConstantNSNumber(
const bool Value,
2297 const QualType &Ty) {
2298 llvm::GlobalVariable *Val =
2299 Value ? EmitConstantCFBooleanTrue() : EmitConstantCFBooleanFalse();
2300 return ConstantAddress(Val, Val->getValueType(), CGM.
getPointerAlign());
2313CGObjCCommonMac::GenerateConstantNSNumber(
const llvm::APSInt &
Value,
2314 const QualType &Ty) {
2318 llvm::GlobalVariable *&Entry =
2321 return ConstantAddress(Entry, Entry->getValueType(), Alignment);
2325 std::string ObjCEncodingType;
2326 CodeGenFunction(CGM).getContext().getObjCEncodingForType(Ty,
2329 llvm::Constant *
const Class = getNSConstantIntegerNumberClassRef();
2331 if (!NSConstantIntegerNumberType) {
2332 NSConstantIntegerNumberType = llvm::StructType::create(
2338 "struct.__builtin_NSConstantIntegerNumber");
2341 ConstantInitBuilder Builder(CGM);
2342 auto Fields = Builder.beginStruct(NSConstantIntegerNumberType);
2345 Fields.addSignedPointer(
Class,
2347 GlobalDecl(), QualType());
2353 llvm::Constant *IntegerValue =
2354 llvm::ConstantInt::get(CGM.
Int64Ty,
Value.extOrTrunc(64));
2356 Fields.add(IntegerValue);
2359 llvm::GlobalVariable *
const GV = Fields.finishAndCreateGlobal(
2360 "_unnamed_nsconstantintegernumber_", Alignment,
2361 true, llvm::GlobalVariable::PrivateLinkage);
2363 GV->setSection(GetNSConstantIntegerNumberSectionName());
2364 GV->addAttribute(
"objc_arc_inert");
2368 return ConstantAddress(GV, GV->getValueType(), Alignment);
2386CGObjCCommonMac::GenerateConstantNSNumber(
const llvm::APFloat &
Value,
2387 const QualType &Ty) {
2391 llvm::GlobalVariable *&Entry =
2394 return ConstantAddress(Entry, Entry->getValueType(), Alignment);
2398 std::string ObjCEncodingType;
2399 CodeGenFunction(CGM).getContext().getObjCEncodingForType(Ty,
2402 assert((ObjCEncodingType ==
"d" || ObjCEncodingType ==
"f") &&
2403 "Unexpected or unknown ObjCEncodingType used in constant NSNumber");
2405 llvm::GlobalValue::LinkageTypes
Linkage =
2406 llvm::GlobalVariable::PrivateLinkage;
2409 if (ObjCEncodingType ==
"f") {
2410 llvm::Constant *
const Class = getNSConstantFloatNumberClassRef();
2412 if (!NSConstantFloatNumberType) {
2413 NSConstantFloatNumberType = llvm::StructType::create(
2418 "struct.__builtin_NSConstantFloatNumber");
2421 ConstantInitBuilder Builder(CGM);
2422 auto Fields = Builder.beginStruct(NSConstantFloatNumberType);
2425 Fields.addSignedPointer(
Class,
2427 GlobalDecl(), QualType());
2430 llvm::Constant *FV = llvm::ConstantFP::get(CGM.
FloatTy,
Value);
2434 llvm::GlobalVariable *
const GV = Fields.finishAndCreateGlobal(
2435 "_unnamed_nsconstantfloatnumber_", Alignment,
2438 GV->setSection(GetNSConstantFloatNumberSectionName());
2439 GV->addAttribute(
"objc_arc_inert");
2443 return ConstantAddress(GV, GV->getValueType(), Alignment);
2446 llvm::Constant *
const Class = getNSConstantDoubleNumberClassRef();
2447 if (!NSConstantDoubleNumberType) {
2449 NSConstantDoubleNumberType = llvm::StructType::create(
2454 "struct.__builtin_NSConstantDoubleNumber");
2457 ConstantInitBuilder Builder(CGM);
2458 auto Fields = Builder.beginStruct(NSConstantDoubleNumberType);
2461 Fields.addSignedPointer(
Class,
2463 GlobalDecl(), QualType());
2466 llvm::Constant *DV = llvm::ConstantFP::get(CGM.
DoubleTy,
Value);
2470 llvm::GlobalVariable *
const GV = Fields.finishAndCreateGlobal(
2471 "_unnamed_nsconstantdoublenumber_", Alignment,
2474 GV->setSection(GetNSConstantDoubleNumberSectionName());
2475 GV->addAttribute(
"objc_arc_inert");
2479 return ConstantAddress(GV, GV->getValueType(), Alignment);
2484llvm::GlobalVariable *
2485CGObjCCommonMac::EmitNSConstantCollectionLiteralArrayStorage(
2486 const ArrayRef<llvm::Constant *> &Elements) {
2487 llvm::Type *ElementsTy = Elements[0]->getType();
2488 llvm::ArrayType *ArrayTy = llvm::ArrayType::get(ElementsTy, Elements.size());
2490 llvm::Constant *
const ArrayData = llvm::ConstantArray::get(ArrayTy, Elements);
2492 llvm::GlobalVariable *ObjectsGV =
new llvm::GlobalVariable(
2493 CGM.
getModule(), ArrayTy,
true, llvm::GlobalValue::InternalLinkage,
2494 ArrayData,
"_unnamed_array_storage");
2497 ObjectsGV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2498 ObjectsGV->setSection(GetNSConstantCollectionStorageSectionName());
2511ConstantAddress CGObjCCommonMac::GenerateConstantNSArray(
2512 const ArrayRef<llvm::Constant *> &Objects) {
2515 if (Objects.size() == 0) {
2516 llvm::GlobalVariable *GV = EmitEmptyConstantNSArray();
2517 return ConstantAddress(GV, GV->getValueType(), Alignment);
2521 CodeGenTypes &Types = CGM.
getTypes();
2522 llvm::Constant *
const Class = getNSConstantArrayClassRef();
2523 llvm::Type *
const NSUIntegerTy =
2526 if (!NSConstantArrayType) {
2527 NSConstantArrayType = llvm::StructType::create(
2533 "struct.__builtin_NSArray");
2536 ConstantInitBuilder Builder(CGM);
2537 auto Fields = Builder.beginStruct(NSConstantArrayType);
2540 Fields.addSignedPointer(
Class,
2542 GlobalDecl(), QualType());
2545 uint64_t ObjectCount = Objects.size();
2546 llvm::Constant *Count = llvm::ConstantInt::get(NSUIntegerTy, ObjectCount);
2550 llvm::GlobalVariable *ObjectsGV =
2551 EmitNSConstantCollectionLiteralArrayStorage(Objects);
2552 Fields.add(ObjectsGV);
2555 llvm::GlobalVariable *GV = Fields.finishAndCreateGlobal(
2556 "_unnamed_nsarray_", Alignment,
2557 true, llvm::GlobalValue::PrivateLinkage);
2559 GV->setSection(GetNSConstantArraySectionName());
2560 GV->addAttribute(
"objc_arc_inert");
2562 return ConstantAddress(GV, GV->getValueType(), Alignment);
2577ConstantAddress CGObjCCommonMac::GenerateConstantNSDictionary(
2578 const ObjCDictionaryLiteral *E,
2579 ArrayRef<std::pair<llvm::Constant *, llvm::Constant *>> KeysAndObjects) {
2582 if (KeysAndObjects.size() == 0) {
2583 llvm::GlobalVariable *GV = EmitEmptyConstantNSDictionary();
2584 return ConstantAddress(GV, GV->getValueType(), Alignment);
2588 CodeGenTypes &Types = CGM.
getTypes();
2589 llvm::Constant *
const Class = getNSConstantDictionaryClassRef();
2591 llvm::Type *
const NSUIntegerTy =
2594 if (!NSConstantDictionaryType) {
2595 NSConstantDictionaryType = llvm::StructType::create(
2603 "struct.__builtin_NSDictionary");
2606 ConstantInitBuilder Builder(CGM);
2607 auto Fields = Builder.beginStruct(NSConstantDictionaryType);
2610 Fields.addSignedPointer(
Class,
2612 GlobalDecl(), QualType());
2615 auto HashOpts(NSDictionaryBuilder::Options::Sorted);
2616 NSDictionaryBuilder DictBuilder(E, KeysAndObjects, HashOpts);
2619 uint64_t const NumElements = DictBuilder.getNumElements();
2621 llvm::Constant *OptionsConstant = llvm::ConstantInt::get(
2622 NSUIntegerTy,
static_cast<uint64_t>(DictBuilder.getOptions()));
2623 Fields.add(OptionsConstant);
2626 llvm::Constant *Count = llvm::ConstantInt::get(NSUIntegerTy, NumElements);
2630 SmallVector<llvm::Constant *, 16> SortedKeys, SortedObjects;
2631 SortedKeys.reserve(NumElements);
2632 SortedObjects.reserve(NumElements);
2633 for (
auto &[Key, Obj] : DictBuilder.getElements()) {
2634 SortedKeys.push_back(Key);
2635 SortedObjects.push_back(Obj);
2639 llvm::GlobalVariable *KeysGV =
2640 EmitNSConstantCollectionLiteralArrayStorage(SortedKeys);
2644 llvm::GlobalVariable *ObjectsGV =
2645 EmitNSConstantCollectionLiteralArrayStorage(SortedObjects);
2646 Fields.add(ObjectsGV);
2649 llvm::GlobalVariable *GV = Fields.finishAndCreateGlobal(
2650 "_unnamed_nsdictionary_", Alignment,
2651 true, llvm::GlobalValue::PrivateLinkage);
2653 GV->setSection(GetNSConstantDictionarySectionName());
2654 GV->addAttribute(
"objc_arc_inert");
2656 return ConstantAddress(GV, GV->getValueType(), Alignment);
2664CodeGen::RValue CGObjCMac::GenerateMessageSendSuper(
2665 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
2666 Selector Sel,
const ObjCInterfaceDecl *
Class,
bool isCategoryImpl,
2667 llvm::Value *Receiver,
bool IsClassMessage,
2668 const CodeGen::CallArgList &CallArgs,
const ObjCMethodDecl *
Method) {
2673 llvm::Value *ReceiverAsObject =
2674 CGF.
Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
2679 llvm::Type *ClassTyPtr = llvm::PointerType::getUnqual(VMContext);
2681 if (IsClassMessage) {
2682 if (isCategoryImpl) {
2689 Target = EmitClassRef(CGF,
Class->getSuperClass());
2694 llvm::Constant *MetaClassPtr = EmitMetaClassRef(
Class);
2695 llvm::Value *SuperPtr =
2701 }
else if (isCategoryImpl)
2702 Target = EmitClassRef(CGF,
Class->getSuperClass());
2704 llvm::Value *ClassPtr = EmitSuperClassRef(
Class);
2711 llvm::Type *ClassTy =
2715 return EmitMessageSend(CGF, Return, ResultType, Sel, ObjCSuper.
getPointer(),
2716 ObjCTypes.SuperPtrCTy,
true, CallArgs,
Method,
Class,
2721CodeGen::RValue CGObjCMac::GenerateMessageSend(
2722 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
2723 Selector Sel, llvm::Value *Receiver,
const CallArgList &CallArgs,
2724 const ObjCInterfaceDecl *
Class,
const ObjCMethodDecl *
Method) {
2725 return EmitMessageSend(CGF, Return, ResultType, Sel, Receiver,
2730CodeGen::RValue CGObjCCommonMac::EmitMessageSend(
2731 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
2732 Selector Sel, llvm::Value *Arg0, QualType Arg0Ty,
bool IsSuper,
2733 const CallArgList &CallArgs,
const ObjCMethodDecl *
Method,
2734 const ObjCInterfaceDecl *ClassReceiver,
2735 const ObjCCommonTypesHelper &ObjCTypes) {
2736 CodeGenTypes &Types = CGM.
getTypes();
2738 llvm::Value *ReceiverValue =
2739 llvm::PoisonValue::get(Types.
ConvertType(Arg0Ty));
2740 llvm::Value *SelValue = llvm::UndefValue::get(Types.
ConvertType(selTy));
2742 CallArgList ActualArgs;
2744 Arg0 = CGF.
Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy);
2751 MessageSendInfo MSI = getMessageSendInfo(
Method, ResultType, ActualArgs);
2756 "Result type mismatch!");
2758 bool ReceiverCanBeNull =
2759 canMessageReceiverBeNull(CGF,
Method, IsSuper, ClassReceiver, Arg0);
2760 bool ClassObjectCanBeUnrealized =
2762 canClassObjectBeUnrealized(ClassReceiver, CGF);
2764 bool RequiresNullCheck =
false;
2765 bool RequiresReceiverValue =
true;
2766 bool RequiresSelValue =
true;
2768 llvm::FunctionCallee
Fn =
nullptr;
2772 ReceiverCanBeNull, ClassObjectCanBeUnrealized);
2775 RequiresSelValue =
false;
2777 if (ReceiverCanBeNull)
2778 RequiresNullCheck =
true;
2779 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
2780 : ObjCTypes.getSendStretFn(IsSuper);
2782 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
2783 : ObjCTypes.getSendFpretFn(IsSuper);
2785 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)
2786 : ObjCTypes.getSendFp2retFn(IsSuper);
2791 RequiresNullCheck =
true;
2793 StringRef ClassName;
2799 if (CGM.
getCodeGenOpts().ObjCMsgSendClassSelectorStubs && ClassReceiver &&
2801 !ClassReceiver->
hasAttr<ObjCClassStubAttr>() &&
2802 !ClassReceiver->
hasAttr<ObjCRuntimeVisibleAttr>() &&
2806 bool UseClassStub = ClassName.data();
2809 (CGM.
getCodeGenOpts().ObjCMsgSendSelectorStubs || UseClassStub)) {
2810 Fn = GenerateMethodSelectorStub(Sel, ClassName, ObjCTypes);
2812 RequiresReceiverValue = !UseClassStub;
2813 RequiresSelValue =
false;
2815 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
2816 : ObjCTypes.getSendFn(IsSuper);
2822 CGF.
Builder.CreateBitCast(
Fn.getCallee(), MSI.MessengerType));
2827 RequiresNullCheck =
false;
2830 if (!RequiresNullCheck &&
Method &&
Method->hasParamDestroyedInCallee())
2831 RequiresNullCheck =
true;
2838 if (ClassReceiver && ClassObjectCanBeUnrealized) {
2840 Arg0 = GenerateClassRealization(CGF, Arg0, ClassReceiver);
2841 ActualArgs[0] = CallArg(
RValue::get(Arg0), ActualArgs[0].Ty);
2847 RequiresNullCheck |= ReceiverCanBeNull;
2850 NullReturnState nullReturn;
2851 if (RequiresNullCheck) {
2852 nullReturn.init(CGF, Arg0);
2856 if (RequiresReceiverValue)
2857 ActualArgs[0] = CallArg(
RValue::get(Arg0), Arg0Ty);
2860 if (RequiresSelValue) {
2861 SelValue = GetSelector(CGF, Sel);
2862 ActualArgs[1] = CallArg(
RValue::get(SelValue), selTy);
2865 llvm::CallBase *CallSite;
2868 CGF.
EmitCall(MSI.CallInfo, Callee, Return, ActualArgs, &CallSite);
2872 if (
Method &&
Method->hasAttr<NoReturnAttr>() && !ReceiverCanBeNull) {
2873 CallSite->setDoesNotReturn();
2876 return nullReturn.complete(CGF, Return, rvalue, ResultType, CallArgs,
2877 RequiresNullCheck ?
Method :
nullptr);
2881 bool pointee =
false) {
2895 switch (ownership) {
2903 llvm_unreachable(
"autoreleasing ivar?");
2905 llvm_unreachable(
"known nonzero");
2907 llvm_unreachable(
"bad objc ownership");
2927 IvarInfo(CharUnits offset, uint64_t sizeInWords)
2928 : Offset(offset), SizeInWords(sizeInWords) {}
2931 bool operator<(
const IvarInfo &other)
const {
return Offset < other.Offset; }
2935class IvarLayoutBuilder {
2940 CharUnits InstanceBegin;
2943 CharUnits InstanceEnd;
2946 bool ForStrongLayout;
2949 bool IsDisordered =
false;
2951 llvm::SmallVector<IvarInfo, 8> IvarsInfo;
2954 IvarLayoutBuilder(CodeGenModule &CGM, CharUnits instanceBegin,
2955 CharUnits instanceEnd,
bool forStrongLayout)
2956 : CGM(CGM), InstanceBegin(instanceBegin), InstanceEnd(instanceEnd),
2957 ForStrongLayout(forStrongLayout) {}
2959 void visitRecord(
const RecordType *RT, CharUnits offset);
2961 template <
class Iterator,
class GetOffsetFn>
2962 void visitAggregate(Iterator begin, Iterator end, CharUnits aggrOffset,
2963 const GetOffsetFn &getOffset);
2965 void visitField(
const FieldDecl *field, CharUnits offset);
2968 void visitBlock(
const CGBlockInfo &blockInfo);
2971 bool hasBitmapData()
const {
return !IvarsInfo.empty(); }
2973 llvm::Constant *buildBitmap(CGObjCCommonMac &CGObjC,
2974 llvm::SmallVectorImpl<unsigned char> &buffer);
2976 static void dump(ArrayRef<unsigned char> buffer) {
2977 const unsigned char *s = buffer.data();
2978 for (
unsigned i = 0, e = buffer.size(); i < e; i++)
2980 printf(
"0x0%x%s", s[i], s[i] != 0 ?
", " :
"");
2982 printf(
"0x%x%s", s[i], s[i] != 0 ?
", " :
"");
2989CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,
2990 const CGBlockInfo &blockInfo) {
2992 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2993 if (CGM.
getLangOpts().getGC() == LangOptions::NonGC)
2999 builder.visitBlock(blockInfo);
3001 if (!builder.hasBitmapData())
3004 llvm::SmallVector<unsigned char, 32> buffer;
3005 llvm::Constant *
C = builder.buildBitmap(*
this, buffer);
3006 if (CGM.
getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
3007 printf(
"\n block variable layout for block: ");
3008 builder.dump(buffer);
3014void IvarLayoutBuilder::visitBlock(
const CGBlockInfo &blockInfo) {
3024 CharUnits lastFieldOffset;
3027 for (
const auto &CI :
blockDecl->captures()) {
3028 const VarDecl *variable = CI.getVariable();
3031 const CGBlockInfo::Capture &capture = blockInfo.
getCapture(variable);
3037 CharUnits fieldOffset = capture.
getOffset();
3041 if (fieldOffset < lastFieldOffset)
3042 IsDisordered =
true;
3043 lastFieldOffset = fieldOffset;
3047 IvarsInfo.push_back(IvarInfo(fieldOffset, 1));
3051 assert(!
type->isArrayType() &&
"array variable should not be caught");
3052 if (
const RecordType *record =
type->getAsCanonical<RecordType>()) {
3053 visitRecord(record, fieldOffset);
3062 IvarsInfo.push_back(IvarInfo(fieldOffset, 1));
3071CGObjCCommonMac::getBlockCaptureLifetime(QualType FQT,
bool ByrefLayout) {
3087void CGObjCCommonMac::UpdateRunSkipBlockVars(
bool IsByref,
3089 CharUnits FieldOffset,
3090 CharUnits FieldSize) {
3093 RunSkipBlockVars.push_back(
3094 RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset, FieldSize));
3096 RunSkipBlockVars.push_back(
3097 RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset, FieldSize));
3099 RunSkipBlockVars.push_back(
3100 RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset, FieldSize));
3102 RunSkipBlockVars.push_back(
3103 RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset, FieldSize));
3105 RunSkipBlockVars.push_back(
3106 RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES, FieldOffset, FieldSize));
3109void CGObjCCommonMac::BuildRCRecordLayout(
const llvm::StructLayout *RecLayout,
3110 const RecordDecl *RD,
3111 ArrayRef<const FieldDecl *> RecFields,
3112 CharUnits BytePos,
bool &HasUnion,
3114 bool IsUnion = (RD && RD->
isUnion());
3116 const FieldDecl *MaxField =
nullptr;
3117 const FieldDecl *LastFieldBitfieldOrUnnamed =
nullptr;
3121 if (RecFields.empty())
3125 for (
unsigned i = 0, e = RecFields.size(); i != e; ++i) {
3126 const FieldDecl *
Field = RecFields[i];
3130 CharUnits FieldOffset =
3134 if (!
Field->getIdentifier() ||
Field->isBitField()) {
3135 LastFieldBitfieldOrUnnamed =
Field;
3136 LastBitfieldOrUnnamedOffset = FieldOffset;
3140 LastFieldBitfieldOrUnnamed =
nullptr;
3141 QualType FQT =
Field->getType();
3147 BytePos + FieldOffset, HasUnion);
3153 uint64_t ElCount = CArray->getZExtSize();
3154 assert(CArray &&
"only array with known element size is supported");
3155 FQT = CArray->getElementType();
3158 ElCount *= CArray->getZExtSize();
3159 FQT = CArray->getElementType();
3162 int OldIndex = RunSkipBlockVars.size() - 1;
3164 BuildRCBlockVarRecordLayout(RT, BytePos + FieldOffset, HasUnion);
3169 for (
int FirstIndex = RunSkipBlockVars.size() - 1; ElIx < ElCount;
3172 for (
int i = OldIndex + 1; i <= FirstIndex; ++i)
3173 RunSkipBlockVars.push_back(
3174 RUN_SKIP(RunSkipBlockVars[i].opcode,
3175 RunSkipBlockVars[i].block_var_bytepos + Size * ElIx,
3176 RunSkipBlockVars[i].block_var_size));
3183 CharUnits UnionIvarSize = FieldSize;
3184 if (UnionIvarSize > MaxUnionSize) {
3185 MaxUnionSize = UnionIvarSize;
3187 MaxFieldOffset = FieldOffset;
3190 UpdateRunSkipBlockVars(
false, getBlockCaptureLifetime(FQT, ByrefLayout),
3191 BytePos + FieldOffset, FieldSize);
3195 if (LastFieldBitfieldOrUnnamed) {
3196 if (LastFieldBitfieldOrUnnamed->
isBitField()) {
3199 unsigned UnsSize = (BitFieldSize / ByteSizeInBits) +
3200 ((BitFieldSize % ByteSizeInBits) != 0);
3202 Size += LastBitfieldOrUnnamedOffset;
3203 UpdateRunSkipBlockVars(
3205 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
3207 BytePos + LastBitfieldOrUnnamedOffset, Size);
3210 "Expected unnamed");
3213 LastFieldBitfieldOrUnnamed->
getType());
3214 UpdateRunSkipBlockVars(
3216 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
3218 BytePos + LastBitfieldOrUnnamedOffset, FieldSize);
3223 UpdateRunSkipBlockVars(
3224 false, getBlockCaptureLifetime(MaxField->
getType(), ByrefLayout),
3225 BytePos + MaxFieldOffset, MaxUnionSize);
3228void CGObjCCommonMac::BuildRCBlockVarRecordLayout(
const RecordType *RT,
3233 SmallVector<const FieldDecl *, 16> Fields(RD->
fields());
3235 const llvm::StructLayout *RecLayout =
3238 BuildRCRecordLayout(RecLayout, RD, Fields, BytePos, HasUnion, ByrefLayout);
3250uint64_t CGObjCCommonMac::InlineLayoutInstruction(
3251 SmallVectorImpl<unsigned char> &Layout) {
3253 if (Layout.size() <= 3) {
3254 unsigned size = Layout.size();
3255 unsigned strong_word_count = 0, byref_word_count = 0, weak_word_count = 0;
3257 enum BLOCK_LAYOUT_OPCODE opcode;
3261 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3262 if (opcode == BLOCK_LAYOUT_STRONG)
3263 strong_word_count = (inst & 0xF) + 1;
3267 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3268 if (opcode == BLOCK_LAYOUT_BYREF)
3269 byref_word_count = (inst & 0xF) + 1;
3273 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3274 if (opcode == BLOCK_LAYOUT_WEAK)
3275 weak_word_count = (inst & 0xF) + 1;
3282 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3283 if (opcode == BLOCK_LAYOUT_STRONG) {
3284 strong_word_count = (inst & 0xF) + 1;
3286 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3287 if (opcode == BLOCK_LAYOUT_BYREF)
3288 byref_word_count = (inst & 0xF) + 1;
3289 else if (opcode == BLOCK_LAYOUT_WEAK)
3290 weak_word_count = (inst & 0xF) + 1;
3293 }
else if (opcode == BLOCK_LAYOUT_BYREF) {
3294 byref_word_count = (inst & 0xF) + 1;
3296 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3297 if (opcode == BLOCK_LAYOUT_WEAK)
3298 weak_word_count = (inst & 0xF) + 1;
3307 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3308 if (opcode == BLOCK_LAYOUT_STRONG)
3309 strong_word_count = (inst & 0xF) + 1;
3310 else if (opcode == BLOCK_LAYOUT_BYREF)
3311 byref_word_count = (inst & 0xF) + 1;
3312 else if (opcode == BLOCK_LAYOUT_WEAK)
3313 weak_word_count = (inst & 0xF) + 1;
3325 if (strong_word_count == 16 || byref_word_count == 16 ||
3326 weak_word_count == 16)
3329 unsigned count = (strong_word_count != 0) + (byref_word_count != 0) +
3330 (weak_word_count != 0);
3332 if (size == count) {
3333 if (strong_word_count)
3334 Result = strong_word_count;
3336 if (byref_word_count)
3337 Result += byref_word_count;
3339 if (weak_word_count)
3340 Result += weak_word_count;
3346llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(
bool ComputeByrefLayout) {
3347 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
3348 if (RunSkipBlockVars.empty())
3352 unsigned WordSizeInBytes = WordSizeInBits / ByteSizeInBits;
3356 llvm::array_pod_sort(RunSkipBlockVars.begin(), RunSkipBlockVars.end());
3357 SmallVector<unsigned char, 16> Layout;
3359 unsigned size = RunSkipBlockVars.size();
3360 for (
unsigned i = 0; i < size; i++) {
3361 enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode;
3362 CharUnits start_byte_pos = RunSkipBlockVars[i].block_var_bytepos;
3363 CharUnits end_byte_pos = start_byte_pos;
3366 if (opcode == RunSkipBlockVars[j].opcode) {
3367 end_byte_pos = RunSkipBlockVars[j++].block_var_bytepos;
3372 CharUnits size_in_bytes =
3373 end_byte_pos - start_byte_pos + RunSkipBlockVars[j - 1].block_var_size;
3375 CharUnits gap = RunSkipBlockVars[j].block_var_bytepos -
3376 RunSkipBlockVars[j - 1].block_var_bytepos -
3377 RunSkipBlockVars[j - 1].block_var_size;
3378 size_in_bytes += gap;
3381 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) {
3382 residue_in_bytes = size_in_bytes % WordSizeInBytes;
3383 size_in_bytes -= residue_in_bytes;
3384 opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS;
3387 unsigned size_in_words = size_in_bytes.
getQuantity() / WordSizeInBytes;
3388 while (size_in_words >= 16) {
3391 unsigned char inst = (opcode << 4) | 0xf;
3392 Layout.push_back(inst);
3393 size_in_words -= 16;
3395 if (size_in_words > 0) {
3398 unsigned char inst = (opcode << 4) | (size_in_words - 1);
3399 Layout.push_back(inst);
3402 unsigned char inst = (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) |
3404 Layout.push_back(inst);
3408 while (!Layout.empty()) {
3409 unsigned char inst = Layout.back();
3410 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3411 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES ||
3412 opcode == BLOCK_LAYOUT_NON_OBJECT_WORDS)
3422 if (ComputeByrefLayout)
3423 printf(
"\n Inline BYREF variable layout: ");
3425 printf(
"\n Inline block variable layout: ");
3427 if (
auto numStrong = (
Result & 0xF00) >> 8)
3428 printf(
", BL_STRONG:%d", (
int)numStrong);
3429 if (
auto numByref = (
Result & 0x0F0) >> 4)
3430 printf(
", BL_BYREF:%d", (
int)numByref);
3431 if (
auto numWeak = (
Result & 0x00F) >> 0)
3432 printf(
", BL_WEAK:%d", (
int)numWeak);
3433 printf(
", BL_OPERATOR:0\n");
3438 unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0;
3439 Layout.push_back(inst);
3441 for (
unsigned char C : Layout)
3445 if (ComputeByrefLayout)
3446 printf(
"\n Byref variable layout: ");
3448 printf(
"\n Block variable layout: ");
3449 for (
unsigned i = 0, e = BitMap.size(); i != e; i++) {
3450 unsigned char inst = BitMap[i];
3451 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3454 case BLOCK_LAYOUT_OPERATOR:
3458 case BLOCK_LAYOUT_NON_OBJECT_BYTES:
3459 printf(
"BL_NON_OBJECT_BYTES:");
3461 case BLOCK_LAYOUT_NON_OBJECT_WORDS:
3462 printf(
"BL_NON_OBJECT_WORD:");
3464 case BLOCK_LAYOUT_STRONG:
3467 case BLOCK_LAYOUT_BYREF:
3470 case BLOCK_LAYOUT_WEAK:
3473 case BLOCK_LAYOUT_UNRETAINED:
3474 printf(
"BL_UNRETAINED:");
3479 printf(
"%d", (inst & 0xf) + delta);
3487 return CreateCStringLiteral(BitMap, ObjCLabelType::LayoutBitMap,
3494 bool HasCopyDisposeHelpers) {
3496 for (
const CGObjCCommonMac::RUN_SKIP &R : RunSkipBlockVars) {
3497 if (R.opcode == CGObjCCommonMac::BLOCK_LAYOUT_UNRETAINED) {
3501 }
else if (HasCopyDisposeHelpers) {
3509 case CGObjCCommonMac::BLOCK_LAYOUT_STRONG:
3512 case CGObjCCommonMac::BLOCK_LAYOUT_BYREF:
3515 case CGObjCCommonMac::BLOCK_LAYOUT_WEAK:
3522 Str += llvm::to_string(R.block_var_bytepos.getQuantity());
3523 Str +=
"l" + llvm::to_string(R.block_var_size.getQuantity());
3528void CGObjCCommonMac::fillRunSkipBlockVars(CodeGenModule &CGM,
3529 const CGBlockInfo &blockInfo) {
3530 assert(CGM.
getLangOpts().getGC() == LangOptions::NonGC);
3532 RunSkipBlockVars.clear();
3533 bool hasUnion =
false;
3537 unsigned WordSizeInBytes = WordSizeInBits / ByteSizeInBits;
3542 const llvm::StructLayout *layout =
3552 for (
const auto &CI :
blockDecl->captures()) {
3553 const VarDecl *variable = CI.getVariable();
3556 const CGBlockInfo::Capture &capture = blockInfo.
getCapture(variable);
3562 CharUnits fieldOffset =
3565 assert(!
type->isArrayType() &&
"array variable should not be caught");
3567 if (
const auto *record =
type->getAsCanonical<RecordType>()) {
3568 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion);
3571 CharUnits fieldSize;
3576 UpdateRunSkipBlockVars(CI.isByRef(), getBlockCaptureLifetime(
type,
false),
3577 fieldOffset, fieldSize);
3582CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM,
3583 const CGBlockInfo &blockInfo) {
3584 fillRunSkipBlockVars(CGM, blockInfo);
3585 return getBitmapBlockLayout(
false);
3588std::string CGObjCCommonMac::getRCBlockLayoutStr(CodeGenModule &CGM,
3589 const CGBlockInfo &blockInfo) {
3590 fillRunSkipBlockVars(CGM, blockInfo);
3594llvm::Constant *CGObjCCommonMac::BuildByrefLayout(CodeGen::CodeGenModule &CGM,
3596 assert(CGM.
getLangOpts().getGC() == LangOptions::NonGC);
3597 assert(!
T->
isArrayType() &&
"__block array variable should not be caught");
3598 CharUnits fieldOffset;
3599 RunSkipBlockVars.clear();
3600 bool hasUnion =
false;
3602 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion,
3604 llvm::Constant *
Result = getBitmapBlockLayout(
true);
3609 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
3613llvm::Value *CGObjCMac::GenerateProtocolRef(CodeGenFunction &CGF,
3614 const ObjCProtocolDecl *PD) {
3619 return GetProtocolRef(PD);
3622void CGObjCCommonMac::GenerateProtocol(
const ObjCProtocolDecl *PD) {
3631 GetOrEmitProtocol(PD);
3634llvm::Constant *CGObjCCommonMac::GetProtocolRef(
const ObjCProtocolDecl *PD) {
3636 return GetOrEmitProtocol(PD);
3638 return GetOrEmitProtocolRef(PD);
3642CGObjCCommonMac::EmitClassRefViaRuntime(CodeGenFunction &CGF,
3643 const ObjCInterfaceDecl *ID,
3644 ObjCCommonTypesHelper &ObjCTypes) {
3645 llvm::FunctionCallee lookUpClassFn = ObjCTypes.getLookUpClassFn();
3647 llvm::Value *className = CGF.
CGM
3649 ID->getObjCRuntimeNameAsString()))
3652 className = CGF.
Builder.CreateBitCast(
3654 llvm::CallInst *call = CGF.
Builder.CreateCall(lookUpClassFn, className);
3655 call->setDoesNotThrow();
3671llvm::Constant *CGObjCMac::GetOrEmitProtocol(
const ObjCProtocolDecl *PD) {
3672 llvm::GlobalVariable *Entry = Protocols[PD->
getIdentifier()];
3675 if (Entry && Entry->hasInitializer())
3687 auto methodLists = ProtocolMethodLists::get(PD);
3689 ConstantInitBuilder builder(CGM);
3690 auto values = builder.beginStruct(ObjCTypes.ProtocolTy);
3691 values.add(EmitProtocolExtension(PD, methodLists));
3693 values.add(EmitProtocolList(
"OBJC_PROTOCOL_REFS_" + PD->
getName(),
3695 values.add(methodLists.emitMethodList(
3696 this, PD, ProtocolMethodLists::RequiredInstanceMethods));
3697 values.add(methodLists.emitMethodList(
3698 this, PD, ProtocolMethodLists::RequiredClassMethods));
3702 assert(Entry->hasPrivateLinkage());
3703 values.finishAndSetAsInitializer(Entry);
3705 Entry = values.finishAndCreateGlobal(
3707 false, llvm::GlobalValue::PrivateLinkage);
3708 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
3717llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD) {
3718 llvm::GlobalVariable *&Entry = Protocols[PD->
getIdentifier()];
3724 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolTy,
3725 false, llvm::GlobalValue::PrivateLinkage,
3726 nullptr,
"OBJC_PROTOCOL_" + PD->
getName());
3727 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
3729 Entry->setAlignment(llvm::Align(4));
3746CGObjCMac::EmitProtocolExtension(
const ObjCProtocolDecl *PD,
3747 const ProtocolMethodLists &methodLists) {
3748 auto optInstanceMethods = methodLists.emitMethodList(
3749 this, PD, ProtocolMethodLists::OptionalInstanceMethods);
3750 auto optClassMethods = methodLists.emitMethodList(
3751 this, PD, ProtocolMethodLists::OptionalClassMethods);
3753 auto extendedMethodTypes = EmitProtocolMethodTypes(
3754 "OBJC_PROTOCOL_METHOD_TYPES_" + PD->
getName(),
3755 methodLists.emitExtendedTypesArray(
this), ObjCTypes);
3757 auto instanceProperties = EmitPropertyList(
3758 "OBJC_$_PROP_PROTO_LIST_" + PD->
getName(),
nullptr, PD, ObjCTypes,
false);
3759 auto classProperties =
3760 EmitPropertyList(
"OBJC_$_CLASS_PROP_PROTO_LIST_" + PD->
getName(),
nullptr,
3761 PD, ObjCTypes,
true);
3764 if (optInstanceMethods->isNullValue() && optClassMethods->isNullValue() &&
3765 extendedMethodTypes->isNullValue() && instanceProperties->isNullValue() &&
3766 classProperties->isNullValue()) {
3767 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
3771 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
3773 ConstantInitBuilder builder(CGM);
3774 auto values = builder.beginStruct(ObjCTypes.ProtocolExtensionTy);
3775 values.addInt(ObjCTypes.IntTy, size);
3776 values.add(optInstanceMethods);
3777 values.add(optClassMethods);
3778 values.add(instanceProperties);
3779 values.add(extendedMethodTypes);
3780 values.add(classProperties);
3783 return CreateMetadataVar(
"_OBJC_PROTOCOLEXT_" + PD->
getName(), values,
3795CGObjCMac::EmitProtocolList(Twine name,
3799 auto PDs = GetRuntimeProtocolList(begin, end);
3801 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
3803 ConstantInitBuilder builder(CGM);
3804 auto values = builder.beginStruct();
3807 values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
3810 auto countSlot = values.addPlaceholder();
3812 auto refsArray = values.beginArray(ObjCTypes.ProtocolPtrTy);
3813 for (
const auto *Proto : PDs)
3814 refsArray.add(GetProtocolRef(Proto));
3816 auto count = refsArray.size();
3819 refsArray.addNullPointer(ObjCTypes.ProtocolPtrTy);
3821 refsArray.finishAndAddTo(values);
3822 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
3825 if (CGM.
getTriple().isOSBinFormatMachO())
3826 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3828 llvm::GlobalVariable *GV =
3829 CreateMetadataVar(name, values, section, CGM.
getPointerAlign(),
false);
3838 if (IsClassProperty != PD->isClassProperty())
3842 Properties.push_back(PD);
3845 for (
const auto *P : Proto->
protocols())
3861llvm::Constant *CGObjCCommonMac::EmitPropertyList(
3862 Twine Name,
const Decl *Container,
const ObjCContainerDecl *OCD,
3863 const ObjCCommonTypesHelper &ObjCTypes,
bool IsClassProperty) {
3864 if (IsClassProperty) {
3868 if ((Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 11)) ||
3869 (Triple.isiOS() && Triple.isOSVersionLT(9)))
3870 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3873 SmallVector<const ObjCPropertyDecl *, 16> Properties;
3874 llvm::SmallPtrSet<const IdentifierInfo *, 16> PropertySet;
3876 if (
const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD))
3877 for (
const ObjCCategoryDecl *ClassExt : OID->known_extensions())
3878 for (
auto *PD : ClassExt->properties()) {
3879 if (IsClassProperty != PD->isClassProperty())
3881 if (PD->isDirectProperty())
3884 Properties.push_back(PD);
3888 if (IsClassProperty != PD->isClassProperty())
3894 if (PD->isDirectProperty())
3896 Properties.push_back(PD);
3899 if (
const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) {
3900 for (
const auto *P : OID->all_referenced_protocols())
3902 }
else if (
const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD)) {
3903 for (
const auto *P : CD->protocols())
3908 if (Properties.empty())
3909 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3911 unsigned propertySize =
3914 ConstantInitBuilder builder(CGM);
3915 auto values = builder.beginStruct();
3916 values.addInt(ObjCTypes.IntTy, propertySize);
3917 values.addInt(ObjCTypes.IntTy, Properties.size());
3918 auto propertiesArray = values.beginArray(ObjCTypes.PropertyTy);
3919 for (
auto PD : Properties) {
3920 auto property = propertiesArray.beginStruct(ObjCTypes.PropertyTy);
3922 property.add(GetPropertyTypeString(PD, Container));
3923 property.finishAndAddTo(propertiesArray);
3925 propertiesArray.finishAndAddTo(values);
3928 if (CGM.
getTriple().isOSBinFormatMachO())
3929 Section = (ObjCABI == 2) ?
"__DATA, __objc_const"
3930 :
"__OBJC,__property,regular,no_dead_strip";
3932 llvm::GlobalVariable *GV =
3933 CreateMetadataVar(Name, values, Section, CGM.
getPointerAlign(),
true);
3937llvm::Constant *CGObjCCommonMac::EmitProtocolMethodTypes(
3938 Twine Name, ArrayRef<llvm::Constant *> MethodTypes,
3939 const ObjCCommonTypesHelper &ObjCTypes) {
3941 if (MethodTypes.empty())
3942 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy);
3944 llvm::ArrayType *AT =
3945 llvm::ArrayType::get(ObjCTypes.Int8PtrTy, MethodTypes.size());
3946 llvm::Constant *
Init = llvm::ConstantArray::get(AT, MethodTypes);
3949 if (CGM.
getTriple().isOSBinFormatMachO() && ObjCABI == 2)
3950 Section =
"__DATA, __objc_const";
3952 llvm::GlobalVariable *GV =
3969void CGObjCMac::GenerateCategory(
const ObjCCategoryImplDecl *OCD) {
3977 const ObjCCategoryDecl *Category =
3980 SmallString<256> ExtName;
3981 llvm::raw_svector_ostream(ExtName)
3984 ConstantInitBuilder Builder(CGM);
3985 auto Values = Builder.beginStruct(ObjCTypes.CategoryTy);
3987 enum { InstanceMethods, ClassMethods, NumMethodLists };
3988 SmallVector<const ObjCMethodDecl *, 16> Methods[NumMethodLists];
3989 for (
const auto *MD : OCD->
methods()) {
3990 if (!MD->isDirectMethod())
3991 Methods[unsigned(MD->isClassMethod())].push_back(MD);
3994 Values.add(GetClassName(OCD->
getName()));
3995 Values.add(GetClassName(
Interface->getObjCRuntimeNameAsString()));
3996 LazySymbols.insert(
Interface->getIdentifier());
3998 Values.add(emitMethodList(ExtName, MethodListType::CategoryInstanceMethods,
3999 Methods[InstanceMethods]));
4000 Values.add(emitMethodList(ExtName, MethodListType::CategoryClassMethods,
4001 Methods[ClassMethods]));
4003 Values.add(EmitProtocolList(
"OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
4004 Category->protocol_begin(),
4005 Category->protocol_end()));
4007 Values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
4009 Values.addInt(ObjCTypes.IntTy, Size);
4013 Values.add(EmitPropertyList(
"_OBJC_$_PROP_LIST_" + ExtName.str(), OCD,
4014 Category, ObjCTypes,
false));
4015 Values.add(EmitPropertyList(
"_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(), OCD,
4016 Category, ObjCTypes,
true));
4018 Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
4019 Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
4022 llvm::GlobalVariable *GV = CreateMetadataVar(
4023 "OBJC_CATEGORY_" + ExtName.str(), Values,
4024 "__OBJC,__category,regular,no_dead_strip", CGM.
getPointerAlign(),
true);
4025 DefinedCategories.push_back(GV);
4026 DefinedCategoryNames.insert(llvm::CachedHashString(ExtName));
4028 MethodDefinitions.clear();
4089 if (
auto *RD =
type->getAsRecordDecl()) {
4090 for (
auto *field : RD->
fields()) {
4109 ID->getClassInterface()->all_declared_ivar_begin();
4137void CGObjCMac::GenerateClass(
const ObjCImplementationDecl *ID) {
4138 IdentifierInfo *RuntimeName =
4140 DefinedSymbols.insert(RuntimeName);
4142 std::string ClassName =
ID->getNameAsString();
4145 const_cast<ObjCInterfaceDecl *
>(
ID->getClassInterface());
4146 llvm::Constant *Protocols =
4147 EmitProtocolList(
"OBJC_CLASS_PROTOCOLS_" +
ID->getName(),
4148 Interface->all_referenced_protocol_begin(),
4149 Interface->all_referenced_protocol_end());
4151 if (
ID->hasNonZeroConstructors() ||
ID->hasDestructors())
4154 bool hasMRCWeak =
false;
4169 enum { InstanceMethods, ClassMethods, NumMethodLists };
4170 SmallVector<const ObjCMethodDecl *, 16> Methods[NumMethodLists];
4171 for (
const auto *MD :
ID->methods()) {
4172 if (!MD->isDirectMethod())
4173 Methods[unsigned(MD->isClassMethod())].push_back(MD);
4176 for (
const auto *PID :
ID->property_impls()) {
4178 if (PID->getPropertyDecl()->isDirectProperty())
4180 if (ObjCMethodDecl *MD = PID->getGetterMethodDecl())
4181 if (GetMethodDefinition(MD))
4182 Methods[InstanceMethods].push_back(MD);
4183 if (ObjCMethodDecl *MD = PID->getSetterMethodDecl())
4184 if (GetMethodDefinition(MD))
4185 Methods[InstanceMethods].push_back(MD);
4189 ConstantInitBuilder builder(CGM);
4190 auto values = builder.beginStruct(ObjCTypes.ClassTy);
4191 values.add(EmitMetaClass(ID, Protocols, Methods[ClassMethods]));
4192 if (ObjCInterfaceDecl *Super =
Interface->getSuperClass()) {
4194 LazySymbols.insert(Super->getIdentifier());
4196 values.add(GetClassName(Super->getObjCRuntimeNameAsString()));
4198 values.addNullPointer(ObjCTypes.ClassPtrTy);
4200 values.add(GetClassName(
ID->getObjCRuntimeNameAsString()));
4202 values.addInt(ObjCTypes.LongTy, 0);
4203 values.addInt(ObjCTypes.LongTy, Flags);
4204 values.addInt(ObjCTypes.LongTy,
Size.getQuantity());
4205 values.add(EmitIvarList(ID,
false));
4206 values.add(emitMethodList(
ID->getName(), MethodListType::InstanceMethods,
4207 Methods[InstanceMethods]));
4209 values.addNullPointer(ObjCTypes.CachePtrTy);
4210 values.add(Protocols);
4212 values.add(EmitClassExtension(ID, Size, hasMRCWeak,
4215 std::string Name(
"OBJC_CLASS_");
4217 const char *Section =
"__OBJC,__class,regular,no_dead_strip";
4219 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
4221 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4222 "Forward metaclass reference has incorrect type.");
4223 values.finishAndSetAsInitializer(GV);
4224 GV->setSection(Section);
4228 GV = CreateMetadataVar(Name, values, Section, CGM.
getPointerAlign(),
true);
4229 DefinedClasses.push_back(GV);
4230 ImplementedClasses.push_back(
Interface);
4232 MethodDefinitions.clear();
4236CGObjCMac::EmitMetaClass(
const ObjCImplementationDecl *ID,
4237 llvm::Constant *Protocols,
4238 ArrayRef<const ObjCMethodDecl *> Methods) {
4245 ConstantInitBuilder builder(CGM);
4246 auto values = builder.beginStruct(ObjCTypes.ClassTy);
4248 const ObjCInterfaceDecl *Root =
ID->getClassInterface();
4249 while (
const ObjCInterfaceDecl *Super = Root->
getSuperClass())
4255 if (ObjCInterfaceDecl *Super =
ID->getClassInterface()->getSuperClass()) {
4256 values.add(GetClassName(Super->getObjCRuntimeNameAsString()));
4258 values.addNullPointer(ObjCTypes.ClassPtrTy);
4260 values.add(GetClassName(
ID->getObjCRuntimeNameAsString()));
4262 values.addInt(ObjCTypes.LongTy, 0);
4263 values.addInt(ObjCTypes.LongTy, Flags);
4264 values.addInt(ObjCTypes.LongTy, Size);
4265 values.add(EmitIvarList(ID,
true));
4267 emitMethodList(
ID->getName(), MethodListType::ClassMethods, Methods));
4269 values.addNullPointer(ObjCTypes.CachePtrTy);
4270 values.add(Protocols);
4272 values.addNullPointer(ObjCTypes.Int8PtrTy);
4277 std::string Name(
"OBJC_METACLASS_");
4278 Name +=
ID->getName();
4281 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
4283 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4284 "Forward metaclass reference has incorrect type.");
4285 values.finishAndSetAsInitializer(GV);
4289 llvm::GlobalValue::PrivateLinkage);
4291 GV->setSection(
"__OBJC,__meta_class,regular,no_dead_strip");
4297llvm::Constant *CGObjCMac::EmitMetaClassRef(
const ObjCInterfaceDecl *ID) {
4298 std::string Name =
"OBJC_METACLASS_" +
ID->getNameAsString();
4308 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
4310 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
4311 llvm::GlobalValue::PrivateLinkage,
nullptr,
4314 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4315 "Forward metaclass reference has incorrect type.");
4319llvm::Value *CGObjCMac::EmitSuperClassRef(
const ObjCInterfaceDecl *ID) {
4320 std::string Name =
"OBJC_CLASS_" +
ID->getNameAsString();
4321 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
4324 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
4325 llvm::GlobalValue::PrivateLinkage,
nullptr,
4328 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4329 "Forward class metadata reference has incorrect type.");
4344llvm::Constant *CGObjCMac::EmitClassExtension(
const ObjCImplementationDecl *ID,
4345 CharUnits InstanceSize,
4349 llvm::Constant *layout;
4351 layout = llvm::ConstantPointerNull::get(CGM.
Int8PtrTy);
4358 llvm::Constant *propertyList =
4359 EmitPropertyList((isMetaclass ? Twine(
"_OBJC_$_CLASS_PROP_LIST_")
4360 : Twine(
"_OBJC_$_PROP_LIST_")) +
4362 ID,
ID->getClassInterface(), ObjCTypes, isMetaclass);
4365 if (layout->isNullValue() && propertyList->isNullValue()) {
4366 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
4370 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
4372 ConstantInitBuilder builder(CGM);
4373 auto values = builder.beginStruct(ObjCTypes.ClassExtensionTy);
4374 values.addInt(ObjCTypes.IntTy, size);
4376 values.add(propertyList);
4378 return CreateMetadataVar(
"OBJC_CLASSEXT_" +
ID->getName(), values,
4379 "__OBJC,__class_ext,regular,no_dead_strip",
4395llvm::Constant *CGObjCMac::EmitIvarList(
const ObjCImplementationDecl *ID,
4403 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
4405 const ObjCInterfaceDecl *OID =
ID->getClassInterface();
4407 ConstantInitBuilder builder(CGM);
4408 auto ivarList = builder.beginStruct();
4409 auto countSlot = ivarList.addPlaceholder();
4410 auto ivars = ivarList.beginArray(ObjCTypes.IvarTy);
4415 if (!IVD->getDeclName())
4418 auto ivar = ivars.beginStruct(ObjCTypes.IvarTy);
4419 ivar.add(GetMethodVarName(IVD->getIdentifier()));
4420 ivar.add(GetMethodVarType(IVD));
4421 ivar.addInt(ObjCTypes.IntTy, ComputeIvarBaseOffset(CGM, OID, IVD));
4422 ivar.finishAndAddTo(ivars);
4426 auto count = ivars.size();
4430 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
4433 ivars.finishAndAddTo(ivarList);
4434 ivarList.fillPlaceholderWithInt(countSlot, ObjCTypes.IntTy, count);
4436 llvm::GlobalVariable *GV;
4437 GV = CreateMetadataVar(
"OBJC_INSTANCE_VARIABLES_" +
ID->getName(), ivarList,
4438 "__OBJC,__instance_vars,regular,no_dead_strip",
4449void CGObjCMac::emitMethodDescriptionConstant(ConstantArrayBuilder &builder,
4450 const ObjCMethodDecl *MD) {
4451 auto description = builder.
beginStruct(ObjCTypes.MethodDescriptionTy);
4452 description.add(GetMethodVarName(MD->
getSelector()));
4453 description.add(GetMethodVarType(MD));
4454 description.finishAndAddTo(builder);
4464void CGObjCMac::emitMethodConstant(ConstantArrayBuilder &builder,
4465 const ObjCMethodDecl *MD) {
4466 llvm::Function *fn = GetMethodDefinition(MD);
4467 assert(fn &&
"no definition registered for method");
4469 auto method = builder.
beginStruct(ObjCTypes.MethodTy);
4471 method.add(GetMethodVarType(MD));
4473 method.finishAndAddTo(builder);
4490CGObjCMac::emitMethodList(Twine name, MethodListType MLT,
4491 ArrayRef<const ObjCMethodDecl *> methods) {
4494 bool forProtocol =
false;
4496 case MethodListType::CategoryInstanceMethods:
4497 prefix =
"OBJC_CATEGORY_INSTANCE_METHODS_";
4498 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
4499 forProtocol =
false;
4501 case MethodListType::CategoryClassMethods:
4502 prefix =
"OBJC_CATEGORY_CLASS_METHODS_";
4503 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
4504 forProtocol =
false;
4506 case MethodListType::InstanceMethods:
4507 prefix =
"OBJC_INSTANCE_METHODS_";
4508 section =
"__OBJC,__inst_meth,regular,no_dead_strip";
4509 forProtocol =
false;
4511 case MethodListType::ClassMethods:
4512 prefix =
"OBJC_CLASS_METHODS_";
4513 section =
"__OBJC,__cls_meth,regular,no_dead_strip";
4514 forProtocol =
false;
4516 case MethodListType::ProtocolInstanceMethods:
4517 prefix =
"OBJC_PROTOCOL_INSTANCE_METHODS_";
4518 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
4521 case MethodListType::ProtocolClassMethods:
4522 prefix =
"OBJC_PROTOCOL_CLASS_METHODS_";
4523 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
4526 case MethodListType::OptionalProtocolInstanceMethods:
4527 prefix =
"OBJC_PROTOCOL_INSTANCE_METHODS_OPT_";
4528 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
4531 case MethodListType::OptionalProtocolClassMethods:
4532 prefix =
"OBJC_PROTOCOL_CLASS_METHODS_OPT_";
4533 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
4539 if (methods.empty())
4540 return llvm::Constant::getNullValue(
4541 forProtocol ? ObjCTypes.MethodDescriptionListPtrTy
4542 : ObjCTypes.MethodListPtrTy);
4547 ConstantInitBuilder builder(CGM);
4549 values.addInt(ObjCTypes.IntTy, methods.size());
4550 auto methodArray = values.beginArray(ObjCTypes.MethodDescriptionTy);
4551 for (
auto MD : methods) {
4552 emitMethodDescriptionConstant(methodArray, MD);
4554 methodArray.finishAndAddTo(values);
4556 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
4562 ConstantInitBuilder builder(CGM);
4564 values.addNullPointer(ObjCTypes.Int8PtrTy);
4565 values.addInt(ObjCTypes.IntTy, methods.size());
4566 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
4567 for (
auto MD : methods) {
4569 emitMethodConstant(methodArray, MD);
4571 methodArray.finishAndAddTo(values);
4573 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
4578llvm::Function *CGObjCCommonMac::GenerateMethod(
const ObjCMethodDecl *OMD,
4579 const ObjCContainerDecl *CD) {
4584 DirectMethodInfo &Info = GenerateDirectMethod(OMD, CD);
4585 Method = Info.Implementation;
4587 auto Name = getSymbolNameForMethod(OMD);
4589 CodeGenTypes &Types = CGM.
getTypes();
4590 llvm::FunctionType *MethodTy =
4592 Method = llvm::Function::Create(
4593 MethodTy, llvm::GlobalValue::InternalLinkage, Name, &CGM.
getModule());
4596 MethodDefinitions.insert(std::make_pair(OMD,
Method));
4602CGObjCCommonMac::DirectMethodInfo &
4603CGObjCCommonMac::GenerateDirectMethod(
const ObjCMethodDecl *OMD,
4604 const ObjCContainerDecl *CD) {
4609 auto Cached = DirectMethodDefinitions.find(COMD);
4610 if (Cached != DirectMethodDefinitions.end()) {
4612 return Cached->second;
4615 CodeGenTypes &Types = CGM.
getTypes();
4616 llvm::FunctionType *MethodTy =
4619 getSymbolNameForMethod(OMD,
false,
4621 std::string ThunkName = Name +
"_thunk";
4624 auto ReplaceFunction = [](llvm::Function *OldFn, llvm::Function *NewFn) {
4625 NewFn->takeName(OldFn);
4626 OldFn->replaceAllUsesWith(NewFn);
4627 OldFn->eraseFromParent();
4632 llvm::Function *
Fn = CGM.
getModule().getFunction(Name);
4636 Fn = llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,
4638 return DirectMethodDefinitions.insert({COMD, DirectMethodInfo(Fn)})
4644 if (
Fn->getFunctionType() == MethodTy) {
4646 Fn->setLinkage(llvm::GlobalValue::ExternalLinkage);
4649 DirectMethodInfo Info(Fn);
4650 if (llvm::Function *Thunk = CGM.
getModule().getFunction(ThunkName))
4653 return DirectMethodDefinitions.insert({COMD, Info}).first->second;
4659 llvm::Function *NewFn = llvm::Function::Create(
4660 MethodTy, llvm::GlobalValue::ExternalLinkage,
"", &CGM.
getModule());
4661 ReplaceFunction(Fn, NewFn);
4664 DirectMethodInfo Info(NewFn);
4665 if (llvm::Function *OldThunk = CGM.
getModule().getFunction(ThunkName)) {
4666 llvm::Function *NewThunk = GenerateObjCDirectThunk(OMD, CD, NewFn);
4667 ReplaceFunction(OldThunk, NewThunk);
4668 Info.Thunk = NewThunk;
4671 if (Cached != DirectMethodDefinitions.end()) {
4672 Cached->second = Info;
4673 return Cached->second;
4675 return DirectMethodDefinitions.insert({COMD, Info}).first->second;
4741CGObjCCommonMac::GenerateObjCDirectThunk(
const ObjCMethodDecl *OMD,
4743 llvm::Function *Implementation) {
4746 "Should only generate thunk when optimization enabled");
4747 assert(Implementation &&
"Implementation must exist");
4749 llvm::FunctionType *ThunkTy = Implementation->getFunctionType();
4750 std::string ThunkName = Implementation->getName().str() +
"_thunk";
4753 llvm::Function *Thunk =
4754 llvm::Function::Create(ThunkTy, llvm::GlobalValue::LinkOnceODRLinkage,
4761 Thunk->setVisibility(llvm::GlobalValue::HiddenVisibility);
4762 Thunk->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4781 GenerateDirectMethodsPreconditionCheck(CGF, Thunk, OMD, CD);
4786 for (
auto &Arg : Thunk->args())
4787 Args.push_back(&Arg);
4790 llvm::CallInst *
Call = CGF.
Builder.CreateCall(Implementation, Args);
4791 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
4798 llvm::AttributeList Attrs;
4802 Call->setAttributes(Attrs);
4803 Call->setCallingConv(
static_cast<llvm::CallingConv::ID
>(
CallingConv));
4808 if (ThunkTy->getReturnType()->isVoidTy())
4818llvm::Function *CGObjCCommonMac::GetDirectMethodCallee(
4820 bool ReceiverCanBeNull,
bool ClassObjectCanBeUnrealized) {
4825 DirectMethodInfo Info = GenerateDirectMethod(OMD, CD);
4831 return Info.Implementation;
4835 auto getOrCreateThunk = [&]() {
4837 Info.Thunk = GenerateObjCDirectThunk(OMD, CD, Info.Implementation);
4847 return ReceiverCanBeNull ? getOrCreateThunk() : Info.Implementation;
4850 "OMD should either be a class method or instance method");
4854 return (ReceiverCanBeNull || ClassObjectCanBeUnrealized)
4855 ? getOrCreateThunk()
4856 : Info.Implementation;
4860CGObjCCommonMac::GenerateClassRealization(CodeGenFunction &CGF,
4861 llvm::Value *classObject,
4862 const ObjCInterfaceDecl *OID) {
4869 RValue result = GeneratePossiblySpecializedMessageSend(
4870 CGF, ReturnValueSlot(), ResultType, SelfSel, classObject, Args, OID,
4876void CGObjCCommonMac::GenerateDirectMethodsPreconditionCheck(
4877 CodeGenFunction &CGF, llvm::Function *Fn,
const ObjCMethodDecl *OMD,
4878 const ObjCContainerDecl *CD) {
4880 bool ReceiverCanBeNull =
true;
4882 auto selfValue = Builder.CreateLoad(selfAddr);
4897 "GenerateDirectMethod() should be called with the Class Interface");
4908 llvm::Value *realizedClass = GenerateClassRealization(CGF, selfValue, OID);
4909 Builder.CreateStore(realizedClass, selfAddr);
4914 ReceiverCanBeNull = isWeakLinkedClass(OID);
4918 if (ReceiverCanBeNull) {
4919 llvm::BasicBlock *SelfIsNilBlock =
4921 llvm::BasicBlock *ContBlock =
4926 auto Zero = llvm::ConstantPointerNull::get(selfTy);
4929 Builder.CreateCondBr(Builder.CreateICmpEQ(selfValue,
Zero), SelfIsNilBlock,
4930 ContBlock, MDHelper.createUnlikelyBranchWeights());
4936 Builder.SetInsertPoint(SelfIsNilBlock);
4937 if (!retTy->isVoidType()) {
4945 Builder.SetInsertPoint(ContBlock);
4949void CGObjCCommonMac::GenerateDirectMethodPrologue(
4950 CodeGenFunction &CGF, llvm::Function *Fn,
const ObjCMethodDecl *OMD,
4951 const ObjCContainerDecl *CD) {
4954 GenerateDirectMethodsPreconditionCheck(CGF, Fn, OMD, CD);
4963 Builder.CreateStore(GetSelector(CGF, OMD),
4968llvm::Function *CGObjCCommonMac::GenerateMethodSelectorStub(
4969 Selector Sel, StringRef ClassName,
const ObjCCommonTypesHelper &ObjCTypes) {
4970 assert((!ClassName.data() || !ClassName.empty()) &&
4971 "class name cannot be an empty string");
4972 auto Key = std::make_pair(Sel, ClassName);
4973 auto I = MethodSelectorStubs.find(Key);
4975 if (I != MethodSelectorStubs.end())
4978 auto *FnTy = llvm::FunctionType::get(
4979 ObjCTypes.ObjectPtrTy, {ObjCTypes.ObjectPtrTy, ObjCTypes.SelectorPtrTy},
4983 if (ClassName.data())
4984 FnName = (
"objc_msgSendClass$" + Sel.
getAsString() +
"$_OBJC_CLASS_$_" +
4985 llvm::Twine(ClassName))
4993 MethodSelectorStubs.insert(std::make_pair(Key, Fn));
4997llvm::GlobalVariable *
4998CGObjCCommonMac::CreateMetadataVar(Twine Name, ConstantStructBuilder &
Init,
4999 StringRef Section, CharUnits Align,
5001 llvm::GlobalValue::LinkageTypes
LT =
5003 llvm::GlobalVariable *GV =
5004 Init.finishAndCreateGlobal(Name, Align,
false, LT);
5005 if (!Section.empty())
5006 GV->setSection(Section);
5012llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
5013 llvm::Constant *
Init,
5017 llvm::Type *Ty =
Init->getType();
5018 llvm::GlobalValue::LinkageTypes
LT =
5020 llvm::GlobalVariable *GV =
5021 new llvm::GlobalVariable(CGM.
getModule(), Ty,
false, LT,
Init, Name);
5022 if (!Section.empty())
5023 GV->setSection(Section);
5030llvm::GlobalVariable *
5031CGObjCCommonMac::CreateCStringLiteral(StringRef Name, ObjCLabelType
Type,
5032 bool ForceNonFragileABI,
5033 bool NullTerminate) {
5036 case ObjCLabelType::ClassName:
5037 Label =
"OBJC_CLASS_NAME_";
5039 case ObjCLabelType::MethodVarName:
5040 Label =
"OBJC_METH_VAR_NAME_";
5042 case ObjCLabelType::MethodVarType:
5043 Label =
"OBJC_METH_VAR_TYPE_";
5045 case ObjCLabelType::PropertyName:
5046 Label =
"OBJC_PROP_NAME_ATTR_";
5048 case ObjCLabelType::LayoutBitMap:
5049 Label =
"OBJC_LAYOUT_BITMAP_";
5053 bool NonFragile = ForceNonFragileABI || isNonFragileABI();
5057 case ObjCLabelType::ClassName:
5058 Section = NonFragile ?
"__TEXT,__objc_classname,cstring_literals"
5059 :
"__TEXT,__cstring,cstring_literals";
5061 case ObjCLabelType::MethodVarName:
5062 Section = NonFragile ?
"__TEXT,__objc_methname,cstring_literals"
5063 :
"__TEXT,__cstring,cstring_literals";
5065 case ObjCLabelType::MethodVarType:
5066 Section = NonFragile ?
"__TEXT,__objc_methtype,cstring_literals"
5067 :
"__TEXT,__cstring,cstring_literals";
5069 case ObjCLabelType::PropertyName:
5070 Section = NonFragile ?
"__TEXT,__objc_methname,cstring_literals"
5071 :
"__TEXT,__cstring,cstring_literals";
5073 case ObjCLabelType::LayoutBitMap:
5074 Section =
"__TEXT,__cstring,cstring_literals";
5078 llvm::Constant *
Value =
5079 llvm::ConstantDataArray::getString(VMContext, Name, NullTerminate);
5080 llvm::GlobalVariable *GV =
new llvm::GlobalVariable(
5082 true, llvm::GlobalValue::PrivateLinkage,
Value, Label);
5083 if (CGM.
getTriple().isOSBinFormatMachO())
5084 GV->setSection(Section);
5085 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
5092llvm::Function *CGObjCMac::ModuleInitFunction() {
5098llvm::FunctionCallee CGObjCMac::GetPropertyGetFunction() {
5099 return ObjCTypes.getGetPropertyFn();
5102llvm::FunctionCallee CGObjCMac::GetPropertySetFunction() {
5103 return ObjCTypes.getSetPropertyFn();
5106llvm::FunctionCallee CGObjCMac::GetOptimizedPropertySetFunction(
bool atomic,
5108 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
5111llvm::FunctionCallee CGObjCMac::GetGetStructFunction() {
5112 return ObjCTypes.getCopyStructFn();
5115llvm::FunctionCallee CGObjCMac::GetSetStructFunction() {
5116 return ObjCTypes.getCopyStructFn();
5119llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectGetFunction() {
5120 return ObjCTypes.getCppAtomicObjectFunction();
5123llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectSetFunction() {
5124 return ObjCTypes.getCppAtomicObjectFunction();
5127llvm::FunctionCallee CGObjCMac::EnumerationMutationFunction() {
5128 return ObjCTypes.getEnumerationMutationFn();
5131void CGObjCMac::EmitTryStmt(CodeGenFunction &CGF,
const ObjCAtTryStmt &S) {
5132 return EmitTryOrSynchronizedStmt(CGF, S);
5135void CGObjCMac::EmitSynchronizedStmt(CodeGenFunction &CGF,
5136 const ObjCAtSynchronizedStmt &S) {
5137 return EmitTryOrSynchronizedStmt(CGF, S);
5141struct PerformFragileFinally final : EHScopeStack::Cleanup {
5146 ObjCTypesHelper &ObjCTypes;
5147 PerformFragileFinally(
const Stmt *S, Address SyncArgSlot,
5148 Address CallTryExitVar, Address ExceptionData,
5149 ObjCTypesHelper *ObjCTypes)
5150 : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
5151 ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
5153 void Emit(CodeGenFunction &CGF, Flags flags)
override {
5156 llvm::BasicBlock *FinallyCallExit =
5158 llvm::BasicBlock *FinallyNoCallExit =
5161 FinallyCallExit, FinallyNoCallExit);
5170 if (
const ObjCAtFinallyStmt *FinallyStmt =
5173 if (flags.isForEHCleanup())
5178 llvm::Value *CurCleanupDest =
5181 CGF.
EmitStmt(FinallyStmt->getFinallyBody());
5200class FragileHazards {
5201 CodeGenFunction &CGF;
5202 SmallVector<llvm::Value *, 20> Locals;
5203 llvm::DenseSet<llvm::BasicBlock *> BlocksBeforeTry;
5205 llvm::InlineAsm *ReadHazard;
5206 llvm::InlineAsm *WriteHazard;
5208 llvm::FunctionType *GetAsmFnType();
5210 void collectLocals();
5211 void emitReadHazard(CGBuilderTy &Builder);
5214 FragileHazards(CodeGenFunction &CGF);
5216 void emitWriteHazard();
5217 void emitHazardsInNewBlocks();
5226FragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) {
5233 for (llvm::BasicBlock &BB : *CGF.
CurFn)
5234 BlocksBeforeTry.insert(&BB);
5236 llvm::FunctionType *AsmFnTy = GetAsmFnType();
5244 std::string Constraint;
5245 for (
unsigned I = 0, E = Locals.size(); I != E; ++I) {
5251 ReadHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
5259 std::string Constraint;
5260 for (
unsigned I = 0, E = Locals.size(); I != E; ++I) {
5263 Constraint +=
"=*m";
5266 WriteHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
5271void FragileHazards::emitWriteHazard() {
5276 for (
auto Pair : llvm::enumerate(Locals))
5279 llvm::Attribute::get(
5284void FragileHazards::emitReadHazard(
CGBuilderTy &Builder) {
5285 assert(!Locals.empty());
5286 llvm::CallInst *call = Builder.CreateCall(ReadHazard, Locals);
5287 call->setDoesNotThrow();
5289 for (
auto Pair : llvm::enumerate(Locals))
5292 llvm::Attribute::get(
5293 Builder.getContext(), llvm::Attribute::ElementType,
5299void FragileHazards::emitHazardsInNewBlocks() {
5306 for (llvm::BasicBlock &BB : *CGF.
CurFn) {
5307 if (BlocksBeforeTry.count(&BB))
5311 for (llvm::BasicBlock::iterator BI = BB.begin(), BE = BB.end(); BI != BE;
5313 llvm::Instruction &I = *BI;
5332 Builder.SetInsertPoint(&BB, BI);
5333 emitReadHazard(Builder);
5340 if (llvm::Value *Ptr =
V.getBasePointer())
5344void FragileHazards::collectLocals() {
5346 llvm::DenseSet<llvm::Value *> AllocasToIgnore;
5352 llvm::BasicBlock &Entry = CGF.
CurFn->getEntryBlock();
5353 for (llvm::Instruction &I : Entry)
5355 Locals.push_back(&I);
5358llvm::FunctionType *FragileHazards::GetAsmFnType() {
5359 SmallVector<llvm::Type *, 16> tys(Locals.size());
5360 for (
unsigned i = 0, e = Locals.size(); i != e; ++i)
5361 tys[i] = Locals[i]->getType();
5362 return llvm::FunctionType::get(CGF.
VoidTy, tys,
false);
5473void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
5494 llvm::Value *SyncArg =
5496 SyncArg = CGF.
Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
5507 ObjCTypes.ExceptionDataTy, CGF.
getPointerAlign(),
"exceptiondata.ptr");
5513 FragileHazards Hazards(CGF);
5532 SyncArgSlot, CallTryExitVar,
5533 ExceptionData, &ObjCTypes);
5539 ExceptionData.emitRawPointer(CGF));
5542 llvm::Constant *
Zero = llvm::ConstantInt::get(CGF.
Builder.getInt32Ty(), 0);
5545 ObjCTypes.ExceptionDataTy, ExceptionData.emitRawPointer(CGF), GEPIndexes,
5548 ObjCTypes.getSetJmpFn(), SetJmpBuffer,
"setjmp_result");
5549 SetJmpResult->setCanReturnTwice();
5555 llvm::Value *DidCatch =
5556 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
5557 CGF.
Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
5565 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.
Builder.saveAndClearIP();
5571 Hazards.emitWriteHazard();
5585 ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF),
5596 llvm::BasicBlock *CatchBlock =
nullptr;
5597 llvm::BasicBlock *CatchHandler =
nullptr;
5608 ExceptionData.emitRawPointer(CGF));
5611 ObjCTypes.getSetJmpFn(), SetJmpBuffer,
"setjmp.result");
5612 SetJmpResult->setCanReturnTwice();
5614 llvm::Value *Threw =
5615 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
5619 CGF.
Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
5629 bool AllMatched =
false;
5630 for (
const ObjCAtCatchStmt *CatchStmt : AtTryStmt->
catch_stmts()) {
5631 const VarDecl *CatchParam = CatchStmt->getCatchParamDecl();
5632 const ObjCObjectPointerType *OPT =
nullptr;
5638 OPT = CatchParam->
getType()->
getAs<ObjCObjectPointerType>();
5657 EmitInitOfCatchParam(CGF, Caught, CatchParam);
5660 CGF.
EmitStmt(CatchStmt->getCatchBody());
5663 CatchVarCleanups.ForceCleanup();
5669 assert(OPT &&
"Unexpected non-object pointer type in @catch");
5673 ObjCInterfaceDecl *IDecl = ObjTy->getInterface();
5674 assert(IDecl &&
"Catch parameter must have Objective-C type!");
5677 llvm::Value *
Class = EmitClassRef(CGF, IDecl);
5679 llvm::Value *matchArgs[] = {
Class, Caught};
5681 ObjCTypes.getExceptionMatchFn(), matchArgs,
"match");
5687 MatchedBlock, NextCatchBlock);
5700 llvm::Value *Tmp = CGF.
Builder.CreateBitCast(
5702 EmitInitOfCatchParam(CGF, Tmp, CatchParam);
5704 CGF.
EmitStmt(CatchStmt->getCatchBody());
5707 CatchVarCleanups.ForceCleanup();
5718 if (Caught->use_empty())
5719 Caught->eraseFromParent();
5735 assert(PropagatingExnVar.
isValid());
5737 ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF),
5748 Hazards.emitHazardsInNewBlocks();
5751 CGF.
Builder.restoreIP(TryFallthroughIP);
5758 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
5762 llvm::Value *PropagatingExn;
5763 if (PropagatingExnVar.
isValid()) {
5769 ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF));
5770 PropagatingExn = Caught;
5775 CGF.
Builder.CreateUnreachable();
5778 CGF.
Builder.restoreIP(SavedIP);
5781void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
5782 const ObjCAtThrowStmt &S,
5783 bool ClearInsertionPoint) {
5784 llvm::Value *ExceptionAsObject;
5789 CGF.
Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
5792 "Unexpected rethrow outside @catch block.");
5796 CGF.
EmitRuntimeCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
5797 ->setDoesNotReturn();
5798 CGF.
Builder.CreateUnreachable();
5801 if (ClearInsertionPoint)
5802 CGF.
Builder.ClearInsertionPoint();
5808llvm::Value *CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
5811 llvm::Value *AddrWeakObjVal = CGF.
Builder.CreateBitCast(
5814 ObjCTypes.getGcReadWeakFn(), AddrWeakObjVal,
"weakread");
5815 read_weak = CGF.
Builder.CreateBitCast(read_weak, DestTy);
5822void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
5823 llvm::Value *src,
Address dst) {
5824 llvm::Type *SrcTy = src->getType();
5827 assert(Size <= 8 && "does not support size > 8
");
5828 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
5829 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
5830 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5832 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5833 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
5834 ObjCTypes.PtrObjectPtrTy);
5835 llvm::Value *args[] = {src, dstVal};
5836 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), args,
5843void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
5844 llvm::Value *src, Address dst,
5846 llvm::Type *SrcTy = src->getType();
5847 if (!isa<llvm::PointerType>(SrcTy)) {
5848 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
5849 assert(Size <= 8 && "does
not support size > 8
");
5850 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
5851 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
5852 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5854 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5855 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
5856 ObjCTypes.PtrObjectPtrTy);
5857 llvm::Value *args[] = {src, dstVal};
5859 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), args,
5862 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(), args,
5863 "threadlocalassign
");
5869void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
5870 llvm::Value *src, Address dst,
5871 llvm::Value *ivarOffset) {
5872 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset
is NULL");
5873 llvm::Type *SrcTy = src->getType();
5874 if (!isa<llvm::PointerType>(SrcTy)) {
5875 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
5876 assert(Size <= 8 && "does
not support size > 8
");
5877 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
5878 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
5879 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5881 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5882 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
5883 ObjCTypes.PtrObjectPtrTy);
5884 llvm::Value *args[] = {src, dstVal, ivarOffset};
5885 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
5891void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
5892 llvm::Value *src, Address dst) {
5893 llvm::Type *SrcTy = src->getType();
5894 if (!isa<llvm::PointerType>(SrcTy)) {
5895 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
5896 assert(Size <= 8 && "does
not support size > 8
");
5897 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
5898 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
5899 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5901 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5902 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
5903 ObjCTypes.PtrObjectPtrTy);
5904 llvm::Value *args[] = {src, dstVal};
5905 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), args,
5909void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
5910 Address DestPtr, Address SrcPtr,
5911 llvm::Value *size) {
5912 llvm::Value *args[] = {DestPtr.emitRawPointer(CGF),
5913 SrcPtr.emitRawPointer(CGF), size};
5914 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
5919LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
5921 llvm::Value *BaseValue,
5922 const ObjCIvarDecl *Ivar,
5923 unsigned CVRQualifiers) {
5924 const ObjCInterfaceDecl *ID =
5925 ObjectTy->castAs<ObjCObjectType>()->getInterface();
5926 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
5927 EmitIvarOffset(CGF, ID, Ivar));
5930llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
5931 const ObjCInterfaceDecl *Interface,
5932 const ObjCIvarDecl *Ivar) {
5933 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
5934 return llvm::ConstantInt::get(
5935 CGM.getTypes().ConvertType(CGM.getContext().LongTy), Offset);
5938/* *** Private Interface *** */
5940std::string CGObjCCommonMac::GetSectionName(StringRef Section,
5941 StringRef MachOAttributes) {
5942 switch (CGM.getTriple().getObjectFormat()) {
5943 case llvm::Triple::UnknownObjectFormat:
5944 llvm_unreachable("unexpected
object file format
");
5945 case llvm::Triple::MachO: {
5946 if (MachOAttributes.empty())
5947 return ("__DATA,
" + Section).str();
5948 return ("__DATA,
" + Section + ",
" + MachOAttributes).str();
5950 case llvm::Triple::ELF:
5951 assert(Section.starts_with("__
") && "expected the name to begin with __
");
5952 return Section.substr(2).str();
5953 case llvm::Triple::COFF:
5954 assert(Section.starts_with("__
") && "expected the name to begin with __
");
5955 return (".
" + Section.substr(2) + "$B
").str();
5956 case llvm::Triple::Wasm:
5957 case llvm::Triple::GOFF:
5958 case llvm::Triple::SPIRV:
5959 case llvm::Triple::XCOFF:
5960 case llvm::Triple::DXContainer:
5961 llvm::report_fatal_error(
5962 "Objective-
C support
is unimplemented
for object file format
");
5965 llvm_unreachable("Unhandled llvm::Triple::ObjectFormatType
enum");
5977enum ImageInfoFlags {
5978 eImageInfo_FixAndContinue = (1 << 0), // This flag is no longer set by clang.
5979 eImageInfo_GarbageCollected = (1 << 1),
5980 eImageInfo_GCOnly = (1 << 2),
5981 eImageInfo_OptimizedByDyld = (1 << 3), // This flag is set by the dyld shared cache.
5983 eImageInfo_SignedClassRO = (1 << 4), // Reused (was _CorrectedSynthesize)
5984 eImageInfo_ImageIsSimulated = (1 << 5),
5985 eImageInfo_ClassProperties = (1 << 6)
5989void CGObjCCommonMac::EmitImageInfo() {
5990 unsigned version = 0; // Version is unused?
5991 std::string Section =
5993 ? "__OBJC,__image_info,regular
"
5994 : GetSectionName("__objc_imageinfo
", "regular,no_dead_strip
");
5996 // Generate module-level named metadata to convey this information to the
5997 // linker and code-gen.
5998 llvm::Module &Mod = CGM.getModule();
6000 // Add the ObjC ABI version to the module flags.
6001 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Version
", ObjCABI);
6002 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Image Info Version
",
6004 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Image Info Section
",
6005 llvm::MDString::get(VMContext, Section));
6007 auto Int8Ty = llvm::Type::getInt8Ty(VMContext);
6008 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
6009 // Non-GC overrides those files which specify GC.
6010 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Garbage Collection
",
6011 llvm::ConstantInt::get(Int8Ty, 0));
6013 // Add the ObjC garbage collection value.
6015 llvm::Module::Error, "Objective-
C Garbage Collection
",
6016 llvm::ConstantInt::get(Int8Ty, (uint8_t)eImageInfo_GarbageCollected));
6018 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
6019 // Add the ObjC GC Only value.
6020 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C GC Only
",
6023 // Require that GC be specified and set to eImageInfo_GarbageCollected.
6024 llvm::Metadata *Ops[2] = {
6025 llvm::MDString::get(VMContext, "Objective-
C Garbage Collection
"),
6026 llvm::ConstantAsMetadata::get(
6027 llvm::ConstantInt::get(Int8Ty, eImageInfo_GarbageCollected))};
6028 Mod.addModuleFlag(llvm::Module::Require, "Objective-
C GC Only
",
6029 llvm::MDNode::get(VMContext, Ops));
6033 // Indicate whether we're compiling this to run on a simulator.
6034 if (CGM.getTarget().getTriple().isSimulatorEnvironment())
6035 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Is Simulated
",
6036 eImageInfo_ImageIsSimulated);
6038 // Indicate whether we are generating class properties.
6039 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Class Properties
",
6040 eImageInfo_ClassProperties);
6042 // Indicate whether we want enforcement of pointer signing for class_ro_t
6044 if (CGM.getLangOpts().PointerAuthObjcClassROPointers)
6045 Mod.addModuleFlag(llvm::Module::Error,
6046 "Objective-
C Enforce ClassRO
Pointer Signing
",
6047 eImageInfo_SignedClassRO);
6049 Mod.addModuleFlag(llvm::Module::Error,
6050 "Objective-
C Enforce ClassRO
Pointer Signing
",
6051 llvm::ConstantInt::get(Int8Ty, 0));
6054// struct objc_module {
6055// unsigned long version;
6056// unsigned long size;
6061// FIXME: Get from somewhere
6062static const int ModuleVersion = 7;
6064void CGObjCMac::EmitModuleInfo() {
6065 uint64_t Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ModuleTy);
6067 ConstantInitBuilder builder(CGM);
6068 auto values = builder.beginStruct(ObjCTypes.ModuleTy);
6069 values.addInt(ObjCTypes.LongTy, ModuleVersion);
6070 values.addInt(ObjCTypes.LongTy, Size);
6071 // This used to be the filename, now it is unused. <rdr://4327263>
6072 values.add(GetClassName(StringRef("")));
6073 values.add(EmitModuleSymbols());
6074 CreateMetadataVar("OBJC_MODULES
", values,
6075 "__OBJC,__module_info,regular,no_dead_strip
",
6076 CGM.getPointerAlign(), true);
6079llvm::Constant *CGObjCMac::EmitModuleSymbols() {
6080 unsigned NumClasses = DefinedClasses.size();
6081 unsigned NumCategories = DefinedCategories.size();
6083 // Return null if no symbols were defined.
6084 if (!NumClasses && !NumCategories)
6085 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
6087 ConstantInitBuilder builder(CGM);
6088 auto values = builder.beginStruct();
6089 values.addInt(ObjCTypes.LongTy, 0);
6090 values.addNullPointer(ObjCTypes.SelectorPtrTy);
6091 values.addInt(ObjCTypes.ShortTy, NumClasses);
6092 values.addInt(ObjCTypes.ShortTy, NumCategories);
6094 // The runtime expects exactly the list of defined classes followed
6095 // by the list of defined categories, in a single array.
6096 auto array = values.beginArray(ObjCTypes.Int8PtrTy);
6097 for (unsigned i = 0; i < NumClasses; i++) {
6098 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
6100 if (ObjCImplementationDecl *IMP = ID->getImplementation())
6101 // We are implementing a weak imported interface. Give it external linkage
6102 if (ID->isWeakImported() && !IMP->isWeakImported())
6103 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
6105 array.add(DefinedClasses[i]);
6107 for (unsigned i = 0; i < NumCategories; i++)
6108 array.add(DefinedCategories[i]);
6110 array.finishAndAddTo(values);
6112 llvm::GlobalVariable *GV = CreateMetadataVar(
6113 "OBJC_SYMBOLS
", values, "__OBJC,__symbols,regular,no_dead_strip
",
6114 CGM.getPointerAlign(), true);
6118llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF,
6119 IdentifierInfo *II) {
6120 LazySymbols.insert(II);
6122 llvm::GlobalVariable *&Entry = ClassReferences[II];
6126 CreateMetadataVar("OBJC_CLASS_REFERENCES_
", GetClassName(II->getName()),
6127 "__OBJC,__cls_refs,literal_pointers,no_dead_strip
",
6128 CGM.getPointerAlign(), true);
6131 return CGF.Builder.CreateAlignedLoad(Entry->getValueType(), Entry,
6132 CGF.getPointerAlign());
6135llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF,
6136 const ObjCInterfaceDecl *ID) {
6137 // If the class has the objc_runtime_visible attribute, we need to
6138 // use the Objective-C runtime to get the class.
6139 if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
6140 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
6142 IdentifierInfo *RuntimeName =
6143 &CGM.getContext().Idents.get(ID->getObjCRuntimeNameAsString());
6144 return EmitClassRefFromId(CGF, RuntimeName);
6147llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
6148 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool
");
6149 return EmitClassRefFromId(CGF, II);
6152llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel) {
6153 return CGF.Builder.CreateLoad(EmitSelectorAddr(Sel));
6156ConstantAddress CGObjCMac::EmitSelectorAddr(Selector Sel) {
6157 CharUnits Align = CGM.getPointerAlign();
6159 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
6161 Entry = CreateMetadataVar(
6162 "OBJC_SELECTOR_REFERENCES_
", GetMethodVarName(Sel),
6163 "__OBJC,__message_refs,literal_pointers,no_dead_strip
", Align, true);
6164 Entry->setExternallyInitialized(true);
6167 return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align);
6170llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) {
6171 llvm::GlobalVariable *&Entry = ClassNames[RuntimeName];
6173 Entry = CreateCStringLiteral(RuntimeName, ObjCLabelType::ClassName);
6177llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
6178 return MethodDefinitions.lookup(MD);
6184CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
6185 const ObjCCommonTypesHelper &ObjCTypes) {
6186 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
6189void IvarLayoutBuilder::visitRecord(const RecordType *RT, CharUnits offset) {
6190 const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
6192 // If this is a union, remember that we had one, because it might mess
6193 // up the ordering of layout entries.
6195 IsDisordered = true;
6197 const ASTRecordLayout *recLayout = nullptr;
6198 visitAggregate(RD->field_begin(), RD->field_end(), offset,
6199 [&](const FieldDecl *field) -> CharUnits {
6201 recLayout = &CGM.getContext().getASTRecordLayout(RD);
6203 recLayout->getFieldOffset(field->getFieldIndex());
6204 return CGM.getContext().toCharUnitsFromBits(offsetInBits);
6208template <class Iterator, class GetOffsetFn>
6209void IvarLayoutBuilder::visitAggregate(Iterator begin, Iterator end,
6210 CharUnits aggregateOffset,
6211 const GetOffsetFn &getOffset) {
6212 for (; begin != end; ++begin) {
6213 auto field = *begin;
6215 // Skip over bitfields.
6216 if (field->isBitField()) {
6220 // Compute the offset of the field within the aggregate.
6221 CharUnits fieldOffset = aggregateOffset + getOffset(field);
6223 visitField(field, fieldOffset);
6228void IvarLayoutBuilder::visitField(const FieldDecl *field,
6229 CharUnits fieldOffset) {
6230 QualType fieldType = field->getType();
6232 // Drill down into arrays.
6233 uint64_t numElts = 1;
6234 if (auto arrayType = CGM.getContext().getAsIncompleteArrayType(fieldType)) {
6236 fieldType = arrayType->getElementType();
6238 // Unlike incomplete arrays, constant arrays can be nested.
6239 while (auto arrayType = CGM.getContext().getAsConstantArrayType(fieldType)) {
6240 numElts *= arrayType->getZExtSize();
6241 fieldType = arrayType->getElementType();
6244 assert(!fieldType->isArrayType() && "ivar of non-constant array
type?
");
6246 // If we ended up with a zero-sized array, we've done what we can do within
6247 // the limits of this layout encoding.
6251 // Recurse if the base element type is a record type.
6252 if (const auto *recType = fieldType->getAsCanonical<RecordType>()) {
6253 size_t oldEnd = IvarsInfo.size();
6255 visitRecord(recType, fieldOffset);
6257 // If we have an array, replicate the first entry's layout information.
6258 auto numEltEntries = IvarsInfo.size() - oldEnd;
6259 if (numElts != 1 && numEltEntries != 0) {
6260 CharUnits eltSize = CGM.getContext().getTypeSizeInChars(recType);
6261 for (uint64_t eltIndex = 1; eltIndex != numElts; ++eltIndex) {
6262 // Copy the last numEltEntries onto the end of the array, adjusting
6263 // each for the element size.
6264 for (size_t i = 0; i != numEltEntries; ++i) {
6265 auto firstEntry = IvarsInfo[oldEnd + i];
6266 IvarsInfo.push_back(IvarInfo(firstEntry.Offset + eltIndex * eltSize,
6267 firstEntry.SizeInWords));
6275 // Classify the element type.
6276 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), fieldType);
6278 // If it matches what we're looking for, add an entry.
6279 if ((ForStrongLayout && GCAttr == Qualifiers::Strong) ||
6280 (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
6281 assert(CGM.getContext().getTypeSizeInChars(fieldType) ==
6282 CGM.getPointerSize());
6283 IvarsInfo.push_back(IvarInfo(fieldOffset, numElts));
6291IvarLayoutBuilder::buildBitmap(CGObjCCommonMac &CGObjC,
6292 llvm::SmallVectorImpl<unsigned char> &buffer) {
6293 // The bitmap is a series of skip/scan instructions, aligned to word
6294 // boundaries. The skip is performed first.
6295 const unsigned char MaxNibble = 0xF;
6296 const unsigned char SkipMask = 0xF0, SkipShift = 4;
6297 const unsigned char ScanMask = 0x0F, ScanShift = 0;
6299 assert(!IvarsInfo.empty() && "generating bitmap
for no data
");
6301 // Sort the ivar info on byte position in case we encounterred a
6302 // union nested in the ivar list.
6304 // This isn't a stable sort, but our algorithm should handle it fine.
6305 llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end());
6307 assert(llvm::is_sorted(IvarsInfo));
6309 assert(IvarsInfo.back().Offset < InstanceEnd);
6311 assert(buffer.empty());
6313 // Skip the next N words.
6314 auto skip = [&](unsigned numWords) {
6315 assert(numWords > 0);
6317 // Try to merge into the previous byte. Since scans happen second, we
6318 // can't do this if it includes a scan.
6319 if (!buffer.empty() && !(buffer.back() & ScanMask)) {
6320 unsigned lastSkip = buffer.back() >> SkipShift;
6321 if (lastSkip < MaxNibble) {
6322 unsigned claimed = std::min(MaxNibble - lastSkip, numWords);
6323 numWords -= claimed;
6324 lastSkip += claimed;
6325 buffer.back() = (lastSkip << SkipShift);
6329 while (numWords >= MaxNibble) {
6330 buffer.push_back(MaxNibble << SkipShift);
6331 numWords -= MaxNibble;
6334 buffer.push_back(numWords << SkipShift);
6338 // Scan the next N words.
6339 auto scan = [&](unsigned numWords) {
6340 assert(numWords > 0);
6342 // Try to merge into the previous byte. Since scans happen second, we can
6343 // do this even if it includes a skip.
6344 if (!buffer.empty()) {
6345 unsigned lastScan = (buffer.back() & ScanMask) >> ScanShift;
6346 if (lastScan < MaxNibble) {
6347 unsigned claimed = std::min(MaxNibble - lastScan, numWords);
6348 numWords -= claimed;
6349 lastScan += claimed;
6350 buffer.back() = (buffer.back() & SkipMask) | (lastScan << ScanShift);
6354 while (numWords >= MaxNibble) {
6355 buffer.push_back(MaxNibble << ScanShift);
6356 numWords -= MaxNibble;
6359 buffer.push_back(numWords << ScanShift);
6363 // One past the end of the last scan.
6364 unsigned endOfLastScanInWords = 0;
6365 const CharUnits WordSize = CGM.getPointerSize();
6367 // Consider all the scan requests.
6368 for (auto &request : IvarsInfo) {
6369 CharUnits beginOfScan = request.Offset - InstanceBegin;
6371 // Ignore scan requests that don't start at an even multiple of the
6372 // word size. We can't encode them.
6373 if (!beginOfScan.isMultipleOf(WordSize))
6376 // Ignore scan requests that start before the instance start.
6377 // This assumes that scans never span that boundary. The boundary
6378 // isn't the true start of the ivars, because in the fragile-ARC case
6379 // it's rounded up to word alignment, but the test above should leave
6380 // us ignoring that possibility.
6381 if (beginOfScan.isNegative()) {
6382 assert(request.Offset + request.SizeInWords * WordSize <= InstanceBegin);
6386 unsigned beginOfScanInWords = beginOfScan / WordSize;
6387 unsigned endOfScanInWords = beginOfScanInWords + request.SizeInWords;
6389 // If the scan starts some number of words after the last one ended,
6391 if (beginOfScanInWords > endOfLastScanInWords) {
6392 skip(beginOfScanInWords - endOfLastScanInWords);
6394 // Otherwise, start scanning where the last left off.
6396 beginOfScanInWords = endOfLastScanInWords;
6398 // If that leaves us with nothing to scan, ignore this request.
6399 if (beginOfScanInWords >= endOfScanInWords)
6403 // Scan to the end of the request.
6404 assert(beginOfScanInWords < endOfScanInWords);
6405 scan(endOfScanInWords - beginOfScanInWords);
6406 endOfLastScanInWords = endOfScanInWords;
6410 return llvm::ConstantPointerNull::get(CGM.Int8PtrTy);
6412 // For GC layouts, emit a skip to the end of the allocation so that we
6413 // have precise information about the entire thing. This isn't useful
6414 // or necessary for the ARC-style layout strings.
6415 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
6416 unsigned lastOffsetInWords =
6417 (InstanceEnd - InstanceBegin + WordSize - CharUnits::One()) / WordSize;
6418 if (lastOffsetInWords > endOfLastScanInWords) {
6419 skip(lastOffsetInWords - endOfLastScanInWords);
6423 // Null terminate the string.
6424 buffer.push_back(0);
6426 return CGObjC.CreateCStringLiteral(reinterpret_cast<char *>(buffer.data()),
6427 ObjCLabelType::LayoutBitMap);
6447CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD,
6448 CharUnits beginOffset, CharUnits endOffset,
6449 bool ForStrongLayout, bool HasMRCWeakIvars) {
6450 // If this is MRC, and we're either building a strong layout or there
6451 // are no weak ivars, bail out early.
6452 llvm::Type *PtrTy = CGM.Int8PtrTy;
6453 if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
6454 !CGM.getLangOpts().ObjCAutoRefCount &&
6455 (ForStrongLayout || !HasMRCWeakIvars))
6456 return llvm::Constant::getNullValue(PtrTy);
6458 const ObjCInterfaceDecl *OI = OMD->getClassInterface();
6459 SmallVector<const ObjCIvarDecl *, 32> ivars;
6461 // GC layout strings include the complete object layout, possibly
6462 // inaccurately in the non-fragile ABI; the runtime knows how to fix this
6465 // ARC layout strings only include the class's ivars. In non-fragile
6466 // runtimes, that means starting at InstanceStart, rounded up to word
6467 // alignment. In fragile runtimes, there's no InstanceStart, so it means
6468 // starting at the offset of the first ivar, rounded up to word alignment.
6470 // MRC weak layout strings follow the ARC style.
6471 CharUnits baseOffset;
6472 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
6473 for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin(); IVD;
6474 IVD = IVD->getNextIvar())
6475 ivars.push_back(IVD);
6477 if (isNonFragileABI()) {
6478 baseOffset = beginOffset; // InstanceStart
6479 } else if (!ivars.empty()) {
6481 CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivars[0]));
6483 baseOffset = CharUnits::Zero();
6486 baseOffset = baseOffset.alignTo(CGM.getPointerAlign());
6488 CGM.getContext().DeepCollectObjCIvars(OI, true, ivars);
6490 baseOffset = CharUnits::Zero();
6494 return llvm::Constant::getNullValue(PtrTy);
6496 IvarLayoutBuilder builder(CGM, baseOffset, endOffset, ForStrongLayout);
6498 builder.visitAggregate(ivars.begin(), ivars.end(), CharUnits::Zero(),
6499 [&](const ObjCIvarDecl *ivar) -> CharUnits {
6500 return CharUnits::fromQuantity(
6501 ComputeIvarBaseOffset(CGM, OMD, ivar));
6504 if (!builder.hasBitmapData())
6505 return llvm::Constant::getNullValue(PtrTy);
6507 llvm::SmallVector<unsigned char, 4> buffer;
6508 llvm::Constant *C = builder.buildBitmap(*this, buffer);
6510 if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
6511 printf("\n%s ivar layout
for class '%s':
",
6512 ForStrongLayout ? "strong
" : "weak
",
6513 OMD->getClassInterface()->getName().str().c_str());
6514 builder.dump(buffer);
6519llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
6520 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
6521 // FIXME: Avoid std::string in "Sel.
getAsString()
"
6524 CreateCStringLiteral(Sel.getAsString(), ObjCLabelType::MethodVarName);
6528// FIXME: Merge into a single cstring creation function.
6529llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
6530 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
6533llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
6534 std::string TypeStr;
6535 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
6537 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
6539 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType);
6543llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D,
6545 std::string TypeStr =
6546 CGM.getContext().getObjCEncodingForMethodDecl(D, Extended);
6548 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
6550 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType);
6554// FIXME: Merge into a single cstring creation function.
6555llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
6556 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
6558 Entry = CreateCStringLiteral(Ident->getName(), ObjCLabelType::PropertyName);
6562// FIXME: Merge into a single cstring creation function.
6563// FIXME: This Decl should be more precise.
6565CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
6566 const Decl *Container) {
6567 std::string TypeStr =
6568 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container);
6569 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
6572void CGObjCMac::FinishModule() {
6575 // Emit the dummy bodies for any protocols which were referenced but
6577 for (auto &entry : Protocols) {
6578 llvm::GlobalVariable *global = entry.second;
6579 if (global->hasInitializer())
6582 ConstantInitBuilder builder(CGM);
6583 auto values = builder.beginStruct(ObjCTypes.ProtocolTy);
6584 values.addNullPointer(ObjCTypes.ProtocolExtensionPtrTy);
6585 values.add(GetClassName(entry.first->getName()));
6586 values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
6587 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy);
6588 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy);
6589 values.finishAndSetAsInitializer(global);
6590 CGM.addCompilerUsedGlobal(global);
6593 // Add assembler directives to add lazy undefined symbol references
6594 // for classes which are referenced but not defined. This is
6595 // important for correct linker interaction.
6597 // FIXME: It would be nice if we had an LLVM construct for this.
6598 if ((!LazySymbols.empty() || !DefinedSymbols.empty()) &&
6599 CGM.getTriple().isOSBinFormatMachO()) {
6600 SmallString<256> Asm;
6601 llvm::raw_svector_ostream OS(Asm);
6602 for (const auto *Sym : DefinedSymbols)
6603 OS << "\t.objc_class_name_
" << Sym->getName() << "=0\n
"
6604 << "\t.globl .objc_class_name_
" << Sym->getName() << "\n
";
6605 for (const auto *Sym : LazySymbols)
6606 OS << "\t.lazy_reference .objc_class_name_
" << Sym->getName() << "\n
";
6607 for (const auto &Category : DefinedCategoryNames)
6608 OS << "\t.objc_category_name_
" << Category << "=0\n
"
6609 << "\t.globl .objc_category_name_
" << Category << "\n
";
6611 CGM.getModule().appendModuleInlineAsm(OS.str());
6615CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
6616 : CGObjCCommonMac(cgm), ObjCTypes(cgm), ObjCEmptyCacheVar(nullptr),
6617 ObjCEmptyVtableVar(nullptr) {
6623ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
6624 : VMContext(cgm.getLLVMContext()), CGM(cgm) {
6625 CodeGen::CodeGenTypes &Types = CGM.getTypes();
6626 ASTContext &Ctx = CGM.getContext();
6627 unsigned ProgramAS = CGM.getDataLayout().getProgramAddressSpace();
6629 ShortTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.ShortTy));
6631 LongTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.LongTy));
6632 Int8PtrTy = CGM.Int8PtrTy;
6633 Int8PtrProgramASTy = llvm::PointerType::get(CGM.getLLVMContext(), ProgramAS);
6634 Int8PtrPtrTy = CGM.Int8PtrPtrTy;
6636 // arm64 targets use "int" ivar offset variables. All others,
6637 // including OS X x86_64 and Windows x86_64, use "long" ivar offsets.
6638 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::aarch64)
6639 IvarOffsetVarTy = IntTy;
6641 IvarOffsetVarTy = LongTy;
6643 ObjectPtrTy = cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCIdType()));
6644 PtrObjectPtrTy = llvm::PointerType::getUnqual(VMContext);
6646 cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCSelType()));
6648 // I'm not sure I like this. The implicit coordination is a bit
6649 // gross. We should solve this in a reasonable fashion because this
6650 // is a pretty common task (match some runtime data structure with
6651 // an LLVM data structure).
6653 // FIXME: This is leaked.
6654 // FIXME: Merge with rewriter code?
6656 // struct _objc_super {
6660 RecordDecl *RD = RecordDecl::Create(
6661 Ctx, TagTypeKind::Struct, Ctx.getTranslationUnitDecl(), SourceLocation(),
6662 SourceLocation(), &Ctx.Idents.get("_objc_super
"));
6663 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
6664 nullptr, Ctx.getObjCIdType(), nullptr, nullptr,
6665 false, ICIS_NoInit));
6666 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
6667 nullptr, Ctx.getObjCClassType(), nullptr,
6668 nullptr, false, ICIS_NoInit));
6669 RD->completeDefinition();
6671 SuperCTy = Ctx.getCanonicalTagType(RD);
6672 SuperPtrCTy = Ctx.getPointerType(SuperCTy);
6674 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
6675 SuperPtrTy = llvm::PointerType::getUnqual(VMContext);
6679 // char *attributes;
6681 PropertyTy = llvm::StructType::create("struct._prop_t
", Int8PtrTy, Int8PtrTy);
6683 // struct _prop_list_t {
6684 // uint32_t entsize; // sizeof(struct _prop_t)
6685 // uint32_t count_of_properties;
6686 // struct _prop_t prop_list[count_of_properties];
6688 PropertyListTy = llvm::StructType::create(
6689 "struct._prop_list_t
", IntTy, IntTy, llvm::ArrayType::get(PropertyTy, 0));
6690 // struct _prop_list_t *
6691 PropertyListPtrTy = llvm::PointerType::getUnqual(VMContext);
6693 // struct _objc_method {
6695 // char *method_type;
6698 MethodTy = llvm::StructType::create("struct._objc_method
", SelectorPtrTy,
6699 Int8PtrTy, Int8PtrProgramASTy);
6701 // struct _objc_cache *
6702 CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache
");
6703 CachePtrTy = llvm::PointerType::getUnqual(VMContext);
6706ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
6707 : ObjCCommonTypesHelper(cgm) {
6708 // struct _objc_method_description {
6712 MethodDescriptionTy = llvm::StructType::create(
6713 "struct._objc_method_description
", SelectorPtrTy, Int8PtrTy);
6715 // struct _objc_method_description_list {
6717 // struct _objc_method_description[1];
6719 MethodDescriptionListTy =
6720 llvm::StructType::create("struct._objc_method_description_list
", IntTy,
6721 llvm::ArrayType::get(MethodDescriptionTy, 0));
6723 // struct _objc_method_description_list *
6724 MethodDescriptionListPtrTy = llvm::PointerType::getUnqual(VMContext);
6726 // Protocol description structures
6728 // struct _objc_protocol_extension {
6729 // uint32_t size; // sizeof(struct _objc_protocol_extension)
6730 // struct _objc_method_description_list *optional_instance_methods;
6731 // struct _objc_method_description_list *optional_class_methods;
6732 // struct _objc_property_list *instance_properties;
6733 // const char ** extendedMethodTypes;
6734 // struct _objc_property_list *class_properties;
6736 ProtocolExtensionTy = llvm::StructType::create(
6737 "struct._objc_protocol_extension
", IntTy, MethodDescriptionListPtrTy,
6738 MethodDescriptionListPtrTy, PropertyListPtrTy, Int8PtrPtrTy,
6741 // struct _objc_protocol_extension *
6742 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(VMContext);
6744 // Handle construction of Protocol and ProtocolList types
6746 // struct _objc_protocol {
6747 // struct _objc_protocol_extension *isa;
6748 // char *protocol_name;
6749 // struct _objc_protocol **_objc_protocol_list;
6750 // struct _objc_method_description_list *instance_methods;
6751 // struct _objc_method_description_list *class_methods;
6753 ProtocolTy = llvm::StructType::create(
6754 {ProtocolExtensionPtrTy, Int8PtrTy,
6755 llvm::PointerType::getUnqual(VMContext), MethodDescriptionListPtrTy,
6756 MethodDescriptionListPtrTy},
6757 "struct._objc_protocol
");
6760 llvm::StructType::create({llvm::PointerType::getUnqual(VMContext), LongTy,
6761 llvm::ArrayType::get(ProtocolTy, 0)},
6762 "struct._objc_protocol_list
");
6764 // struct _objc_protocol_list *
6765 ProtocolListPtrTy = llvm::PointerType::getUnqual(VMContext);
6767 ProtocolPtrTy = llvm::PointerType::getUnqual(VMContext);
6769 // Class description structures
6771 // struct _objc_ivar {
6776 IvarTy = llvm::StructType::create("struct._objc_ivar
", Int8PtrTy, Int8PtrTy,
6779 // struct _objc_ivar_list *
6780 IvarListTy = llvm::StructType::create(VMContext, "struct._objc_ivar_list
");
6781 IvarListPtrTy = llvm::PointerType::getUnqual(VMContext);
6783 // struct _objc_method_list *
6785 llvm::StructType::create(VMContext, "struct._objc_method_list
");
6786 MethodListPtrTy = llvm::PointerType::getUnqual(VMContext);
6788 // struct _objc_class_extension *
6789 ClassExtensionTy = llvm::StructType::create(
6790 "struct._objc_class_extension
", IntTy, Int8PtrTy, PropertyListPtrTy);
6791 ClassExtensionPtrTy = llvm::PointerType::getUnqual(VMContext);
6793 // struct _objc_class {
6795 // Class super_class;
6799 // long instance_size;
6800 // struct _objc_ivar_list *ivars;
6801 // struct _objc_method_list *methods;
6802 // struct _objc_cache *cache;
6803 // struct _objc_protocol_list *protocols;
6804 // char *ivar_layout;
6805 // struct _objc_class_ext *ext;
6807 ClassTy = llvm::StructType::create(
6808 {llvm::PointerType::getUnqual(VMContext),
6809 llvm::PointerType::getUnqual(VMContext), Int8PtrTy, LongTy, LongTy,
6810 LongTy, IvarListPtrTy, MethodListPtrTy, CachePtrTy, ProtocolListPtrTy,
6811 Int8PtrTy, ClassExtensionPtrTy},
6812 "struct._objc_class
");
6814 ClassPtrTy = llvm::PointerType::getUnqual(VMContext);
6816 // struct _objc_category {
6817 // char *category_name;
6818 // char *class_name;
6819 // struct _objc_method_list *instance_method;
6820 // struct _objc_method_list *class_method;
6821 // struct _objc_protocol_list *protocols;
6822 // uint32_t size; // sizeof(struct _objc_category)
6823 // struct _objc_property_list *instance_properties;// category's @property
6824 // struct _objc_property_list *class_properties;
6826 CategoryTy = llvm::StructType::create(
6827 "struct._objc_category
", Int8PtrTy, Int8PtrTy, MethodListPtrTy,
6828 MethodListPtrTy, ProtocolListPtrTy, IntTy, PropertyListPtrTy,
6831 // Global metadata structures
6833 // struct _objc_symtab {
6834 // long sel_ref_cnt;
6836 // short cls_def_cnt;
6837 // short cat_def_cnt;
6838 // char *defs[cls_def_cnt + cat_def_cnt];
6840 SymtabTy = llvm::StructType::create("struct._objc_symtab
", LongTy,
6841 SelectorPtrTy, ShortTy, ShortTy,
6842 llvm::ArrayType::get(Int8PtrTy, 0));
6843 SymtabPtrTy = llvm::PointerType::getUnqual(VMContext);
6845 // struct _objc_module {
6847 // long size; // sizeof(struct _objc_module)
6849 // struct _objc_symtab* symtab;
6851 ModuleTy = llvm::StructType::create("struct._objc_module
", LongTy, LongTy,
6852 Int8PtrTy, SymtabPtrTy);
6854 // FIXME: This is the size of the setjmp buffer and should be target
6855 // specific. 18 is what's used on 32-bit X86.
6856 uint64_t SetJmpBufferSize = 18;
6859 llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4);
6861 ExceptionDataTy = llvm::StructType::create(
6862 "struct._objc_exception_data
",
6863 llvm::ArrayType::get(CGM.Int32Ty, SetJmpBufferSize), StackPtrTy);
6866ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(
6867 CodeGen::CodeGenModule &cgm)
6868 : ObjCCommonTypesHelper(cgm) {
6869 // struct _method_list_t {
6870 // uint32_t entsize; // sizeof(struct _objc_method)
6871 // uint32_t method_count;
6872 // struct _objc_method method_list[method_count];
6875 llvm::StructType::create("struct.__method_list_t
", IntTy, IntTy,
6876 llvm::ArrayType::get(MethodTy, 0));
6877 // struct method_list_t *
6878 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6880 // struct _protocol_t {
6882 // const char * const protocol_name;
6883 // const struct _protocol_list_t * protocol_list; // super protocols
6884 // const struct method_list_t * const instance_methods;
6885 // const struct method_list_t * const class_methods;
6886 // const struct method_list_t *optionalInstanceMethods;
6887 // const struct method_list_t *optionalClassMethods;
6888 // const struct _prop_list_t * properties;
6889 // const uint32_t size; // sizeof(struct _protocol_t)
6890 // const uint32_t flags; // = 0
6891 // const char ** extendedMethodTypes;
6892 // const char *demangledName;
6893 // const struct _prop_list_t * class_properties;
6896 ProtocolnfABITy = llvm::StructType::create(
6897 "struct._protocol_t
", ObjectPtrTy, Int8PtrTy,
6898 llvm::PointerType::getUnqual(VMContext), MethodListnfABIPtrTy,
6899 MethodListnfABIPtrTy, MethodListnfABIPtrTy, MethodListnfABIPtrTy,
6900 PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy, Int8PtrTy,
6903 // struct _protocol_t*
6904 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6906 // struct _protocol_list_t {
6907 // long protocol_count; // Note, this is 32/64 bit
6908 // struct _protocol_t *[protocol_count];
6910 ProtocolListnfABITy = llvm::StructType::create(
6911 {LongTy, llvm::ArrayType::get(ProtocolnfABIPtrTy, 0)},
6912 "struct._objc_protocol_list
");
6914 // struct _objc_protocol_list*
6915 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6918 // unsigned [long] int *offset; // pointer to ivar offset location
6921 // uint32_t alignment;
6924 IvarnfABITy = llvm::StructType::create(
6925 "struct._ivar_t
", llvm::PointerType::getUnqual(VMContext), Int8PtrTy,
6926 Int8PtrTy, IntTy, IntTy);
6928 // struct _ivar_list_t {
6929 // uint32 entsize; // sizeof(struct _ivar_t)
6931 // struct _iver_t list[count];
6934 llvm::StructType::create("struct._ivar_list_t
", IntTy, IntTy,
6935 llvm::ArrayType::get(IvarnfABITy, 0));
6937 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6939 // struct _class_ro_t {
6940 // uint32_t const flags;
6941 // uint32_t const instanceStart;
6942 // uint32_t const instanceSize;
6943 // uint32_t const reserved; // only when building for 64bit targets
6944 // const uint8_t * const ivarLayout;
6945 // const char *const name;
6946 // const struct _method_list_t * const baseMethods;
6947 // const struct _objc_protocol_list *const baseProtocols;
6948 // const struct _ivar_list_t *const ivars;
6949 // const uint8_t * const weakIvarLayout;
6950 // const struct _prop_list_t * const properties;
6953 // FIXME. Add 'reserved' field in 64bit abi mode!
6954 ClassRonfABITy = llvm::StructType::create(
6955 "struct._class_ro_t
", IntTy, IntTy, IntTy, Int8PtrTy, Int8PtrTy,
6956 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, IvarListnfABIPtrTy,
6957 Int8PtrTy, PropertyListPtrTy);
6959 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
6960 ImpnfABITy = CGM.DefaultPtrTy;
6962 // struct _class_t {
6963 // struct _class_t *isa;
6964 // struct _class_t * const superclass;
6967 // struct class_ro_t *ro;
6970 ClassnfABITy = llvm::StructType::create(
6971 {llvm::PointerType::getUnqual(VMContext),
6972 llvm::PointerType::getUnqual(VMContext), CachePtrTy,
6973 llvm::PointerType::getUnqual(VMContext),
6974 llvm::PointerType::getUnqual(VMContext)},
6977 // LLVM for struct _class_t *
6978 ClassnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6980 // struct _category_t {
6981 // const char * const name;
6982 // struct _class_t *const cls;
6983 // const struct _method_list_t * const instance_methods;
6984 // const struct _method_list_t * const class_methods;
6985 // const struct _protocol_list_t * const protocols;
6986 // const struct _prop_list_t * const properties;
6987 // const struct _prop_list_t * const class_properties;
6988 // const uint32_t size;
6990 CategorynfABITy = llvm::StructType::create(
6991 "struct._category_t
", Int8PtrTy, ClassnfABIPtrTy, MethodListnfABIPtrTy,
6992 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, PropertyListPtrTy,
6993 PropertyListPtrTy, IntTy);
6995 // New types for nonfragile abi messaging.
6996 CodeGen::CodeGenTypes &Types = CGM.getTypes();
6997 ASTContext &Ctx = CGM.getContext();
6999 // MessageRefTy - LLVM for:
7000 // struct _message_ref_t {
7005 // First the clang type for struct _message_ref_t
7006 RecordDecl *RD = RecordDecl::Create(
7007 Ctx, TagTypeKind::Struct, Ctx.getTranslationUnitDecl(), SourceLocation(),
7008 SourceLocation(), &Ctx.Idents.get("_message_ref_t
"));
7009 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
7010 nullptr, Ctx.VoidPtrTy, nullptr, nullptr, false,
7012 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
7013 nullptr, Ctx.getObjCSelType(), nullptr, nullptr,
7014 false, ICIS_NoInit));
7015 RD->completeDefinition();
7017 MessageRefCTy = Ctx.getCanonicalTagType(RD);
7018 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy);
7019 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy));
7021 // MessageRefPtrTy - LLVM for struct _message_ref_t*
7022 MessageRefPtrTy = llvm::PointerType::getUnqual(VMContext);
7024 // SuperMessageRefTy - LLVM for:
7025 // struct _super_message_ref_t {
7026 // SUPER_IMP messenger;
7029 SuperMessageRefTy = llvm::StructType::create("struct._super_message_ref_t
",
7030 ImpnfABITy, SelectorPtrTy);
7032 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
7033 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(VMContext);
7035 // struct objc_typeinfo {
7036 // const void** vtable; // objc_ehtype_vtable + 2
7037 // const char* name; // c++ typeinfo string
7040 EHTypeTy = llvm::StructType::create("struct._objc_typeinfo
",
7041 llvm::PointerType::getUnqual(VMContext),
7042 Int8PtrTy, ClassnfABIPtrTy);
7043 EHTypePtrTy = llvm::PointerType::getUnqual(VMContext);
7046llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
7047 FinishNonFragileABIModule();
7052void CGObjCNonFragileABIMac::AddModuleClassList(
7053 ArrayRef<llvm::GlobalValue *> Container, StringRef SymbolName,
7054 StringRef SectionName) {
7055 unsigned NumClasses = Container.size();
7060 SmallVector<llvm::Constant *, 8> Symbols(NumClasses);
7061 for (unsigned i = 0; i < NumClasses; i++)
7062 Symbols[i] = Container[i];
7064 llvm::Constant *Init = llvm::ConstantArray::get(
7065 llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Symbols.size()), Symbols);
7067 // Section name is obtained by calling GetSectionName, which returns
7068 // sections in the __DATA segment on MachO.
7069 assert((!CGM.getTriple().isOSBinFormatMachO() ||
7070 SectionName.starts_with("__DATA
")) &&
7071 "SectionName expected to start with __DATA on
MachO");
7072 llvm::GlobalVariable *GV = new llvm::GlobalVariable(
7073 CGM.getModule(), Init->getType(), false,
7074 llvm::GlobalValue::PrivateLinkage, Init, SymbolName);
7075 GV->setAlignment(CGM.getDataLayout().getABITypeAlign(Init->getType()));
7076 GV->setSection(SectionName);
7077 CGM.addCompilerUsedGlobal(GV);
7080void CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
7081 // nonfragile abi has no module definition.
7083 // Build list of all implemented class addresses in array
7084 // L_OBJC_LABEL_CLASS_$.
7086 for (unsigned i = 0, NumClasses = ImplementedClasses.size(); i < NumClasses;
7088 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
7090 if (ObjCImplementationDecl *IMP = ID->getImplementation())
7091 // We are implementing a weak imported interface. Give it external linkage
7092 if (ID->isWeakImported() && !IMP->isWeakImported()) {
7093 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
7094 DefinedMetaClasses[i]->setLinkage(
7095 llvm::GlobalVariable::ExternalLinkage);
7100 DefinedClasses, "OBJC_LABEL_CLASS_$
",
7101 GetSectionName("__objc_classlist
", "regular,no_dead_strip
"));
7104 DefinedNonLazyClasses, "OBJC_LABEL_NONLAZY_CLASS_$
",
7105 GetSectionName("__objc_nlclslist
", "regular,no_dead_strip
"));
7107 // Build list of all implemented category addresses in array
7108 // L_OBJC_LABEL_CATEGORY_$.
7109 AddModuleClassList(DefinedCategories, "OBJC_LABEL_CATEGORY_$
",
7110 GetSectionName("__objc_catlist
", "regular,no_dead_strip
"));
7112 DefinedStubCategories, "OBJC_LABEL_STUB_CATEGORY_$
",
7113 GetSectionName("__objc_catlist2
", "regular,no_dead_strip
"));
7115 DefinedNonLazyCategories, "OBJC_LABEL_NONLAZY_CATEGORY_$
",
7116 GetSectionName("__objc_nlcatlist
", "regular,no_dead_strip
"));
7125bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
7126 // At various points we've experimented with using vtable-based
7127 // dispatch for all methods.
7128 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
7129 case CodeGenOptions::Legacy:
7131 case CodeGenOptions::NonLegacy:
7133 case CodeGenOptions::Mixed:
7137 // If so, see whether this selector is in the white-list of things which must
7138 // use the new dispatch convention. We lazily build a dense set for this.
7139 if (VTableDispatchMethods.empty()) {
7140 VTableDispatchMethods.insert(GetNullarySelector("alloc
"));
7141 VTableDispatchMethods.insert(GetNullarySelector("class"));
7142 VTableDispatchMethods.insert(GetNullarySelector("self
"));
7143 VTableDispatchMethods.insert(GetNullarySelector("isFlipped
"));
7144 VTableDispatchMethods.insert(GetNullarySelector("length"));
7145 VTableDispatchMethods.insert(GetNullarySelector("count
"));
7147 // These are vtable-based if GC is disabled.
7148 // Optimistically use vtable dispatch for hybrid compiles.
7149 if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) {
7150 VTableDispatchMethods.insert(GetNullarySelector("retain
"));
7151 VTableDispatchMethods.insert(GetNullarySelector("release
"));
7152 VTableDispatchMethods.insert(GetNullarySelector("autorelease
"));
7155 VTableDispatchMethods.insert(GetUnarySelector("allocWithZone
"));
7156 VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass
"));
7157 VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector
"));
7158 VTableDispatchMethods.insert(GetUnarySelector("objectForKey
"));
7159 VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex
"));
7160 VTableDispatchMethods.insert(GetUnarySelector("isEqualToString
"));
7161 VTableDispatchMethods.insert(GetUnarySelector("isEqual
"));
7163 // These are vtable-based if GC is enabled.
7164 // Optimistically use vtable dispatch for hybrid compiles.
7165 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
7166 VTableDispatchMethods.insert(GetNullarySelector("hash
"));
7167 VTableDispatchMethods.insert(GetUnarySelector("addObject
"));
7169 // "countByEnumeratingWithState:objects:count
"
7170 const IdentifierInfo *KeyIdents[] = {
7171 &CGM.getContext().Idents.get("countByEnumeratingWithState
"),
7172 &CGM.getContext().Idents.get("objects
"),
7173 &CGM.getContext().Idents.get("count
")};
7174 VTableDispatchMethods.insert(
7175 CGM.getContext().Selectors.getSelector(3, KeyIdents));
7179 return VTableDispatchMethods.count(Sel);
7197llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassRoTInitializer(
7198 unsigned flags, unsigned InstanceStart, unsigned InstanceSize,
7199 const ObjCImplementationDecl *ID) {
7200 std::string ClassName = std::string(ID->getObjCRuntimeNameAsString());
7202 CharUnits beginInstance = CharUnits::fromQuantity(InstanceStart);
7203 CharUnits endInstance = CharUnits::fromQuantity(InstanceSize);
7205 bool hasMRCWeak = false;
7206 if (CGM.getLangOpts().ObjCAutoRefCount)
7207 flags |= NonFragileABI_Class_CompiledByARC;
7208 else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))
7209 flags |= NonFragileABI_Class_HasMRCWeakIvars;
7211 ConstantInitBuilder builder(CGM);
7212 auto values = builder.beginStruct(ObjCTypes.ClassRonfABITy);
7214 values.addInt(ObjCTypes.IntTy, flags);
7215 values.addInt(ObjCTypes.IntTy, InstanceStart);
7216 values.addInt(ObjCTypes.IntTy, InstanceSize);
7217 values.add((flags & NonFragileABI_Class_Meta)
7218 ? GetIvarLayoutName(nullptr, ObjCTypes)
7219 : BuildStrongIvarLayout(ID, beginInstance, endInstance));
7220 values.add(GetClassName(ID->getObjCRuntimeNameAsString()));
7222 // const struct _method_list_t * const baseMethods;
7223 SmallVector<const ObjCMethodDecl *, 16> methods;
7224 if (flags & NonFragileABI_Class_Meta) {
7225 for (const auto *MD : ID->class_methods())
7226 if (!MD->isDirectMethod())
7227 methods.push_back(MD);
7229 for (const auto *MD : ID->instance_methods())
7230 if (!MD->isDirectMethod())
7231 methods.push_back(MD);
7234 llvm::Constant *MethListPtr = emitMethodList(
7235 ID->getObjCRuntimeNameAsString(),
7236 (flags & NonFragileABI_Class_Meta) ? MethodListType::ClassMethods
7237 : MethodListType::InstanceMethods,
7240 const PointerAuthSchema &MethListSchema =
7241 CGM.getCodeGenOpts().PointerAuth.ObjCMethodListPointer;
7242 if (!MethListPtr->isNullValue())
7243 values.addSignedPointer(MethListPtr, MethListSchema, GlobalDecl(),
7246 values.add(MethListPtr);
7248 const ObjCInterfaceDecl *OID = ID->getClassInterface();
7249 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer
");
7250 values.add(EmitProtocolList("_OBJC_CLASS_PROTOCOLS_$_
" +
7251 OID->getObjCRuntimeNameAsString(),
7252 OID->all_referenced_protocol_begin(),
7253 OID->all_referenced_protocol_end()));
7255 if (flags & NonFragileABI_Class_Meta) {
7256 values.addNullPointer(ObjCTypes.IvarListnfABIPtrTy);
7257 values.add(GetIvarLayoutName(nullptr, ObjCTypes));
7258 values.add(EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_
" +
7259 ID->getObjCRuntimeNameAsString(),
7260 ID, ID->getClassInterface(), ObjCTypes, true));
7262 values.add(EmitIvarList(ID));
7263 values.add(BuildWeakIvarLayout(ID, beginInstance, endInstance, hasMRCWeak));
7264 values.add(EmitPropertyList("_OBJC_$_PROP_LIST_
" +
7265 ID->getObjCRuntimeNameAsString(),
7266 ID, ID->getClassInterface(), ObjCTypes, false));
7269 llvm::SmallString<64> roLabel;
7270 llvm::raw_svector_ostream(roLabel)
7271 << ((flags & NonFragileABI_Class_Meta) ? "_OBJC_METACLASS_RO_$_
"
7272 : "_OBJC_CLASS_RO_$_
")
7275 return finishAndCreateGlobal(values, roLabel, CGM);
7288llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassObject(
7289 const ObjCInterfaceDecl *CI, bool isMetaclass, llvm::Constant *IsAGV,
7290 llvm::Constant *SuperClassGV, llvm::Constant *ClassRoGV,
7291 bool HiddenVisibility) {
7292 ConstantInitBuilder builder(CGM);
7293 auto values = builder.beginStruct(ObjCTypes.ClassnfABITy);
7294 const PointerAuthOptions &PointerAuthOpts = CGM.getCodeGenOpts().PointerAuth;
7295 values.addSignedPointer(IsAGV, PointerAuthOpts.ObjCIsaPointers, GlobalDecl(),
7298 values.addSignedPointer(SuperClassGV, PointerAuthOpts.ObjCSuperPointers,
7299 GlobalDecl(), QualType());
7301 values.addNullPointer(ObjCTypes.ClassnfABIPtrTy);
7303 values.add(ObjCEmptyCacheVar);
7304 values.add(ObjCEmptyVtableVar);
7306 values.addSignedPointer(ClassRoGV, PointerAuthOpts.ObjCClassROPointers,
7307 GlobalDecl(), QualType());
7309 llvm::GlobalVariable *GV = cast<llvm::GlobalVariable>(
7310 GetClassGlobal(CI, isMetaclass, ForDefinition));
7311 values.finishAndSetAsInitializer(GV);
7313 if (CGM.getTriple().isOSBinFormatMachO())
7314 GV->setSection("__DATA, __objc_data
");
7315 GV->setAlignment(CGM.getDataLayout().getABITypeAlign(ObjCTypes.ClassnfABITy));
7316 if (!CGM.getTriple().isOSBinFormatCOFF())
7317 if (HiddenVisibility)
7318 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
7319 if (CGM.getCodeGenOpts().ObjCMsgSendClassSelectorStubs && !isMetaclass)
7320 CGM.addUsedGlobal(GV);
7324bool CGObjCNonFragileABIMac::ImplementationIsNonLazy(
7325 const ObjCImplDecl *OD) const {
7326 return OD->getClassMethod(GetNullarySelector("load
")) != nullptr ||
7327 OD->getClassInterface()->hasAttr<ObjCNonLazyClassAttr>() ||
7328 OD->hasAttr<ObjCNonLazyClassAttr>();
7331void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
7332 uint32_t &InstanceStart,
7333 uint32_t &InstanceSize) {
7334 const ASTRecordLayout &RL =
7335 CGM.getContext().getASTObjCInterfaceLayout(OID->getClassInterface());
7337 // InstanceSize is really instance end.
7338 InstanceSize = RL.getDataSize().getQuantity();
7340 // If there are no fields, the start is the same as the end.
7341 if (!RL.getFieldCount())
7342 InstanceStart = InstanceSize;
7344 InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth();
7347static llvm::GlobalValue::DLLStorageClassTypes getStorage(CodeGenModule &CGM,
7349 IdentifierInfo &II = CGM.getContext().Idents.get(Name);
7350 TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl();
7351 DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl);
7353 const VarDecl *VD = nullptr;
7354 for (const auto *Result : DC->lookup(&II))
7355 if ((VD = dyn_cast<VarDecl>(Result)))
7359 return llvm::GlobalValue::DLLImportStorageClass;
7360 if (VD->hasAttr<DLLExportAttr>())
7361 return llvm::GlobalValue::DLLExportStorageClass;
7362 if (VD->hasAttr<DLLImportAttr>())
7363 return llvm::GlobalValue::DLLImportStorageClass;
7364 return llvm::GlobalValue::DefaultStorageClass;
7367void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
7368 if (!ObjCEmptyCacheVar) {
7369 ObjCEmptyCacheVar = new llvm::GlobalVariable(
7370 CGM.getModule(), ObjCTypes.CacheTy, false,
7371 llvm::GlobalValue::ExternalLinkage, nullptr, "_objc_empty_cache
");
7372 if (CGM.getTriple().isOSBinFormatCOFF())
7373 ObjCEmptyCacheVar->setDLLStorageClass(
7374 getStorage(CGM, "_objc_empty_cache
"));
7376 // Only OS X with deployment version <10.9 use the empty vtable symbol
7377 const llvm::Triple &Triple = CGM.getTarget().getTriple();
7378 if (Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 9))
7379 ObjCEmptyVtableVar = new llvm::GlobalVariable(
7380 CGM.getModule(), ObjCTypes.ImpnfABITy, false,
7381 llvm::GlobalValue::ExternalLinkage, nullptr, "_objc_empty_vtable
");
7383 ObjCEmptyVtableVar = llvm::ConstantPointerNull::get(CGM.DefaultPtrTy);
7386 // FIXME: Is this correct (that meta class size is never computed)?
7387 uint32_t InstanceStart =
7388 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy);
7389 uint32_t InstanceSize = InstanceStart;
7390 uint32_t flags = NonFragileABI_Class_Meta;
7392 llvm::Constant *SuperClassGV, *IsAGV;
7394 const auto *CI = ID->getClassInterface();
7395 assert(CI && "CGObjCNonFragileABIMac::GenerateClass -
class is 0
");
7397 // Build the flags for the metaclass.
7398 bool classIsHidden = (CGM.getTriple().isOSBinFormatCOFF())
7399 ? !CI->hasAttr<DLLExportAttr>()
7400 : CI->getVisibility() == HiddenVisibility;
7402 flags |= NonFragileABI_Class_Hidden;
7404 // FIXME: why is this flag set on the metaclass?
7405 // ObjC metaclasses have no fields and don't really get constructed.
7406 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
7407 flags |= NonFragileABI_Class_HasCXXStructors;
7408 if (!ID->hasNonZeroConstructors())
7409 flags |= NonFragileABI_Class_HasCXXDestructorOnly;
7412 if (!CI->getSuperClass()) {
7414 flags |= NonFragileABI_Class_Root;
7416 SuperClassGV = GetClassGlobal(CI, /*metaclass*/ false, NotForDefinition);
7417 IsAGV = GetClassGlobal(CI, /*metaclass*/ true, NotForDefinition);
7419 // Has a root. Current class is not a root.
7420 const ObjCInterfaceDecl *Root = ID->getClassInterface();
7421 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
7424 const auto *Super = CI->getSuperClass();
7425 IsAGV = GetClassGlobal(Root, /*metaclass*/ true, NotForDefinition);
7426 SuperClassGV = GetClassGlobal(Super, /*metaclass*/ true, NotForDefinition);
7429 llvm::GlobalVariable *CLASS_RO_GV =
7430 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
7432 llvm::GlobalVariable *MetaTClass = BuildClassObject(
7433 CI, /*metaclass*/ true, IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden);
7434 CGM.setGVProperties(MetaTClass, CI);
7435 DefinedMetaClasses.push_back(MetaTClass);
7437 // Metadata for the class
7440 flags |= NonFragileABI_Class_Hidden;
7442 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
7443 flags |= NonFragileABI_Class_HasCXXStructors;
7445 // Set a flag to enable a runtime optimization when a class has
7446 // fields that require destruction but which don't require
7447 // anything except zero-initialization during construction. This
7448 // is most notably true of __strong and __weak types, but you can
7449 // also imagine there being C++ types with non-trivial default
7450 // constructors that merely set all fields to null.
7451 if (!ID->hasNonZeroConstructors())
7452 flags |= NonFragileABI_Class_HasCXXDestructorOnly;
7455 if (hasObjCExceptionAttribute(CGM.getContext(), CI))
7456 flags |= NonFragileABI_Class_Exception;
7458 if (!CI->getSuperClass()) {
7459 flags |= NonFragileABI_Class_Root;
7460 SuperClassGV = nullptr;
7462 // Has a root. Current class is not a root.
7463 const auto *Super = CI->getSuperClass();
7464 SuperClassGV = GetClassGlobal(Super, /*metaclass*/ false, NotForDefinition);
7467 GetClassSizeInfo(ID, InstanceStart, InstanceSize);
7469 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
7471 llvm::GlobalVariable *ClassMD =
7472 BuildClassObject(CI, /*metaclass*/ false, MetaTClass, SuperClassGV,
7473 CLASS_RO_GV, classIsHidden);
7474 CGM.setGVProperties(ClassMD, CI);
7475 DefinedClasses.push_back(ClassMD);
7476 ImplementedClasses.push_back(CI);
7478 // Determine if this class is also "non-lazy
".
7479 if (ImplementationIsNonLazy(ID))
7480 DefinedNonLazyClasses.push_back(ClassMD);
7482 // Force the definition of the EHType if necessary.
7483 if (flags & NonFragileABI_Class_Exception)
7484 (void)GetInterfaceEHType(CI, ForDefinition);
7485 // Make sure method definition entries are all clear for next implementation.
7486 MethodDefinitions.clear();
7498CGObjCNonFragileABIMac::GenerateProtocolRef(CodeGenFunction &CGF,
7499 const ObjCProtocolDecl *PD) {
7501 // This routine is called for @protocol only. So, we must build definition
7502 // of protocol's meta-data (not a reference to it!)
7503 assert(!PD->isNonRuntimeProtocol() &&
7504 "attempting to get a protocol ref to a
static protocol.
");
7505 llvm::Constant *Init = GetOrEmitProtocol(PD);
7507 std::string ProtocolName("_OBJC_PROTOCOL_REFERENCE_$_
");
7508 ProtocolName += PD->getObjCRuntimeNameAsString();
7510 CharUnits Align = CGF.getPointerAlign();
7512 llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);
7514 return CGF.Builder.CreateAlignedLoad(PTGV->getValueType(), PTGV, Align);
7515 PTGV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
7516 llvm::GlobalValue::WeakAnyLinkage, Init,
7519 GetSectionName("__objc_protorefs
", "coalesced,no_dead_strip
"));
7520 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
7521 PTGV->setAlignment(Align.getAsAlign());
7522 if (!CGM.getTriple().isOSBinFormatMachO())
7523 PTGV->setComdat(CGM.getModule().getOrInsertComdat(ProtocolName));
7524 CGM.addUsedGlobal(PTGV);
7525 return CGF.Builder.CreateAlignedLoad(PTGV->getValueType(), PTGV, Align);
7540void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
7541 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
7542 const char *Prefix = "_OBJC_$_CATEGORY_
";
7544 llvm::SmallString<64> ExtCatName(Prefix);
7545 ExtCatName += Interface->getObjCRuntimeNameAsString();
7546 ExtCatName += "_$_
";
7547 ExtCatName += OCD->getNameAsString();
7549 ConstantInitBuilder builder(CGM);
7550 auto values = builder.beginStruct(ObjCTypes.CategorynfABITy);
7551 values.add(GetClassName(OCD->getIdentifier()->getName()));
7552 // meta-class entry symbol
7553 values.add(GetClassGlobal(Interface, /*metaclass*/ false, NotForDefinition));
7554 std::string listName =
7555 (Interface->getObjCRuntimeNameAsString() + "_$_
" + OCD->getName()).str();
7557 SmallVector<const ObjCMethodDecl *, 16> instanceMethods;
7558 SmallVector<const ObjCMethodDecl *, 8> classMethods;
7559 for (const auto *MD : OCD->methods()) {
7560 if (MD->isDirectMethod())
7562 if (MD->isInstanceMethod()) {
7563 instanceMethods.push_back(MD);
7565 classMethods.push_back(MD);
7569 llvm::Constant *InstanceMethodList = emitMethodList(
7570 listName, MethodListType::CategoryInstanceMethods, instanceMethods);
7571 const PointerAuthSchema &MethListSchema =
7572 CGM.getCodeGenOpts().PointerAuth.ObjCMethodListPointer;
7573 if (!InstanceMethodList->isNullValue())
7574 values.addSignedPointer(InstanceMethodList, MethListSchema, GlobalDecl(),
7577 values.add(InstanceMethodList);
7579 llvm::Constant *ClassMethodList = emitMethodList(
7580 listName, MethodListType::CategoryClassMethods, classMethods);
7581 if (!ClassMethodList->isNullValue())
7582 values.addSignedPointer(ClassMethodList, MethListSchema, GlobalDecl(),
7585 values.add(ClassMethodList);
7587 // Keep track of whether we have actual metadata to emit.
7588 bool isEmptyCategory =
7589 InstanceMethodList->isNullValue() && ClassMethodList->isNullValue();
7591 const ObjCCategoryDecl *Category =
7592 Interface->FindCategoryDeclaration(OCD->getIdentifier());
7594 SmallString<256> ExtName;
7595 llvm::raw_svector_ostream(ExtName)
7596 << Interface->getObjCRuntimeNameAsString() << "_$_
" << OCD->getName();
7598 EmitProtocolList("_OBJC_CATEGORY_PROTOCOLS_$_
" +
7599 Interface->getObjCRuntimeNameAsString() + "_$_
" +
7600 Category->getName(),
7601 Category->protocol_begin(), Category->protocol_end());
7602 auto propertyList = EmitPropertyList("_OBJC_$_PROP_LIST_
" + ExtName.str(),
7603 OCD, Category, ObjCTypes, false);
7604 auto classPropertyList =
7605 EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_
" + ExtName.str(), OCD,
7606 Category, ObjCTypes, true);
7607 values.add(protocolList);
7608 values.add(propertyList);
7609 values.add(classPropertyList);
7610 isEmptyCategory &= protocolList->isNullValue() &&
7611 propertyList->isNullValue() &&
7612 classPropertyList->isNullValue();
7614 values.addNullPointer(ObjCTypes.ProtocolListnfABIPtrTy);
7615 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
7616 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
7619 if (isEmptyCategory) {
7620 // Empty category, don't emit any metadata.
7622 MethodDefinitions.clear();
7627 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.CategorynfABITy);
7628 values.addInt(ObjCTypes.IntTy, Size);
7630 llvm::GlobalVariable *GCATV =
7631 finishAndCreateGlobal(values, ExtCatName.str(), CGM);
7632 CGM.addCompilerUsedGlobal(GCATV);
7633 if (Interface->hasAttr<ObjCClassStubAttr>())
7634 DefinedStubCategories.push_back(GCATV);
7636 DefinedCategories.push_back(GCATV);
7638 // Determine if this category is also "non-lazy
".
7639 if (ImplementationIsNonLazy(OCD))
7640 DefinedNonLazyCategories.push_back(GCATV);
7641 // method definition entries must be clear for next implementation.
7642 MethodDefinitions.clear();
7654void CGObjCNonFragileABIMac::emitMethodConstant(ConstantArrayBuilder &builder,
7655 const ObjCMethodDecl *MD,
7657 auto method = builder.beginStruct(ObjCTypes.MethodTy);
7658 method.add(GetMethodVarName(MD->getSelector()));
7659 method.add(GetMethodVarType(MD));
7662 // Protocol methods have no implementation. So, this entry is always NULL.
7663 method.addNullPointer(ObjCTypes.Int8PtrProgramASTy);
7665 llvm::Function *fn = GetMethodDefinition(MD);
7666 assert(fn && "no definition
for method?
");
7667 if (const PointerAuthSchema &Schema =
7668 CGM.getCodeGenOpts().PointerAuth.ObjCMethodListFunctionPointers) {
7669 llvm::Constant *Bitcast =
7670 llvm::ConstantExpr::getBitCast(fn, ObjCTypes.Int8PtrProgramASTy);
7671 method.addSignedPointer(Bitcast, Schema, GlobalDecl(), QualType());
7676 method.finishAndAddTo(builder);
7687llvm::Constant *CGObjCNonFragileABIMac::emitMethodList(
7688 Twine name, MethodListType kind, ArrayRef<const ObjCMethodDecl *> methods) {
7689 // Return null for empty list.
7690 if (methods.empty())
7691 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
7696 case MethodListType::CategoryInstanceMethods:
7697 prefix = "_OBJC_$_CATEGORY_INSTANCE_METHODS_
";
7698 forProtocol = false;
7700 case MethodListType::CategoryClassMethods:
7701 prefix = "_OBJC_$_CATEGORY_CLASS_METHODS_
";
7702 forProtocol = false;
7704 case MethodListType::InstanceMethods:
7705 prefix = "_OBJC_$_INSTANCE_METHODS_
";
7706 forProtocol = false;
7708 case MethodListType::ClassMethods:
7709 prefix = "_OBJC_$_CLASS_METHODS_
";
7710 forProtocol = false;
7713 case MethodListType::ProtocolInstanceMethods:
7714 prefix = "_OBJC_$_PROTOCOL_INSTANCE_METHODS_
";
7717 case MethodListType::ProtocolClassMethods:
7718 prefix = "_OBJC_$_PROTOCOL_CLASS_METHODS_
";
7721 case MethodListType::OptionalProtocolInstanceMethods:
7722 prefix = "_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_
";
7725 case MethodListType::OptionalProtocolClassMethods:
7726 prefix = "_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_
";
7731 ConstantInitBuilder builder(CGM);
7732 auto values = builder.beginStruct();
7734 // sizeof(struct _objc_method)
7735 unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.MethodTy);
7736 values.addInt(ObjCTypes.IntTy, Size);
7738 values.addInt(ObjCTypes.IntTy, methods.size());
7739 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
7740 for (auto MD : methods)
7741 emitMethodConstant(methodArray, MD, forProtocol);
7742 methodArray.finishAndAddTo(values);
7744 llvm::GlobalVariable *GV = finishAndCreateGlobal(values, prefix + name, CGM);
7745 CGM.addCompilerUsedGlobal(GV);
7751llvm::GlobalVariable *
7752CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
7753 const ObjCIvarDecl *Ivar) {
7754 const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
7755 llvm::SmallString<64> Name("OBJC_IVAR_$_
");
7756 Name += Container->getObjCRuntimeNameAsString();
7758 Name += Ivar->getName();
7759 llvm::GlobalVariable *IvarOffsetGV = CGM.getModule().getGlobalVariable(Name);
7760 if (!IvarOffsetGV) {
7761 IvarOffsetGV = new llvm::GlobalVariable(
7762 CGM.getModule(), ObjCTypes.IvarOffsetVarTy, false,
7763 llvm::GlobalValue::ExternalLinkage, nullptr, Name.str());
7764 if (CGM.getTriple().isOSBinFormatCOFF()) {
7765 bool IsPrivateOrPackage =
7766 Ivar->getAccessControl() == ObjCIvarDecl::Private ||
7767 Ivar->getAccessControl() == ObjCIvarDecl::Package;
7769 const ObjCInterfaceDecl *ContainingID = Ivar->getContainingInterface();
7771 if (ContainingID->hasAttr<DLLImportAttr>())
7772 IvarOffsetGV->setDLLStorageClass(
7773 llvm::GlobalValue::DLLImportStorageClass);
7774 else if (ContainingID->hasAttr<DLLExportAttr>() && !IsPrivateOrPackage)
7775 IvarOffsetGV->setDLLStorageClass(
7776 llvm::GlobalValue::DLLExportStorageClass);
7779 return IvarOffsetGV;
7783CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
7784 const ObjCIvarDecl *Ivar,
7785 unsigned long int Offset) {
7786 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
7787 IvarOffsetGV->setInitializer(
7788 llvm::ConstantInt::get(ObjCTypes.IvarOffsetVarTy, Offset));
7789 IvarOffsetGV->setAlignment(
7790 CGM.getDataLayout().getABITypeAlign(ObjCTypes.IvarOffsetVarTy));
7792 if (!CGM.getTriple().isOSBinFormatCOFF()) {
7793 // FIXME: This matches gcc, but shouldn't the visibility be set on the use
7794 // as well (i.e., in ObjCIvarOffsetVariable).
7795 if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
7796 Ivar->getAccessControl() == ObjCIvarDecl::Package ||
7797 ID->getVisibility() == HiddenVisibility)
7798 IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
7800 IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility);
7803 // If ID's layout is known, then make the global constant. This serves as a
7804 // useful assertion: we'll never use this variable to calculate ivar offsets,
7805 // so if the runtime tries to patch it then we should crash.
7806 if (isClassLayoutKnownStatically(ID))
7807 IvarOffsetGV->setConstant(true);
7809 if (CGM.getTriple().isOSBinFormatMachO())
7810 IvarOffsetGV->setSection("__DATA, __objc_ivar
");
7811 return IvarOffsetGV;
7832CGObjCNonFragileABIMac::EmitIvarList(const ObjCImplementationDecl *ID) {
7834 ConstantInitBuilder builder(CGM);
7835 auto ivarList = builder.beginStruct();
7836 ivarList.addInt(ObjCTypes.IntTy,
7837 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.IvarnfABITy));
7838 auto ivarCountSlot = ivarList.addPlaceholder();
7839 auto ivars = ivarList.beginArray(ObjCTypes.IvarnfABITy);
7841 const ObjCInterfaceDecl *OID = ID->getClassInterface();
7842 assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface
");
7844 // FIXME. Consolidate this with similar code in GenerateClass.
7846 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin(); IVD;
7847 IVD = IVD->getNextIvar()) {
7848 // Ignore unnamed bit-fields.
7849 if (!IVD->getDeclName())
7852 auto ivar = ivars.beginStruct(ObjCTypes.IvarnfABITy);
7853 ivar.add(EmitIvarOffsetVar(ID->getClassInterface(), IVD,
7854 ComputeIvarBaseOffset(CGM, ID, IVD)));
7855 ivar.add(GetMethodVarName(IVD->getIdentifier()));
7856 ivar.add(GetMethodVarType(IVD));
7857 llvm::Type *FieldTy = CGM.getTypes().ConvertTypeForMem(IVD->getType());
7858 unsigned Size = CGM.getDataLayout().getTypeAllocSize(FieldTy);
7860 CGM.getContext().getPreferredTypeAlign(IVD->getType().getTypePtr()) >>
7862 Align = llvm::Log2_32(Align);
7863 ivar.addInt(ObjCTypes.IntTy, Align);
7864 // NOTE. Size of a bitfield does not match gcc's, because of the
7865 // way bitfields are treated special in each. But I am told that
7866 // 'size' for bitfield ivars is ignored by the runtime so it does
7867 // not matter. If it matters, there is enough info to get the
7869 ivar.addInt(ObjCTypes.IntTy, Size);
7870 ivar.finishAndAddTo(ivars);
7872 // Return null for empty list.
7873 if (ivars.empty()) {
7876 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
7879 auto ivarCount = ivars.size();
7880 ivars.finishAndAddTo(ivarList);
7881 ivarList.fillPlaceholderWithInt(ivarCountSlot, ObjCTypes.IntTy, ivarCount);
7883 const char *Prefix = "_OBJC_$_INSTANCE_VARIABLES_
";
7884 llvm::GlobalVariable *GV = finishAndCreateGlobal(
7885 ivarList, Prefix + OID->getObjCRuntimeNameAsString(), CGM);
7886 CGM.addCompilerUsedGlobal(GV);
7891CGObjCNonFragileABIMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {
7892 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
7894 assert(!PD->isNonRuntimeProtocol() &&
7895 "attempting to GetOrEmit a non-runtime protocol
");
7897 // We use the initializer as a marker of whether this is a forward
7898 // reference or not. At module finalization we add the empty
7899 // contents for protocols which were referenced but never defined.
7900 llvm::SmallString<64> Protocol;
7901 llvm::raw_svector_ostream(Protocol)
7902 << "_OBJC_PROTOCOL_$_
" << PD->getObjCRuntimeNameAsString();
7904 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
7905 false, llvm::GlobalValue::ExternalLinkage,
7907 if (!CGM.getTriple().isOSBinFormatMachO())
7908 Entry->setComdat(CGM.getModule().getOrInsertComdat(Protocol));
7935CGObjCNonFragileABIMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
7936 llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
7938 // Early exit if a defining object has already been generated.
7939 if (Entry && Entry->hasInitializer())
7942 // Use the protocol definition, if there is one.
7943 assert(PD->hasDefinition() &&
7944 "emitting protocol metadata without definition
");
7945 PD = PD->getDefinition();
7947 auto methodLists = ProtocolMethodLists::get(PD);
7949 ConstantInitBuilder builder(CGM);
7950 auto values = builder.beginStruct(ObjCTypes.ProtocolnfABITy);
7953 values.addNullPointer(ObjCTypes.ObjectPtrTy);
7954 values.add(GetClassName(PD->getObjCRuntimeNameAsString()));
7955 values.add(EmitProtocolList("_OBJC_$_PROTOCOL_REFS_
" +
7956 PD->getObjCRuntimeNameAsString(),
7957 PD->protocol_begin(), PD->protocol_end()));
7958 values.add(methodLists.emitMethodList(
7959 this, PD, ProtocolMethodLists::RequiredInstanceMethods));
7960 values.add(methodLists.emitMethodList(
7961 this, PD, ProtocolMethodLists::RequiredClassMethods));
7962 values.add(methodLists.emitMethodList(
7963 this, PD, ProtocolMethodLists::OptionalInstanceMethods));
7964 values.add(methodLists.emitMethodList(
7965 this, PD, ProtocolMethodLists::OptionalClassMethods));
7967 EmitPropertyList("_OBJC_$_PROP_LIST_
" + PD->getObjCRuntimeNameAsString(),
7968 nullptr, PD, ObjCTypes, false));
7970 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
7971 values.addInt(ObjCTypes.IntTy, Size);
7972 values.addInt(ObjCTypes.IntTy, 0);
7973 values.add(EmitProtocolMethodTypes(
7974 "_OBJC_$_PROTOCOL_METHOD_TYPES_
" + PD->getObjCRuntimeNameAsString(),
7975 methodLists.emitExtendedTypesArray(this), ObjCTypes));
7977 // const char *demangledName;
7978 values.addNullPointer(ObjCTypes.Int8PtrTy);
7980 values.add(EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_
" +
7981 PD->getObjCRuntimeNameAsString(),
7982 nullptr, PD, ObjCTypes, true));
7985 // Already created, fix the linkage and update the initializer.
7986 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
7987 values.finishAndSetAsInitializer(Entry);
7989 llvm::SmallString<64> symbolName;
7990 llvm::raw_svector_ostream(symbolName)
7991 << "_OBJC_PROTOCOL_$_
" << PD->getObjCRuntimeNameAsString();
7993 Entry = values.finishAndCreateGlobal(symbolName, CGM.getPointerAlign(),
7995 llvm::GlobalValue::WeakAnyLinkage);
7996 if (!CGM.getTriple().isOSBinFormatMachO())
7997 Entry->setComdat(CGM.getModule().getOrInsertComdat(symbolName));
7999 Protocols[PD->getIdentifier()] = Entry;
8001 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
8002 CGM.addUsedGlobal(Entry);
8004 // Use this protocol meta-data to build protocol list table in section
8005 // __DATA, __objc_protolist
8006 llvm::SmallString<64> ProtocolRef;
8007 llvm::raw_svector_ostream(ProtocolRef)
8008 << "_OBJC_LABEL_PROTOCOL_$_
" << PD->getObjCRuntimeNameAsString();
8010 llvm::GlobalVariable *PTGV = new llvm::GlobalVariable(
8011 CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy, false,
8012 llvm::GlobalValue::WeakAnyLinkage, Entry, ProtocolRef);
8013 if (!CGM.getTriple().isOSBinFormatMachO())
8014 PTGV->setComdat(CGM.getModule().getOrInsertComdat(ProtocolRef));
8016 CGM.getDataLayout().getABITypeAlign(ObjCTypes.ProtocolnfABIPtrTy));
8018 GetSectionName("__objc_protolist
", "coalesced,no_dead_strip
"));
8019 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
8020 CGM.addUsedGlobal(PTGV);
8032llvm::Constant *CGObjCNonFragileABIMac::EmitProtocolList(
8033 Twine Name, ObjCProtocolDecl::protocol_iterator begin,
8034 ObjCProtocolDecl::protocol_iterator end) {
8035 // Just return null for empty protocol lists
8036 auto Protocols = GetRuntimeProtocolList(begin, end);
8037 if (Protocols.empty())
8038 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
8040 SmallVector<llvm::Constant *, 16> ProtocolRefs;
8041 ProtocolRefs.reserve(Protocols.size());
8043 for (const auto *PD : Protocols)
8044 ProtocolRefs.push_back(GetProtocolRef(PD));
8046 // If all of the protocols in the protocol list are objc_non_runtime_protocol
8048 if (ProtocolRefs.size() == 0)
8049 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
8051 // FIXME: We shouldn't need to do this lookup here, should we?
8052 SmallString<256> TmpName;
8053 Name.toVector(TmpName);
8054 llvm::GlobalVariable *GV =
8055 CGM.getModule().getGlobalVariable(TmpName.str(), true);
8059 ConstantInitBuilder builder(CGM);
8060 auto values = builder.beginStruct();
8061 auto countSlot = values.addPlaceholder();
8063 // A null-terminated array of protocols.
8064 auto array = values.beginArray(ObjCTypes.ProtocolnfABIPtrTy);
8065 for (auto const &proto : ProtocolRefs)
8067 auto count = array.size();
8068 array.addNullPointer(ObjCTypes.ProtocolnfABIPtrTy);
8070 array.finishAndAddTo(values);
8071 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
8073 GV = finishAndCreateGlobal(values, Name, CGM);
8074 CGM.addCompilerUsedGlobal(GV);
8084LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
8085 CodeGen::CodeGenFunction &CGF, QualType ObjectTy, llvm::Value *BaseValue,
8086 const ObjCIvarDecl *Ivar, unsigned CVRQualifiers) {
8087 ObjCInterfaceDecl *ID = ObjectTy->castAs<ObjCObjectType>()->getInterface();
8088 llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
8089 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
8094CGObjCNonFragileABIMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
8095 const ObjCInterfaceDecl *Interface,
8096 const ObjCIvarDecl *Ivar) {
8097 llvm::Value *IvarOffsetValue;
8098 if (isClassLayoutKnownStatically(Interface)) {
8099 IvarOffsetValue = llvm::ConstantInt::get(
8100 ObjCTypes.IvarOffsetVarTy,
8101 ComputeIvarBaseOffset(CGM, Interface->getImplementation(), Ivar));
8103 llvm::GlobalVariable *GV = ObjCIvarOffsetVariable(Interface, Ivar);
8104 IvarOffsetValue = CGF.Builder.CreateAlignedLoad(GV->getValueType(), GV,
8105 CGF.getSizeAlign(), "ivar
");
8106 if (IsIvarOffsetKnownIdempotent(CGF, Ivar))
8107 cast<llvm::LoadInst>(IvarOffsetValue)
8108 ->setMetadata(llvm::LLVMContext::MD_invariant_load,
8109 llvm::MDNode::get(VMContext, {}));
8112 // This could be 32bit int or 64bit integer depending on the architecture.
8113 // Cast it to 64bit integer value, if it is a 32bit integer ivar offset value
8114 // as this is what caller always expects.
8115 if (ObjCTypes.IvarOffsetVarTy == ObjCTypes.IntTy)
8116 IvarOffsetValue = CGF.Builder.CreateIntCast(
8117 IvarOffsetValue, ObjCTypes.LongTy, true, "ivar.conv
");
8118 return IvarOffsetValue;
8121static void appendSelectorForMessageRefTable(std::string &buffer,
8122 Selector selector) {
8123 if (selector.isUnarySelector()) {
8124 buffer += selector.getNameForSlot(0);
8128 for (unsigned i = 0, e = selector.getNumArgs(); i != e; ++i) {
8129 buffer += selector.getNameForSlot(i);
8144RValue CGObjCNonFragileABIMac::EmitVTableMessageSend(
8145 CodeGenFunction &CGF, ReturnValueSlot returnSlot, QualType resultType,
8146 Selector selector, llvm::Value *arg0, QualType arg0Type, bool isSuper,
8147 const CallArgList &formalArgs, const ObjCMethodDecl *method) {
8148 // Compute the actual arguments.
8151 // First argument: the receiver / super-call structure.
8153 arg0 = CGF.Builder.CreateBitCast(arg0, ObjCTypes.ObjectPtrTy);
8154 args.add(RValue::get(arg0), arg0Type);
8156 // Second argument: a pointer to the message ref structure. Leave
8157 // the actual argument value blank for now.
8158 args.add(RValue::get(nullptr), ObjCTypes.MessageRefCPtrTy);
8160 llvm::append_range(args, formalArgs);
8162 MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);
8164 NullReturnState nullReturn;
8166 // Find the function to call and the mangled name for the message
8167 // ref structure. Using a different mangled name wouldn't actually
8168 // be a problem; it would just be a waste.
8170 // The runtime currently never uses vtable dispatch for anything
8171 // except normal, non-super message-sends.
8172 // FIXME: don't use this for that.
8173 llvm::FunctionCallee fn = nullptr;
8174 std::string messageRefName("_
");
8175 if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
8177 fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
8178 messageRefName += "objc_msgSendSuper2_stret_fixup
";
8180 nullReturn.init(CGF, arg0);
8181 fn = ObjCTypes.getMessageSendStretFixupFn();
8182 messageRefName += "objc_msgSend_stret_fixup
";
8184 } else if (!isSuper && CGM.ReturnTypeUsesFPRet(resultType)) {
8185 fn = ObjCTypes.getMessageSendFpretFixupFn();
8186 messageRefName += "objc_msgSend_fpret_fixup
";
8189 fn = ObjCTypes.getMessageSendSuper2FixupFn();
8190 messageRefName += "objc_msgSendSuper2_fixup
";
8192 fn = ObjCTypes.getMessageSendFixupFn();
8193 messageRefName += "objc_msgSend_fixup
";
8196 assert(fn && "CGObjCNonFragileABIMac::EmitMessageSend
");
8197 messageRefName += '_';
8199 // Append the selector name, except use underscores anywhere we
8200 // would have used colons.
8201 appendSelectorForMessageRefTable(messageRefName, selector);
8203 llvm::GlobalVariable *messageRef =
8204 CGM.getModule().getGlobalVariable(messageRefName);
8206 // Build the message ref structure.
8207 ConstantInitBuilder builder(CGM);
8208 auto values = builder.beginStruct();
8209 values.add(cast<llvm::Constant>(fn.getCallee()));
8210 values.add(GetMethodVarName(selector));
8211 messageRef = values.finishAndCreateGlobal(
8212 messageRefName, CharUnits::fromQuantity(16),
8213 /*constant*/ false, llvm::GlobalValue::WeakAnyLinkage);
8214 messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility);
8215 messageRef->setSection(GetSectionName("__objc_msgrefs
", "coalesced
"));
8218 bool requiresnullCheck = false;
8219 if (CGM.getLangOpts().ObjCAutoRefCount && method)
8220 for (const auto *ParamDecl : method->parameters()) {
8221 if (ParamDecl->isDestroyedInCallee()) {
8222 if (!nullReturn.NullBB)
8223 nullReturn.init(CGF, arg0);
8224 requiresnullCheck = true;
8230 Address(CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy),
8231 ObjCTypes.MessageRefTy, CGF.getPointerAlign());
8233 // Update the message ref argument.
8234 args[1].setRValue(RValue::get(mref, CGF));
8236 // Load the function to call from the message ref table.
8237 Address calleeAddr = CGF.Builder.CreateStructGEP(mref, 0);
8238 llvm::Value *calleePtr = CGF.Builder.CreateLoad(calleeAddr, "msgSend_fn
");
8240 calleePtr = CGF.Builder.CreateBitCast(calleePtr, MSI.MessengerType);
8241 CGCallee callee(CGCalleeInfo(), calleePtr);
8243 RValue result = CGF.EmitCall(MSI.CallInfo, callee, returnSlot, args);
8244 return nullReturn.complete(CGF, returnSlot, result, resultType, formalArgs,
8245 requiresnullCheck ? method : nullptr);
8249CodeGen::RValue CGObjCNonFragileABIMac::GenerateMessageSend(
8250 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
8251 Selector Sel, llvm::Value *Receiver, const CallArgList &CallArgs,
8252 const ObjCInterfaceDecl *Class, const ObjCMethodDecl *Method) {
8253 return isVTableDispatchedSelector(Sel)
8254 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel, Receiver,
8255 CGF.getContext().getObjCIdType(), false,
8257 : EmitMessageSend(CGF, Return, ResultType, Sel, Receiver,
8258 CGF.getContext().getObjCIdType(), false,
8259 CallArgs, Method, Class, ObjCTypes);
8263CGObjCNonFragileABIMac::GetClassGlobal(const ObjCInterfaceDecl *ID,
8265 ForDefinition_t isForDefinition) {
8267 (metaclass ? getMetaclassSymbolPrefix() : getClassSymbolPrefix());
8268 return GetClassGlobal((prefix + ID->getObjCRuntimeNameAsString()).str(),
8269 isForDefinition, ID->isWeakImported(),
8271 CGM.getTriple().isOSBinFormatCOFF() &&
8272 ID->hasAttr<DLLImportAttr>());
8276CGObjCNonFragileABIMac::GetClassGlobal(StringRef Name,
8277 ForDefinition_t IsForDefinition,
8278 bool Weak, bool DLLImport) {
8279 llvm::GlobalValue::LinkageTypes L =
8280 Weak ? llvm::GlobalValue::ExternalWeakLinkage
8281 : llvm::GlobalValue::ExternalLinkage;
8283 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
8284 if (!GV || GV->getValueType() != ObjCTypes.ClassnfABITy) {
8285 auto *NewGV = new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, L,
8289 NewGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
8292 GV->replaceAllUsesWith(NewGV);
8293 GV->eraseFromParent();
8296 CGM.getModule().insertGlobalVariable(GV);
8299 assert(GV->getLinkage() == L);
8304CGObjCNonFragileABIMac::GetClassGlobalForClassRef(const ObjCInterfaceDecl *ID) {
8305 llvm::Constant *ClassGV =
8306 GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition);
8308 if (!ID->hasAttr<ObjCClassStubAttr>())
8311 ClassGV = llvm::ConstantExpr::getPointerCast(ClassGV, ObjCTypes.Int8PtrTy);
8313 // Stub classes are pointer-aligned. Classrefs pointing at stub classes
8314 // must set the least significant bit set to 1.
8315 auto *Idx = llvm::ConstantInt::get(CGM.Int32Ty, 1);
8316 return llvm::ConstantExpr::getPtrAdd(ClassGV, Idx);
8320CGObjCNonFragileABIMac::EmitLoadOfClassRef(CodeGenFunction &CGF,
8321 const ObjCInterfaceDecl *ID,
8322 llvm::GlobalVariable *Entry) {
8323 if (ID && ID->hasAttr<ObjCClassStubAttr>()) {
8324 // Classrefs pointing at Objective-C stub classes must be loaded by calling
8325 // a special runtime function.
8326 return CGF.EmitRuntimeCall(ObjCTypes.getLoadClassrefFn(), Entry,
8327 "load_classref_result
");
8330 CharUnits Align = CGF.getPointerAlign();
8331 return CGF.Builder.CreateAlignedLoad(Entry->getValueType(), Entry, Align);
8334llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(
8335 CodeGenFunction &CGF, IdentifierInfo *II, const ObjCInterfaceDecl *ID) {
8336 llvm::GlobalVariable *&Entry = ClassReferences[II];
8339 llvm::Constant *ClassGV;
8341 ClassGV = GetClassGlobalForClassRef(ID);
8343 ClassGV = GetClassGlobal((getClassSymbolPrefix() + II->getName()).str(),
8345 assert(ClassGV->getType() == ObjCTypes.ClassnfABIPtrTy &&
8346 "classref was emitted with the wrong
type?
");
8349 std::string SectionName =
8350 GetSectionName("__objc_classrefs
", "regular,no_dead_strip
");
8351 Entry = new llvm::GlobalVariable(
8352 CGM.getModule(), ClassGV->getType(), false,
8353 getLinkageTypeForObjCMetadata(CGM, SectionName), ClassGV,
8354 "OBJC_CLASSLIST_REFERENCES_$_
");
8355 Entry->setAlignment(CGF.getPointerAlign().getAsAlign());
8356 if (!ID || !ID->hasAttr<ObjCClassStubAttr>())
8357 Entry->setSection(SectionName);
8359 CGM.addCompilerUsedGlobal(Entry);
8362 return EmitLoadOfClassRef(CGF, ID, Entry);
8365llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CodeGenFunction &CGF,
8366 const ObjCInterfaceDecl *ID) {
8367 // If the class has the objc_runtime_visible attribute, we need to
8368 // use the Objective-C runtime to get the class.
8369 if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
8370 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
8372 return EmitClassRefFromId(CGF, ID->getIdentifier(), ID);
8376CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
8377 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool
");
8378 return EmitClassRefFromId(CGF, II, nullptr);
8382CGObjCNonFragileABIMac::EmitSuperClassRef(CodeGenFunction &CGF,
8383 const ObjCInterfaceDecl *ID) {
8384 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
8387 llvm::Constant *ClassGV = GetClassGlobalForClassRef(ID);
8388 std::string SectionName =
8389 GetSectionName("__objc_superrefs
", "regular,no_dead_strip
");
8390 Entry = new llvm::GlobalVariable(CGM.getModule(), ClassGV->getType(), false,
8391 llvm::GlobalValue::PrivateLinkage, ClassGV,
8392 "OBJC_CLASSLIST_SUP_REFS_$_
");
8393 Entry->setAlignment(CGF.getPointerAlign().getAsAlign());
8394 Entry->setSection(SectionName);
8395 CGM.addCompilerUsedGlobal(Entry);
8398 return EmitLoadOfClassRef(CGF, ID, Entry);
8404llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(
8405 CodeGenFunction &CGF, const ObjCInterfaceDecl *ID, bool Weak) {
8406 CharUnits Align = CGF.getPointerAlign();
8407 llvm::GlobalVariable *&Entry = MetaClassReferences[ID->getIdentifier()];
8409 auto MetaClassGV = GetClassGlobal(ID, /*metaclass*/ true, NotForDefinition);
8410 std::string SectionName =
8411 GetSectionName("__objc_superrefs
", "regular,no_dead_strip
");
8412 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
8413 false, llvm::GlobalValue::PrivateLinkage,
8414 MetaClassGV, "OBJC_CLASSLIST_SUP_REFS_$_
");
8415 Entry->setAlignment(Align.getAsAlign());
8416 Entry->setSection(SectionName);
8417 CGM.addCompilerUsedGlobal(Entry);
8420 return CGF.Builder.CreateAlignedLoad(ObjCTypes.ClassnfABIPtrTy, Entry, Align);
8425llvm::Value *CGObjCNonFragileABIMac::GetClass(CodeGenFunction &CGF,
8426 const ObjCInterfaceDecl *ID) {
8427 if (ID->isWeakImported()) {
8428 auto ClassGV = GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition);
8430 assert(!isa<llvm::GlobalVariable>(ClassGV) ||
8431 cast<llvm::GlobalVariable>(ClassGV)->hasExternalWeakLinkage());
8434 return EmitClassRef(CGF, ID);
8440CodeGen::RValue CGObjCNonFragileABIMac::GenerateMessageSendSuper(
8441 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
8442 Selector Sel, const ObjCInterfaceDecl *Class, bool isCategoryImpl,
8443 llvm::Value *Receiver, bool IsClassMessage,
8444 const CodeGen::CallArgList &CallArgs, const ObjCMethodDecl *Method) {
8446 // Create and init a super structure; this is a (receiver, class)
8447 // pair we will pass to objc_msgSendSuper.
8448 RawAddress ObjCSuper = CGF.CreateTempAlloca(
8449 ObjCTypes.SuperTy, CGF.getPointerAlign(), "objc_super
");
8451 llvm::Value *ReceiverAsObject =
8452 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
8453 CGF.Builder.CreateStore(ReceiverAsObject,
8454 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
8456 // If this is a class message the metaclass is passed as the target.
8457 llvm::Value *Target;
8459 Target = EmitMetaClassRef(CGF, Class, Class->isWeakImported());
8461 Target = EmitSuperClassRef(CGF, Class);
8463 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
8465 llvm::Type *ClassTy =
8466 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
8467 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
8468 CGF.Builder.CreateStore(Target, CGF.Builder.CreateStructGEP(ObjCSuper, 1));
8470 return (isVTableDispatchedSelector(Sel))
8471 ? EmitVTableMessageSend(
8472 CGF, Return, ResultType, Sel, ObjCSuper.getPointer(),
8473 ObjCTypes.SuperPtrCTy, true, CallArgs, Method)
8474 : EmitMessageSend(CGF, Return, ResultType, Sel,
8475 ObjCSuper.getPointer(), ObjCTypes.SuperPtrCTy,
8476 true, CallArgs, Method, Class, ObjCTypes);
8479llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CodeGenFunction &CGF,
8481 Address Addr = EmitSelectorAddr(Sel);
8483 llvm::LoadInst *LI = CGF.Builder.CreateLoad(Addr);
8484 LI->setMetadata(llvm::LLVMContext::MD_invariant_load,
8485 llvm::MDNode::get(VMContext, {}));
8489ConstantAddress CGObjCNonFragileABIMac::EmitSelectorAddr(Selector Sel) {
8490 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
8491 CharUnits Align = CGM.getPointerAlign();
8493 std::string SectionName =
8494 GetSectionName("__objc_selrefs
", "literal_pointers,no_dead_strip
");
8495 Entry = new llvm::GlobalVariable(
8496 CGM.getModule(), ObjCTypes.SelectorPtrTy, false,
8497 getLinkageTypeForObjCMetadata(CGM, SectionName), GetMethodVarName(Sel),
8498 "OBJC_SELECTOR_REFERENCES_
");
8499 Entry->setExternallyInitialized(true);
8500 Entry->setSection(SectionName);
8501 Entry->setAlignment(Align.getAsAlign());
8502 CGM.addCompilerUsedGlobal(Entry);
8505 return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align);
8511void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
8512 llvm::Value *src, Address dst,
8513 llvm::Value *ivarOffset) {
8514 llvm::Type *SrcTy = src->getType();
8515 if (!isa<llvm::PointerType>(SrcTy)) {
8516 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
8517 assert(Size <= 8 && "does
not support size > 8
");
8518 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
8519 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
8520 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
8522 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
8523 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
8524 ObjCTypes.PtrObjectPtrTy);
8525 llvm::Value *args[] = {src, dstVal, ivarOffset};
8526 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
8532void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
8533 CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dst) {
8534 llvm::Type *SrcTy = src->getType();
8535 if (!isa<llvm::PointerType>(SrcTy)) {
8536 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
8537 assert(Size <= 8 && "does
not support size > 8
");
8538 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
8539 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
8540 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
8542 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
8543 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
8544 ObjCTypes.PtrObjectPtrTy);
8545 llvm::Value *args[] = {src, dstVal};
8546 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), args,
8550void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
8551 CodeGen::CodeGenFunction &CGF, Address DestPtr, Address SrcPtr,
8552 llvm::Value *Size) {
8553 llvm::Value *args[] = {DestPtr.emitRawPointer(CGF),
8554 SrcPtr.emitRawPointer(CGF), Size};
8555 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
8562CGObjCNonFragileABIMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
8563 Address AddrWeakObj) {
8564 llvm::Type *DestTy = AddrWeakObj.getElementType();
8565 llvm::Value *AddrWeakObjVal = CGF.Builder.CreateBitCast(
8566 AddrWeakObj.emitRawPointer(CGF), ObjCTypes.PtrObjectPtrTy);
8567 llvm::Value *read_weak = CGF.EmitNounwindRuntimeCall(
8568 ObjCTypes.getGcReadWeakFn(), AddrWeakObjVal, "weakread
");
8569 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
8576void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
8577 llvm::Value *src, Address dst) {
8578 llvm::Type *SrcTy = src->getType();
8579 if (!isa<llvm::PointerType>(SrcTy)) {
8580 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
8581 assert(Size <= 8 && "does
not support size > 8
");
8582 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
8583 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
8584 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
8586 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
8587 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
8588 ObjCTypes.PtrObjectPtrTy);
8589 llvm::Value *args[] = {src, dstVal};
8590 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), args,
8597void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
8598 llvm::Value *src, Address dst,
8600 llvm::Type *SrcTy = src->getType();
8601 if (!isa<llvm::PointerType>(SrcTy)) {
8602 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
8603 assert(Size <= 8 && "does
not support size > 8
");
8604 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
8605 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
8606 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
8608 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
8609 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
8610 ObjCTypes.PtrObjectPtrTy);
8611 llvm::Value *args[] = {src, dstVal};
8613 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), args,
8616 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(), args,
8617 "threadlocalassign
");
8620void CGObjCNonFragileABIMac::EmitSynchronizedStmt(
8621 CodeGen::CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S) {
8622 EmitAtSynchronizedStmt(CGF, S, ObjCTypes.getSyncEnterFn(),
8623 ObjCTypes.getSyncExitFn());
8626llvm::Constant *CGObjCNonFragileABIMac::GetEHType(QualType T) {
8627 // There's a particular fixed type info for 'id'.
8628 if (T->isObjCIdType() || T->isObjCQualifiedIdType()) {
8629 auto *IDEHType = CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id
");
8631 IDEHType = new llvm::GlobalVariable(
8632 CGM.getModule(), ObjCTypes.EHTypeTy, false,
8633 llvm::GlobalValue::ExternalLinkage, nullptr, "OBJC_EHTYPE_id
");
8634 if (CGM.getTriple().isOSBinFormatCOFF())
8635 IDEHType->setDLLStorageClass(getStorage(CGM, "OBJC_EHTYPE_id
"));
8640 // All other types should be Objective-C interface pointer types.
8641 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
8644 const ObjCInterfaceType *IT = PT->getInterfaceType();
8645 assert(IT && "Invalid
@catch type.
");
8647 return GetInterfaceEHType(IT->getDecl(), NotForDefinition);
8650void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
8651 const ObjCAtTryStmt &S) {
8652 EmitTryCatchStmt(CGF, S, ObjCTypes.getObjCBeginCatchFn(),
8653 ObjCTypes.getObjCEndCatchFn(),
8654 ObjCTypes.getExceptionRethrowFn());
8658void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
8659 const ObjCAtThrowStmt &S,
8660 bool ClearInsertionPoint) {
8661 if (const Expr *ThrowExpr = S.getThrowExpr()) {
8662 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
8663 Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
8664 llvm::CallBase *Call =
8665 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception);
8666 Call->setDoesNotReturn();
8668 llvm::CallBase *Call =
8669 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionRethrowFn());
8670 Call->setDoesNotReturn();
8673 CGF.Builder.CreateUnreachable();
8674 if (ClearInsertionPoint)
8675 CGF.Builder.ClearInsertionPoint();
8679CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
8680 ForDefinition_t IsForDefinition) {
8681 llvm::GlobalVariable *&Entry = EHTypeReferences[ID->getIdentifier()];
8682 StringRef ClassName = ID->getObjCRuntimeNameAsString();
8684 // If we don't need a definition, return the entry if found or check
8685 // if we use an external reference.
8686 if (!IsForDefinition) {
8690 // If this type (or a super class) has the __objc_exception__
8691 // attribute, emit an external reference.
8692 if (hasObjCExceptionAttribute(CGM.getContext(), ID)) {
8693 std::string EHTypeName = ("OBJC_EHTYPE_$_
" + ClassName).str();
8694 Entry = new llvm::GlobalVariable(
8695 CGM.getModule(), ObjCTypes.EHTypeTy, false,
8696 llvm::GlobalValue::ExternalLinkage, nullptr, EHTypeName);
8697 CGM.setGVProperties(Entry, ID);
8702 // Otherwise we need to either make a new entry or fill in the initializer.
8703 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition
");
8705 std::string VTableName = "objc_ehtype_vtable
";
8706 auto *VTableGV = CGM.getModule().getGlobalVariable(VTableName);
8708 VTableGV = new llvm::GlobalVariable(
8709 CGM.getModule(), ObjCTypes.Int8PtrTy, false,
8710 llvm::GlobalValue::ExternalLinkage, nullptr, VTableName);
8711 if (CGM.getTriple().isOSBinFormatCOFF())
8712 VTableGV->setDLLStorageClass(getStorage(CGM, VTableName));
8715 llvm::Constant *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2);
8716 llvm::Constant *VTablePtr = llvm::ConstantExpr::getGetElementPtr(
8717 CGM.getDataLayout(), VTableGV->getValueType(), VTableGV, VTableIdx,
8718 llvm::GEPNoWrapFlags::inBounds());
8720 ConstantInitBuilder builder(CGM);
8721 auto values = builder.beginStruct(ObjCTypes.EHTypeTy);
8722 const PointerAuthSchema &TypeInfoSchema =
8723 CGM.getCodeGenOpts().PointerAuth.CXXTypeInfoVTablePointer;
8724 values.addSignedPointer(VTablePtr, TypeInfoSchema, GlobalDecl(), QualType());
8726 values.add(GetClassName(ClassName));
8727 values.add(GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition));
8729 llvm::GlobalValue::LinkageTypes L = IsForDefinition
8730 ? llvm::GlobalValue::ExternalLinkage
8731 : llvm::GlobalValue::WeakAnyLinkage;
8733 values.finishAndSetAsInitializer(Entry);
8734 Entry->setAlignment(CGM.getPointerAlign().getAsAlign());
8736 Entry = values.finishAndCreateGlobal("OBJC_EHTYPE_$_
" + ClassName,
8737 CGM.getPointerAlign(),
8738 /*constant*/ false, L);
8739 if (hasObjCExceptionAttribute(CGM.getContext(), ID))
8740 CGM.setGVProperties(Entry, ID);
8742 assert(Entry->getLinkage() == L);
8744 if (!CGM.getTriple().isOSBinFormatCOFF())
8745 if (ID->getVisibility() == HiddenVisibility)
8746 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
8748 if (IsForDefinition)
8749 if (CGM.getTriple().isOSBinFormatMachO())
8750 Entry->setSection("__DATA,__objc_const
");
8757CodeGen::CGObjCRuntime *
8758CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
8759 switch (CGM.getLangOpts().ObjCRuntime.getKind()) {
8760 case ObjCRuntime::FragileMacOSX:
8761 return new CGObjCMac(CGM);
8763 case ObjCRuntime::MacOSX:
8764 case ObjCRuntime::iOS:
8765 case ObjCRuntime::WatchOS:
8766 return new CGObjCNonFragileABIMac(CGM);
8768 case ObjCRuntime::GNUstep:
8769 case ObjCRuntime::GCC:
8770 case ObjCRuntime::ObjFW:
8771 llvm_unreachable("these runtimes are
not Mac runtimes
");
8773 llvm_unreachable("bad runtime
");
8776// Public wrapper function for external compilers (e.g., Swift) to access
8777// the Mac runtime's GetDirectMethodCallee functionality.
8778llvm::Function *clang::CodeGen::getObjCDirectMethodCallee(
8779 CodeGenModule &CGM, const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD,
8780 bool ReceiverCanBeNull, bool ClassObjectCanBeUnrealized) {
8781 // This function should only be called when targeting Darwin platforms,
8782 // which always use the Mac runtime.
8783 assert(CGM.getLangOpts().ObjCRuntime.isNeXTFamily() &&
8785 CGObjCCommonMac *MacRuntime =
8786 static_cast<CGObjCCommonMac *>(&CGM.getObjCRuntime());
8787 return MacRuntime->GetDirectMethodCallee(OMD, CD, ReceiverCanBeNull,
8788 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 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.
Top level wrappers for InstallAPI frontend operations.
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.
const FunctionProtoType * T
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 + ...)
__builtin_elementwise_add_sat __builtin_elementwise_sub_sat uint32_t __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.