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) {}
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,
1685 uint32_t &InstanceStart, uint32_t &InstanceSize);
1700 bool ImplementationIsNonLazy(
const ObjCImplDecl *OD)
const;
1702 bool IsIvarOffsetKnownIdempotent(
const CodeGen::CodeGenFunction &CGF,
1703 const ObjCIvarDecl *IV) {
1718 if (
const ObjCMethodDecl *MD =
1719 dyn_cast_or_null<ObjCMethodDecl>(CGF.
CurFuncDecl))
1720 if (MD->isInstanceMethod() && !MD->isDirectMethod())
1721 if (
const ObjCInterfaceDecl *ID = MD->getClassInterface())
1726 bool isClassLayoutKnownStatically(
const ObjCInterfaceDecl *ID) {
1729 assert(ID !=
nullptr &&
"Passed a null class to check layout");
1730 for (;
ID !=
nullptr;
ID =
ID->getSuperClass()) {
1733 if (
ID->getIdentifier()->getName() ==
"NSObject")
1738 if (!
ID->getImplementation())
1747 CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm);
1749 llvm::Constant *getNSConstantStringClassRef()
override;
1750 llvm::Constant *getNSConstantArrayClassRef()
override;
1751 llvm::Constant *getNSConstantDictionaryClassRef()
override;
1753 llvm::Constant *getNSConstantIntegerNumberClassRef()
override;
1754 llvm::Constant *getNSConstantFloatNumberClassRef()
override;
1755 llvm::Constant *getNSConstantDoubleNumberClassRef()
override;
1757 llvm::Function *ModuleInitFunction()
override;
1759 CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1760 ReturnValueSlot Return,
1761 QualType ResultType, Selector Sel,
1762 llvm::Value *Receiver,
1763 const CallArgList &CallArgs,
1764 const ObjCInterfaceDecl *
Class,
1765 const ObjCMethodDecl *
Method)
override;
1767 CodeGen::RValue GenerateMessageSendSuper(
1768 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return,
1769 QualType ResultType, Selector Sel,
const ObjCInterfaceDecl *
Class,
1770 bool isCategoryImpl, llvm::Value *Receiver,
bool IsClassMessage,
1771 const CallArgList &CallArgs,
const ObjCMethodDecl *
Method)
override;
1773 llvm::Value *GetClass(CodeGenFunction &CGF,
1774 const ObjCInterfaceDecl *ID)
override;
1776 llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel)
override {
1777 return EmitSelector(CGF, Sel);
1779 Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel)
override {
1780 return EmitSelectorAddr(Sel);
1785 llvm::Value *GetSelector(CodeGenFunction &CGF,
1786 const ObjCMethodDecl *
Method)
override {
1787 return EmitSelector(CGF,
Method->getSelector());
1790 void GenerateCategory(
const ObjCCategoryImplDecl *CMD)
override;
1792 void GenerateClass(
const ObjCImplementationDecl *ClassDecl)
override;
1794 void RegisterAlias(
const ObjCCompatibleAliasDecl *OAD)
override {}
1796 llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
1797 const ObjCProtocolDecl *PD)
override;
1799 llvm::Constant *GetEHType(QualType T)
override;
1801 llvm::FunctionCallee GetPropertyGetFunction()
override {
1802 return ObjCTypes.getGetPropertyFn();
1804 llvm::FunctionCallee GetPropertySetFunction()
override {
1805 return ObjCTypes.getSetPropertyFn();
1808 llvm::FunctionCallee GetOptimizedPropertySetFunction(
bool atomic,
1809 bool copy)
override {
1810 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
1813 llvm::FunctionCallee GetSetStructFunction()
override {
1814 return ObjCTypes.getCopyStructFn();
1817 llvm::FunctionCallee GetGetStructFunction()
override {
1818 return ObjCTypes.getCopyStructFn();
1821 llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override {
1822 return ObjCTypes.getCppAtomicObjectFunction();
1825 llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override {
1826 return ObjCTypes.getCppAtomicObjectFunction();
1829 llvm::FunctionCallee EnumerationMutationFunction()
override {
1830 return ObjCTypes.getEnumerationMutationFn();
1833 void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1834 const ObjCAtTryStmt &S)
override;
1835 void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1836 const ObjCAtSynchronizedStmt &S)
override;
1837 void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
const ObjCAtThrowStmt &S,
1838 bool ClearInsertionPoint =
true)
override;
1839 llvm::Value *EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1840 Address AddrWeakObj)
override;
1841 void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1842 Address edst)
override;
1843 void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1844 Address dest,
bool threadlocal =
false)
override;
1845 void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1846 Address dest, llvm::Value *ivarOffset)
override;
1847 void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1848 Address dest)
override;
1849 void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, Address dest,
1850 Address src, llvm::Value *size)
override;
1851 LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy,
1852 llvm::Value *BaseValue,
const ObjCIvarDecl *Ivar,
1853 unsigned CVRQualifiers)
override;
1854 llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1856 const ObjCIvarDecl *Ivar)
override;
1861struct NullReturnState {
1862 llvm::BasicBlock *NullBB =
nullptr;
1863 NullReturnState() =
default;
1866 void init(CodeGenFunction &CGF, llvm::Value *receiver) {
1876 CGF.
Builder.CreateCondBr(isNull, NullBB, callBB);
1884 RValue complete(CodeGenFunction &CGF, ReturnValueSlot returnSlot,
1885 RValue result, QualType resultType,
1886 const CallArgList &CallArgs,
const ObjCMethodDecl *
Method) {
1893 llvm::BasicBlock *contBB =
nullptr;
1896 llvm::BasicBlock *callBB = CGF.
Builder.GetInsertBlock();
1911 assert(CGF.
Builder.GetInsertBlock() == NullBB);
1933 llvm::PHINode *phi = CGF.
Builder.CreatePHI(null->getType(), 2);
1935 phi->addIncoming(null, NullBB);
1944 assert(result.
isAggregate() &&
"null init of non-aggregate result?");
1957 llvm::Type *scalarTy = callResult.first->getType();
1958 llvm::Constant *scalarZero = llvm::Constant::getNullValue(scalarTy);
1961 llvm::PHINode *real = CGF.
Builder.CreatePHI(scalarTy, 2);
1962 real->addIncoming(callResult.first, callBB);
1963 real->addIncoming(scalarZero, NullBB);
1964 llvm::PHINode *imag = CGF.
Builder.CreatePHI(scalarTy, 2);
1965 imag->addIncoming(callResult.second, callBB);
1966 imag->addIncoming(scalarZero, NullBB);
1977 llvm::GlobalVariable *
C,
unsigned idx0,
1979 llvm::Value *Idxs[] = {
1980 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),
1981 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)};
1982 return llvm::ConstantExpr::getGetElementPtr(
C->getValueType(),
C, Idxs);
1989 if (OID->
hasAttr<ObjCExceptionAttr>())
1996static llvm::GlobalValue::LinkageTypes
1998 if (CGM.
getTriple().isOSBinFormatMachO() &&
1999 (Section.empty() || Section.starts_with(
"__DATA")))
2000 return llvm::GlobalValue::InternalLinkage;
2001 return llvm::GlobalValue::PrivateLinkage;
2005static llvm::GlobalVariable *
2008 std::string SectionName;
2009 if (CGM.
getTriple().isOSBinFormatMachO())
2010 SectionName =
"__DATA, __objc_const";
2011 auto *GV = Builder.finishAndCreateGlobal(
2014 GV->setSection(SectionName);
2021 : CGObjCCommonMac(cgm), ObjCTypes(cgm) {
2030 return EmitClassRef(CGF, ID);
2034llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF, Selector Sel) {
2035 return EmitSelector(CGF, Sel);
2037Address CGObjCMac::GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) {
2038 return EmitSelectorAddr(Sel);
2040llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF,
2041 const ObjCMethodDecl *
Method) {
2042 return EmitSelector(CGF,
Method->getSelector());
2045llvm::Constant *CGObjCMac::GetEHType(QualType T) {
2057 llvm_unreachable(
"asking for catch type for ObjC type in fragile runtime");
2080CGObjCCommonMac::GenerateConstantString(
const StringLiteral *SL) {
2083 : GenerateConstantNSString(SL));
2086ConstantAddress CGObjCCommonMac::GenerateConstantNumber(
const bool Value,
2087 const QualType &Ty) {
2088 return GenerateConstantNSNumber(
Value, Ty);
2092CGObjCCommonMac::GenerateConstantNumber(
const llvm::APSInt &
Value,
2093 const QualType &Ty) {
2094 return GenerateConstantNSNumber(
Value, Ty);
2098CGObjCCommonMac::GenerateConstantNumber(
const llvm::APFloat &
Value,
2099 const QualType &Ty) {
2100 return GenerateConstantNSNumber(
Value, Ty);
2103ConstantAddress CGObjCCommonMac::GenerateConstantArray(
2104 const ArrayRef<llvm::Constant *> &Objects) {
2105 return GenerateConstantNSArray(Objects);
2108ConstantAddress CGObjCCommonMac::GenerateConstantDictionary(
2109 const ObjCDictionaryLiteral *E,
2110 ArrayRef<std::pair<llvm::Constant *, llvm::Constant *>> KeysAndObjects) {
2111 return GenerateConstantNSDictionary(E, KeysAndObjects);
2114static llvm::StringMapEntry<llvm::GlobalVariable *> &
2117 StringRef String = Literal->getString();
2118 StringLength = String.size();
2119 return *Map.insert(std::make_pair(String,
nullptr)).first;
2122llvm::Constant *CGObjCMac::getNSConstantStringClassRef() {
2123 if (llvm::Value *
V = ConstantStringClassRef)
2127 std::string str = StringClass.empty() ?
"_NSConstantStringClassReference"
2128 :
"_" + StringClass +
"ClassReference";
2130 llvm::Type *PTy = llvm::ArrayType::get(CGM.
IntTy, 0);
2132 ConstantStringClassRef = GV;
2136llvm::Constant *CGObjCMac::getNSConstantArrayClassRef() {
2137 llvm_unreachable(
"constant array literals not supported for fragile ABI");
2140llvm::Constant *CGObjCMac::getNSConstantDictionaryClassRef() {
2141 llvm_unreachable(
"constant dictionary literals not supported for fragile "
2145llvm::Constant *CGObjCMac::getNSConstantIntegerNumberClassRef() {
2146 llvm_unreachable(
"constant number literals not supported for fragile ABI");
2149llvm::Constant *CGObjCMac::getNSConstantFloatNumberClassRef() {
2150 llvm_unreachable(
"constant number literals not supported for fragile ABI");
2153llvm::Constant *CGObjCMac::getNSConstantDoubleNumberClassRef() {
2154 llvm_unreachable(
"constant number literals not supported for fragile ABI");
2157llvm::Constant *CGObjCNonFragileABIMac::getNSConstantStringClassRef() {
2158 if (llvm::Value *
V = ConstantStringClassRef)
2162 std::string str = StringClass.empty() ?
"OBJC_CLASS_$_NSConstantString"
2163 :
"OBJC_CLASS_$_" + StringClass;
2165 ConstantStringClassRef = GV;
2169llvm::Constant *CGObjCNonFragileABIMac::getNSConstantArrayClassRef() {
2170 if (llvm::Value *
V = ConstantArrayClassRef)
2174 std::string Str = ArrayClass.empty() ?
"OBJC_CLASS_$_NSConstantArray"
2175 :
"OBJC_CLASS_$_" + ArrayClass;
2178 ConstantArrayClassRef = GV;
2182llvm::Constant *CGObjCNonFragileABIMac::getNSConstantDictionaryClassRef() {
2183 if (llvm::Value *
V = ConstantDictionaryClassRef)
2186 const std::string &DictionaryClass =
2188 std::string Str = DictionaryClass.empty()
2189 ?
"OBJC_CLASS_$_NSConstantDictionary"
2190 :
"OBJC_CLASS_$_" + DictionaryClass;
2193 ConstantDictionaryClassRef = GV;
2197llvm::Constant *CGObjCNonFragileABIMac::getNSConstantIntegerNumberClassRef() {
2198 if (llvm::Value *
V = ConstantIntegerNumberClassRef)
2201 const std::string &NumberClass =
2203 std::string Str = NumberClass.empty() ?
"OBJC_CLASS_$_NSConstantIntegerNumber"
2204 :
"OBJC_CLASS_$_" + NumberClass;
2207 ConstantIntegerNumberClassRef = GV;
2211llvm::Constant *CGObjCNonFragileABIMac::getNSConstantFloatNumberClassRef() {
2212 if (llvm::Value *
V = ConstantFloatNumberClassRef)
2215 const std::string &NumberClass =
2217 std::string Str = NumberClass.empty() ?
"OBJC_CLASS_$_NSConstantFloatNumber"
2218 :
"OBJC_CLASS_$_" + NumberClass;
2221 ConstantFloatNumberClassRef = GV;
2225llvm::Constant *CGObjCNonFragileABIMac::getNSConstantDoubleNumberClassRef() {
2226 if (llvm::Value *
V = ConstantDoubleNumberClassRef)
2229 const std::string &NumberClass =
2231 std::string Str = NumberClass.empty() ?
"OBJC_CLASS_$_NSConstantDoubleNumber"
2232 :
"OBJC_CLASS_$_" + NumberClass;
2235 ConstantDoubleNumberClassRef = GV;
2240CGObjCCommonMac::GenerateConstantNSString(
const StringLiteral *Literal) {
2241 unsigned StringLength = 0;
2242 llvm::StringMapEntry<llvm::GlobalVariable *> &Entry =
2245 if (
auto *
C = Entry.second)
2246 return ConstantAddress(
C,
C->getValueType(),
2250 llvm::Constant *
Class = getNSConstantStringClassRef();
2253 if (!NSConstantStringType) {
2257 NSConstantStringType =
2259 "struct.__builtin_NSString");
2262 ConstantInitBuilder Builder(CGM);
2263 auto Fields = Builder.beginStruct(NSConstantStringType);
2266 Fields.addSignedPointer(
Class,
2268 GlobalDecl(), QualType());
2272 llvm::ConstantDataArray::getString(VMContext, Entry.first());
2274 llvm::GlobalValue::LinkageTypes
Linkage = llvm::GlobalValue::PrivateLinkage;
2275 bool isConstant = !CGM.
getLangOpts().WritableStrings;
2277 auto *GV =
new llvm::GlobalVariable(CGM.
getModule(),
C->getType(), isConstant,
2279 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2282 GV->setAlignment(llvm::Align(1));
2286 Fields.addInt(CGM.
IntTy, StringLength);
2290 GV = Fields.finishAndCreateGlobal(
"_unnamed_nsstring_", Alignment,
2292 llvm::GlobalVariable::PrivateLinkage);
2293 const char *NSStringSection =
"__OBJC,__cstring_object,regular,no_dead_strip";
2294 const char *NSStringNonFragileABISection =
2295 "__DATA,__objc_stringobj,regular,no_dead_strip";
2298 ? NSStringNonFragileABISection
2302 return ConstantAddress(GV, GV->getValueType(), Alignment);
2306ConstantAddress CGObjCCommonMac::GenerateConstantNSNumber(
const bool Value,
2307 const QualType &Ty) {
2308 llvm::GlobalVariable *Val =
2309 Value ? EmitConstantCFBooleanTrue() : EmitConstantCFBooleanFalse();
2310 return ConstantAddress(Val, Val->getValueType(), CGM.
getPointerAlign());
2323CGObjCCommonMac::GenerateConstantNSNumber(
const llvm::APSInt &
Value,
2324 const QualType &Ty) {
2328 llvm::GlobalVariable *&Entry =
2331 return ConstantAddress(Entry, Entry->getValueType(), Alignment);
2335 std::string ObjCEncodingType;
2336 CodeGenFunction(CGM).getContext().getObjCEncodingForType(Ty,
2339 llvm::Constant *
const Class = getNSConstantIntegerNumberClassRef();
2341 if (!NSConstantIntegerNumberType) {
2342 NSConstantIntegerNumberType = llvm::StructType::create(
2348 "struct.__builtin_NSConstantIntegerNumber");
2351 ConstantInitBuilder Builder(CGM);
2352 auto Fields = Builder.beginStruct(NSConstantIntegerNumberType);
2355 Fields.addSignedPointer(
Class,
2357 GlobalDecl(), QualType());
2363 llvm::Constant *IntegerValue =
2364 llvm::ConstantInt::get(CGM.
Int64Ty,
Value.extOrTrunc(64));
2366 Fields.add(IntegerValue);
2369 llvm::GlobalVariable *
const GV = Fields.finishAndCreateGlobal(
2370 "_unnamed_nsconstantintegernumber_", Alignment,
2371 true, llvm::GlobalVariable::PrivateLinkage);
2373 GV->setSection(GetNSConstantIntegerNumberSectionName());
2374 GV->addAttribute(
"objc_arc_inert");
2378 return ConstantAddress(GV, GV->getValueType(), Alignment);
2396CGObjCCommonMac::GenerateConstantNSNumber(
const llvm::APFloat &
Value,
2397 const QualType &Ty) {
2401 llvm::GlobalVariable *&Entry =
2404 return ConstantAddress(Entry, Entry->getValueType(), Alignment);
2408 std::string ObjCEncodingType;
2409 CodeGenFunction(CGM).getContext().getObjCEncodingForType(Ty,
2412 assert((ObjCEncodingType ==
"d" || ObjCEncodingType ==
"f") &&
2413 "Unexpected or unknown ObjCEncodingType used in constant NSNumber");
2415 llvm::GlobalValue::LinkageTypes
Linkage =
2416 llvm::GlobalVariable::PrivateLinkage;
2419 if (ObjCEncodingType ==
"f") {
2420 llvm::Constant *
const Class = getNSConstantFloatNumberClassRef();
2422 if (!NSConstantFloatNumberType) {
2423 NSConstantFloatNumberType = llvm::StructType::create(
2428 "struct.__builtin_NSConstantFloatNumber");
2431 ConstantInitBuilder Builder(CGM);
2432 auto Fields = Builder.beginStruct(NSConstantFloatNumberType);
2435 Fields.addSignedPointer(
Class,
2437 GlobalDecl(), QualType());
2440 llvm::Constant *FV = llvm::ConstantFP::get(CGM.
FloatTy,
Value);
2444 llvm::GlobalVariable *
const GV = Fields.finishAndCreateGlobal(
2445 "_unnamed_nsconstantfloatnumber_", Alignment,
2448 GV->setSection(GetNSConstantFloatNumberSectionName());
2449 GV->addAttribute(
"objc_arc_inert");
2453 return ConstantAddress(GV, GV->getValueType(), Alignment);
2456 llvm::Constant *
const Class = getNSConstantDoubleNumberClassRef();
2457 if (!NSConstantDoubleNumberType) {
2459 NSConstantDoubleNumberType = llvm::StructType::create(
2464 "struct.__builtin_NSConstantDoubleNumber");
2467 ConstantInitBuilder Builder(CGM);
2468 auto Fields = Builder.beginStruct(NSConstantDoubleNumberType);
2471 Fields.addSignedPointer(
Class,
2473 GlobalDecl(), QualType());
2476 llvm::Constant *DV = llvm::ConstantFP::get(CGM.
DoubleTy,
Value);
2480 llvm::GlobalVariable *
const GV = Fields.finishAndCreateGlobal(
2481 "_unnamed_nsconstantdoublenumber_", Alignment,
2484 GV->setSection(GetNSConstantDoubleNumberSectionName());
2485 GV->addAttribute(
"objc_arc_inert");
2489 return ConstantAddress(GV, GV->getValueType(), Alignment);
2494llvm::GlobalVariable *
2495CGObjCCommonMac::EmitNSConstantCollectionLiteralArrayStorage(
2496 const ArrayRef<llvm::Constant *> &Elements) {
2497 llvm::Type *ElementsTy = Elements[0]->getType();
2498 llvm::ArrayType *ArrayTy = llvm::ArrayType::get(ElementsTy, Elements.size());
2500 llvm::Constant *
const ArrayData = llvm::ConstantArray::get(ArrayTy, Elements);
2502 llvm::GlobalVariable *ObjectsGV =
new llvm::GlobalVariable(
2503 CGM.
getModule(), ArrayTy,
true, llvm::GlobalValue::InternalLinkage,
2504 ArrayData,
"_unnamed_array_storage");
2507 ObjectsGV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2508 ObjectsGV->setSection(GetNSConstantCollectionStorageSectionName());
2521ConstantAddress CGObjCCommonMac::GenerateConstantNSArray(
2522 const ArrayRef<llvm::Constant *> &Objects) {
2525 if (Objects.size() == 0) {
2526 llvm::GlobalVariable *GV = EmitEmptyConstantNSArray();
2527 return ConstantAddress(GV, GV->getValueType(), Alignment);
2531 CodeGenTypes &Types = CGM.
getTypes();
2532 llvm::Constant *
const Class = getNSConstantArrayClassRef();
2533 llvm::Type *
const NSUIntegerTy =
2536 if (!NSConstantArrayType) {
2537 NSConstantArrayType = llvm::StructType::create(
2543 "struct.__builtin_NSArray");
2546 ConstantInitBuilder Builder(CGM);
2547 auto Fields = Builder.beginStruct(NSConstantArrayType);
2550 Fields.addSignedPointer(
Class,
2552 GlobalDecl(), QualType());
2555 uint64_t ObjectCount = Objects.size();
2556 llvm::Constant *Count = llvm::ConstantInt::get(NSUIntegerTy, ObjectCount);
2560 llvm::GlobalVariable *ObjectsGV =
2561 EmitNSConstantCollectionLiteralArrayStorage(Objects);
2562 Fields.add(ObjectsGV);
2565 llvm::GlobalVariable *GV = Fields.finishAndCreateGlobal(
2566 "_unnamed_nsarray_", Alignment,
2567 true, llvm::GlobalValue::PrivateLinkage);
2569 GV->setSection(GetNSConstantArraySectionName());
2570 GV->addAttribute(
"objc_arc_inert");
2572 return ConstantAddress(GV, GV->getValueType(), Alignment);
2587ConstantAddress CGObjCCommonMac::GenerateConstantNSDictionary(
2588 const ObjCDictionaryLiteral *E,
2589 ArrayRef<std::pair<llvm::Constant *, llvm::Constant *>> KeysAndObjects) {
2592 if (KeysAndObjects.size() == 0) {
2593 llvm::GlobalVariable *GV = EmitEmptyConstantNSDictionary();
2594 return ConstantAddress(GV, GV->getValueType(), Alignment);
2598 CodeGenTypes &Types = CGM.
getTypes();
2599 llvm::Constant *
const Class = getNSConstantDictionaryClassRef();
2601 llvm::Type *
const NSUIntegerTy =
2604 if (!NSConstantDictionaryType) {
2605 NSConstantDictionaryType = llvm::StructType::create(
2613 "struct.__builtin_NSDictionary");
2616 ConstantInitBuilder Builder(CGM);
2617 auto Fields = Builder.beginStruct(NSConstantDictionaryType);
2620 Fields.addSignedPointer(
Class,
2622 GlobalDecl(), QualType());
2625 auto HashOpts(NSDictionaryBuilder::Options::Sorted);
2626 NSDictionaryBuilder DictBuilder(E, KeysAndObjects, HashOpts);
2629 uint64_t const NumElements = DictBuilder.getNumElements();
2631 llvm::Constant *OptionsConstant = llvm::ConstantInt::get(
2632 NSUIntegerTy,
static_cast<uint64_t>(DictBuilder.getOptions()));
2633 Fields.add(OptionsConstant);
2636 llvm::Constant *Count = llvm::ConstantInt::get(NSUIntegerTy, NumElements);
2640 SmallVector<llvm::Constant *, 16> SortedKeys, SortedObjects;
2641 SortedKeys.reserve(NumElements);
2642 SortedObjects.reserve(NumElements);
2643 for (
auto &[Key, Obj] : DictBuilder.getElements()) {
2644 SortedKeys.push_back(Key);
2645 SortedObjects.push_back(Obj);
2649 llvm::GlobalVariable *KeysGV =
2650 EmitNSConstantCollectionLiteralArrayStorage(SortedKeys);
2654 llvm::GlobalVariable *ObjectsGV =
2655 EmitNSConstantCollectionLiteralArrayStorage(SortedObjects);
2656 Fields.add(ObjectsGV);
2659 llvm::GlobalVariable *GV = Fields.finishAndCreateGlobal(
2660 "_unnamed_nsdictionary_", Alignment,
2661 true, llvm::GlobalValue::PrivateLinkage);
2663 GV->setSection(GetNSConstantDictionarySectionName());
2664 GV->addAttribute(
"objc_arc_inert");
2666 return ConstantAddress(GV, GV->getValueType(), Alignment);
2674CodeGen::RValue CGObjCMac::GenerateMessageSendSuper(
2675 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
2676 Selector Sel,
const ObjCInterfaceDecl *
Class,
bool isCategoryImpl,
2677 llvm::Value *Receiver,
bool IsClassMessage,
2678 const CodeGen::CallArgList &CallArgs,
const ObjCMethodDecl *
Method) {
2683 llvm::Value *ReceiverAsObject =
2684 CGF.
Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
2689 llvm::Type *ClassTyPtr = llvm::PointerType::getUnqual(VMContext);
2691 if (IsClassMessage) {
2692 if (isCategoryImpl) {
2699 Target = EmitClassRef(CGF,
Class->getSuperClass());
2704 llvm::Constant *MetaClassPtr = EmitMetaClassRef(
Class);
2705 llvm::Value *SuperPtr =
2711 }
else if (isCategoryImpl)
2712 Target = EmitClassRef(CGF,
Class->getSuperClass());
2714 llvm::Value *ClassPtr = EmitSuperClassRef(
Class);
2721 llvm::Type *ClassTy =
2725 return EmitMessageSend(CGF, Return, ResultType, Sel, ObjCSuper.
getPointer(),
2726 ObjCTypes.SuperPtrCTy,
true, CallArgs,
Method,
Class,
2731CodeGen::RValue CGObjCMac::GenerateMessageSend(
2732 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
2733 Selector Sel, llvm::Value *Receiver,
const CallArgList &CallArgs,
2734 const ObjCInterfaceDecl *
Class,
const ObjCMethodDecl *
Method) {
2735 return EmitMessageSend(CGF, Return, ResultType, Sel, Receiver,
2740CodeGen::RValue CGObjCCommonMac::EmitMessageSend(
2741 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
2742 Selector Sel, llvm::Value *Arg0, QualType Arg0Ty,
bool IsSuper,
2743 const CallArgList &CallArgs,
const ObjCMethodDecl *
Method,
2744 const ObjCInterfaceDecl *ClassReceiver,
2745 const ObjCCommonTypesHelper &ObjCTypes) {
2746 CodeGenTypes &Types = CGM.
getTypes();
2748 llvm::Value *ReceiverValue =
2749 llvm::PoisonValue::get(Types.
ConvertType(Arg0Ty));
2750 llvm::Value *SelValue = llvm::UndefValue::get(Types.
ConvertType(selTy));
2752 CallArgList ActualArgs;
2754 Arg0 = CGF.
Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy);
2761 MessageSendInfo MSI = getMessageSendInfo(
Method, ResultType, ActualArgs);
2766 "Result type mismatch!");
2768 bool ReceiverCanBeNull =
2769 canMessageReceiverBeNull(CGF,
Method, IsSuper, ClassReceiver, Arg0);
2770 bool ClassObjectCanBeUnrealized =
2772 canClassObjectBeUnrealized(ClassReceiver, CGF);
2774 bool RequiresNullCheck =
false;
2775 bool RequiresReceiverValue =
true;
2776 bool RequiresSelValue =
true;
2778 llvm::FunctionCallee
Fn =
nullptr;
2782 ReceiverCanBeNull, ClassObjectCanBeUnrealized);
2785 RequiresSelValue =
false;
2787 if (ReceiverCanBeNull)
2788 RequiresNullCheck =
true;
2789 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
2790 : ObjCTypes.getSendStretFn(IsSuper);
2792 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
2793 : ObjCTypes.getSendFpretFn(IsSuper);
2795 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)
2796 : ObjCTypes.getSendFp2retFn(IsSuper);
2801 RequiresNullCheck =
true;
2803 StringRef ClassName;
2809 if (CGM.
getCodeGenOpts().ObjCMsgSendClassSelectorStubs && ClassReceiver &&
2811 !ClassReceiver->
hasAttr<ObjCClassStubAttr>() &&
2812 !ClassReceiver->
hasAttr<ObjCRuntimeVisibleAttr>() &&
2816 bool UseClassStub = ClassName.data();
2819 (CGM.
getCodeGenOpts().ObjCMsgSendSelectorStubs || UseClassStub)) {
2820 Fn = GenerateMethodSelectorStub(Sel, ClassName, ObjCTypes);
2822 RequiresReceiverValue = !UseClassStub;
2823 RequiresSelValue =
false;
2825 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
2826 : ObjCTypes.getSendFn(IsSuper);
2832 CGF.
Builder.CreateBitCast(
Fn.getCallee(), MSI.MessengerType));
2837 RequiresNullCheck =
false;
2840 if (!RequiresNullCheck &&
Method &&
Method->hasParamDestroyedInCallee())
2841 RequiresNullCheck =
true;
2848 if (ClassReceiver && ClassObjectCanBeUnrealized) {
2850 Arg0 = GenerateClassRealization(CGF, Arg0, ClassReceiver);
2851 ActualArgs[0] = CallArg(
RValue::get(Arg0), ActualArgs[0].Ty);
2857 RequiresNullCheck |= ReceiverCanBeNull;
2860 NullReturnState nullReturn;
2861 if (RequiresNullCheck) {
2862 nullReturn.init(CGF, Arg0);
2866 if (RequiresReceiverValue)
2867 ActualArgs[0] = CallArg(
RValue::get(Arg0), Arg0Ty);
2870 if (RequiresSelValue) {
2871 SelValue = GetSelector(CGF, Sel);
2872 ActualArgs[1] = CallArg(
RValue::get(SelValue), selTy);
2875 llvm::CallBase *CallSite;
2878 CGF.
EmitCall(MSI.CallInfo, Callee, Return, ActualArgs, &CallSite);
2882 if (
Method &&
Method->hasAttr<NoReturnAttr>() && !ReceiverCanBeNull) {
2883 CallSite->setDoesNotReturn();
2886 return nullReturn.complete(CGF, Return, rvalue, ResultType, CallArgs,
2887 RequiresNullCheck ?
Method :
nullptr);
2891 bool pointee =
false) {
2905 switch (ownership) {
2913 llvm_unreachable(
"autoreleasing ivar?");
2915 llvm_unreachable(
"known nonzero");
2917 llvm_unreachable(
"bad objc ownership");
2937 IvarInfo(CharUnits offset, uint64_t sizeInWords)
2938 : Offset(offset), SizeInWords(sizeInWords) {}
2941 bool operator<(
const IvarInfo &other)
const {
return Offset < other.Offset; }
2945class IvarLayoutBuilder {
2950 CharUnits InstanceBegin;
2953 CharUnits InstanceEnd;
2956 bool ForStrongLayout;
2959 bool IsDisordered =
false;
2961 llvm::SmallVector<IvarInfo, 8> IvarsInfo;
2964 IvarLayoutBuilder(CodeGenModule &CGM, CharUnits instanceBegin,
2965 CharUnits instanceEnd,
bool forStrongLayout)
2966 : CGM(CGM), InstanceBegin(instanceBegin), InstanceEnd(instanceEnd),
2967 ForStrongLayout(forStrongLayout) {}
2969 void visitRecord(
const RecordType *RT, CharUnits offset);
2971 template <
class Iterator,
class GetOffsetFn>
2972 void visitAggregate(Iterator begin, Iterator end, CharUnits aggrOffset,
2973 const GetOffsetFn &getOffset);
2975 void visitField(
const FieldDecl *field, CharUnits offset);
2978 void visitBlock(
const CGBlockInfo &blockInfo);
2981 bool hasBitmapData()
const {
return !IvarsInfo.empty(); }
2983 llvm::Constant *buildBitmap(CGObjCCommonMac &CGObjC,
2984 llvm::SmallVectorImpl<unsigned char> &buffer);
2986 static void dump(ArrayRef<unsigned char> buffer) {
2987 const unsigned char *
s = buffer.data();
2988 for (
unsigned i = 0, e = buffer.size(); i < e; i++)
2990 printf(
"0x0%x%s",
s[i],
s[i] != 0 ?
", " :
"");
2992 printf(
"0x%x%s",
s[i],
s[i] != 0 ?
", " :
"");
2999CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,
3000 const CGBlockInfo &blockInfo) {
3002 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
3003 if (CGM.
getLangOpts().getGC() == LangOptions::NonGC)
3009 builder.visitBlock(blockInfo);
3011 if (!builder.hasBitmapData())
3014 llvm::SmallVector<unsigned char, 32> buffer;
3015 llvm::Constant *
C = builder.buildBitmap(*
this, buffer);
3016 if (CGM.
getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
3017 printf(
"\n block variable layout for block: ");
3018 builder.dump(buffer);
3024void IvarLayoutBuilder::visitBlock(
const CGBlockInfo &blockInfo) {
3034 CharUnits lastFieldOffset;
3037 for (
const auto &CI :
blockDecl->captures()) {
3038 const VarDecl *variable = CI.getVariable();
3041 const CGBlockInfo::Capture &capture = blockInfo.
getCapture(variable);
3047 CharUnits fieldOffset = capture.
getOffset();
3051 if (fieldOffset < lastFieldOffset)
3052 IsDisordered =
true;
3053 lastFieldOffset = fieldOffset;
3057 IvarsInfo.push_back(IvarInfo(fieldOffset, 1));
3061 assert(!
type->isArrayType() &&
"array variable should not be caught");
3062 if (
const RecordType *record =
type->getAsCanonical<RecordType>()) {
3063 visitRecord(record, fieldOffset);
3072 IvarsInfo.push_back(IvarInfo(fieldOffset, 1));
3081CGObjCCommonMac::getBlockCaptureLifetime(QualType FQT,
bool ByrefLayout) {
3097void CGObjCCommonMac::UpdateRunSkipBlockVars(
bool IsByref,
3099 CharUnits FieldOffset,
3100 CharUnits FieldSize) {
3103 RunSkipBlockVars.push_back(
3104 RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset, FieldSize));
3106 RunSkipBlockVars.push_back(
3107 RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset, FieldSize));
3109 RunSkipBlockVars.push_back(
3110 RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset, FieldSize));
3112 RunSkipBlockVars.push_back(
3113 RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset, FieldSize));
3115 RunSkipBlockVars.push_back(
3116 RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES, FieldOffset, FieldSize));
3119void CGObjCCommonMac::BuildRCRecordLayout(
const llvm::StructLayout *RecLayout,
3120 const RecordDecl *RD,
3121 ArrayRef<const FieldDecl *> RecFields,
3122 CharUnits BytePos,
bool &HasUnion,
3124 bool IsUnion = (RD && RD->
isUnion());
3126 const FieldDecl *MaxField =
nullptr;
3127 const FieldDecl *LastFieldBitfieldOrUnnamed =
nullptr;
3131 if (RecFields.empty())
3135 for (
unsigned i = 0, e = RecFields.size(); i != e; ++i) {
3136 const FieldDecl *
Field = RecFields[i];
3140 CharUnits FieldOffset =
3144 if (!
Field->getIdentifier() ||
Field->isBitField()) {
3145 LastFieldBitfieldOrUnnamed =
Field;
3146 LastBitfieldOrUnnamedOffset = FieldOffset;
3150 LastFieldBitfieldOrUnnamed =
nullptr;
3151 QualType FQT =
Field->getType();
3157 BytePos + FieldOffset, HasUnion);
3163 uint64_t ElCount = CArray->getZExtSize();
3164 assert(CArray &&
"only array with known element size is supported");
3165 FQT = CArray->getElementType();
3168 ElCount *= CArray->getZExtSize();
3169 FQT = CArray->getElementType();
3172 int OldIndex = RunSkipBlockVars.size() - 1;
3174 BuildRCBlockVarRecordLayout(RT, BytePos + FieldOffset, HasUnion);
3179 for (
int FirstIndex = RunSkipBlockVars.size() - 1; ElIx < ElCount;
3182 for (
int i = OldIndex + 1; i <= FirstIndex; ++i)
3183 RunSkipBlockVars.push_back(
3184 RUN_SKIP(RunSkipBlockVars[i].opcode,
3185 RunSkipBlockVars[i].block_var_bytepos + Size * ElIx,
3186 RunSkipBlockVars[i].block_var_size));
3193 CharUnits UnionIvarSize = FieldSize;
3194 if (UnionIvarSize > MaxUnionSize) {
3195 MaxUnionSize = UnionIvarSize;
3197 MaxFieldOffset = FieldOffset;
3200 UpdateRunSkipBlockVars(
false, getBlockCaptureLifetime(FQT, ByrefLayout),
3201 BytePos + FieldOffset, FieldSize);
3205 if (LastFieldBitfieldOrUnnamed) {
3206 if (LastFieldBitfieldOrUnnamed->
isBitField()) {
3209 unsigned UnsSize = (BitFieldSize / ByteSizeInBits) +
3210 ((BitFieldSize % ByteSizeInBits) != 0);
3212 Size += LastBitfieldOrUnnamedOffset;
3213 UpdateRunSkipBlockVars(
3215 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
3217 BytePos + LastBitfieldOrUnnamedOffset, Size);
3220 "Expected unnamed");
3223 LastFieldBitfieldOrUnnamed->
getType());
3224 UpdateRunSkipBlockVars(
3226 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
3228 BytePos + LastBitfieldOrUnnamedOffset, FieldSize);
3233 UpdateRunSkipBlockVars(
3234 false, getBlockCaptureLifetime(MaxField->
getType(), ByrefLayout),
3235 BytePos + MaxFieldOffset, MaxUnionSize);
3238void CGObjCCommonMac::BuildRCBlockVarRecordLayout(
const RecordType *RT,
3242 const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
3243 SmallVector<const FieldDecl *, 16> Fields(RD->
fields());
3245 const llvm::StructLayout *RecLayout =
3248 BuildRCRecordLayout(RecLayout, RD, Fields, BytePos, HasUnion, ByrefLayout);
3260uint64_t CGObjCCommonMac::InlineLayoutInstruction(
3261 SmallVectorImpl<unsigned char> &Layout) {
3263 if (Layout.size() <= 3) {
3264 unsigned size = Layout.size();
3265 unsigned strong_word_count = 0, byref_word_count = 0, weak_word_count = 0;
3267 enum BLOCK_LAYOUT_OPCODE opcode;
3271 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3272 if (opcode == BLOCK_LAYOUT_STRONG)
3273 strong_word_count = (inst & 0xF) + 1;
3277 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3278 if (opcode == BLOCK_LAYOUT_BYREF)
3279 byref_word_count = (inst & 0xF) + 1;
3283 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3284 if (opcode == BLOCK_LAYOUT_WEAK)
3285 weak_word_count = (inst & 0xF) + 1;
3292 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3293 if (opcode == BLOCK_LAYOUT_STRONG) {
3294 strong_word_count = (inst & 0xF) + 1;
3296 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3297 if (opcode == BLOCK_LAYOUT_BYREF)
3298 byref_word_count = (inst & 0xF) + 1;
3299 else if (opcode == BLOCK_LAYOUT_WEAK)
3300 weak_word_count = (inst & 0xF) + 1;
3303 }
else if (opcode == BLOCK_LAYOUT_BYREF) {
3304 byref_word_count = (inst & 0xF) + 1;
3306 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3307 if (opcode == BLOCK_LAYOUT_WEAK)
3308 weak_word_count = (inst & 0xF) + 1;
3317 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3318 if (opcode == BLOCK_LAYOUT_STRONG)
3319 strong_word_count = (inst & 0xF) + 1;
3320 else if (opcode == BLOCK_LAYOUT_BYREF)
3321 byref_word_count = (inst & 0xF) + 1;
3322 else if (opcode == BLOCK_LAYOUT_WEAK)
3323 weak_word_count = (inst & 0xF) + 1;
3335 if (strong_word_count == 16 || byref_word_count == 16 ||
3336 weak_word_count == 16)
3339 unsigned count = (strong_word_count != 0) + (byref_word_count != 0) +
3340 (weak_word_count != 0);
3342 if (size == count) {
3343 if (strong_word_count)
3344 Result = strong_word_count;
3346 if (byref_word_count)
3347 Result += byref_word_count;
3349 if (weak_word_count)
3350 Result += weak_word_count;
3356llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(
bool ComputeByrefLayout) {
3357 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
3358 if (RunSkipBlockVars.empty())
3362 unsigned WordSizeInBytes = WordSizeInBits / ByteSizeInBits;
3366 llvm::array_pod_sort(RunSkipBlockVars.begin(), RunSkipBlockVars.end());
3367 SmallVector<unsigned char, 16> Layout;
3369 unsigned size = RunSkipBlockVars.size();
3370 for (
unsigned i = 0; i < size; i++) {
3371 enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode;
3372 CharUnits start_byte_pos = RunSkipBlockVars[i].block_var_bytepos;
3373 CharUnits end_byte_pos = start_byte_pos;
3376 if (opcode == RunSkipBlockVars[j].opcode) {
3377 end_byte_pos = RunSkipBlockVars[j++].block_var_bytepos;
3382 CharUnits size_in_bytes =
3383 end_byte_pos - start_byte_pos + RunSkipBlockVars[j - 1].block_var_size;
3385 CharUnits gap = RunSkipBlockVars[j].block_var_bytepos -
3386 RunSkipBlockVars[j - 1].block_var_bytepos -
3387 RunSkipBlockVars[j - 1].block_var_size;
3388 size_in_bytes += gap;
3391 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) {
3392 residue_in_bytes = size_in_bytes % WordSizeInBytes;
3393 size_in_bytes -= residue_in_bytes;
3394 opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS;
3397 unsigned size_in_words = size_in_bytes.
getQuantity() / WordSizeInBytes;
3398 while (size_in_words >= 16) {
3401 unsigned char inst = (opcode << 4) | 0xf;
3402 Layout.push_back(inst);
3403 size_in_words -= 16;
3405 if (size_in_words > 0) {
3408 unsigned char inst = (opcode << 4) | (size_in_words - 1);
3409 Layout.push_back(inst);
3412 unsigned char inst = (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) |
3414 Layout.push_back(inst);
3418 while (!Layout.empty()) {
3419 unsigned char inst = Layout.back();
3420 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3421 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES ||
3422 opcode == BLOCK_LAYOUT_NON_OBJECT_WORDS)
3432 if (ComputeByrefLayout)
3433 printf(
"\n Inline BYREF variable layout: ");
3435 printf(
"\n Inline block variable layout: ");
3437 if (
auto numStrong = (
Result & 0xF00) >> 8)
3438 printf(
", BL_STRONG:%d", (
int)numStrong);
3439 if (
auto numByref = (
Result & 0x0F0) >> 4)
3440 printf(
", BL_BYREF:%d", (
int)numByref);
3441 if (
auto numWeak = (
Result & 0x00F) >> 0)
3442 printf(
", BL_WEAK:%d", (
int)numWeak);
3443 printf(
", BL_OPERATOR:0\n");
3448 unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0;
3449 Layout.push_back(inst);
3451 for (
unsigned char C : Layout)
3455 if (ComputeByrefLayout)
3456 printf(
"\n Byref variable layout: ");
3458 printf(
"\n Block variable layout: ");
3459 for (
unsigned i = 0, e = BitMap.size(); i != e; i++) {
3460 unsigned char inst = BitMap[i];
3461 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3464 case BLOCK_LAYOUT_OPERATOR:
3468 case BLOCK_LAYOUT_NON_OBJECT_BYTES:
3469 printf(
"BL_NON_OBJECT_BYTES:");
3471 case BLOCK_LAYOUT_NON_OBJECT_WORDS:
3472 printf(
"BL_NON_OBJECT_WORD:");
3474 case BLOCK_LAYOUT_STRONG:
3477 case BLOCK_LAYOUT_BYREF:
3480 case BLOCK_LAYOUT_WEAK:
3483 case BLOCK_LAYOUT_UNRETAINED:
3484 printf(
"BL_UNRETAINED:");
3489 printf(
"%d", (inst & 0xf) + delta);
3497 auto *Entry = CreateCStringLiteral(BitMap, ObjCLabelType::LayoutBitMap,
3505 bool HasCopyDisposeHelpers) {
3507 for (
const CGObjCCommonMac::RUN_SKIP &R : RunSkipBlockVars) {
3508 if (R.opcode == CGObjCCommonMac::BLOCK_LAYOUT_UNRETAINED) {
3512 }
else if (HasCopyDisposeHelpers) {
3520 case CGObjCCommonMac::BLOCK_LAYOUT_STRONG:
3523 case CGObjCCommonMac::BLOCK_LAYOUT_BYREF:
3526 case CGObjCCommonMac::BLOCK_LAYOUT_WEAK:
3533 Str += llvm::to_string(R.block_var_bytepos.getQuantity());
3534 Str +=
"l" + llvm::to_string(R.block_var_size.getQuantity());
3539void CGObjCCommonMac::fillRunSkipBlockVars(CodeGenModule &CGM,
3540 const CGBlockInfo &blockInfo) {
3541 assert(CGM.
getLangOpts().getGC() == LangOptions::NonGC);
3543 RunSkipBlockVars.clear();
3544 bool hasUnion =
false;
3548 unsigned WordSizeInBytes = WordSizeInBits / ByteSizeInBits;
3553 const llvm::StructLayout *layout =
3563 for (
const auto &CI :
blockDecl->captures()) {
3564 const VarDecl *variable = CI.getVariable();
3567 const CGBlockInfo::Capture &capture = blockInfo.
getCapture(variable);
3573 CharUnits fieldOffset =
3576 assert(!
type->isArrayType() &&
"array variable should not be caught");
3578 if (
const auto *record =
type->getAsCanonical<RecordType>()) {
3579 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion);
3582 CharUnits fieldSize;
3587 UpdateRunSkipBlockVars(CI.isByRef(), getBlockCaptureLifetime(
type,
false),
3588 fieldOffset, fieldSize);
3593CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM,
3594 const CGBlockInfo &blockInfo) {
3595 fillRunSkipBlockVars(CGM, blockInfo);
3596 return getBitmapBlockLayout(
false);
3599std::string CGObjCCommonMac::getRCBlockLayoutStr(CodeGenModule &CGM,
3600 const CGBlockInfo &blockInfo) {
3601 fillRunSkipBlockVars(CGM, blockInfo);
3605llvm::Constant *CGObjCCommonMac::BuildByrefLayout(CodeGen::CodeGenModule &CGM,
3607 assert(CGM.
getLangOpts().getGC() == LangOptions::NonGC);
3608 assert(!T->
isArrayType() &&
"__block array variable should not be caught");
3609 CharUnits fieldOffset;
3610 RunSkipBlockVars.clear();
3611 bool hasUnion =
false;
3613 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion,
3615 llvm::Constant *
Result = getBitmapBlockLayout(
true);
3620 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
3624llvm::Value *CGObjCMac::GenerateProtocolRef(CodeGenFunction &CGF,
3625 const ObjCProtocolDecl *PD) {
3630 return GetProtocolRef(PD);
3633void CGObjCCommonMac::GenerateProtocol(
const ObjCProtocolDecl *PD) {
3642 GetOrEmitProtocol(PD);
3645llvm::Constant *CGObjCCommonMac::GetProtocolRef(
const ObjCProtocolDecl *PD) {
3647 return GetOrEmitProtocol(PD);
3649 return GetOrEmitProtocolRef(PD);
3653CGObjCCommonMac::EmitClassRefViaRuntime(CodeGenFunction &CGF,
3654 const ObjCInterfaceDecl *ID,
3655 ObjCCommonTypesHelper &ObjCTypes) {
3656 llvm::FunctionCallee lookUpClassFn = ObjCTypes.getLookUpClassFn();
3658 llvm::Value *className = CGF.
CGM
3660 ID->getObjCRuntimeNameAsString()))
3663 className = CGF.
Builder.CreateBitCast(
3665 llvm::CallInst *call = CGF.
Builder.CreateCall(lookUpClassFn, className);
3666 call->setDoesNotThrow();
3682llvm::Constant *CGObjCMac::GetOrEmitProtocol(
const ObjCProtocolDecl *PD) {
3683 llvm::GlobalVariable *Entry = Protocols[PD->
getIdentifier()];
3686 if (Entry && Entry->hasInitializer())
3698 auto methodLists = ProtocolMethodLists::get(PD);
3700 ConstantInitBuilder builder(CGM);
3701 auto values = builder.beginStruct(ObjCTypes.ProtocolTy);
3702 values.add(EmitProtocolExtension(PD, methodLists));
3704 values.add(EmitProtocolList(
"OBJC_PROTOCOL_REFS_" + PD->
getName(),
3706 values.add(methodLists.emitMethodList(
3707 this, PD, ProtocolMethodLists::RequiredInstanceMethods));
3708 values.add(methodLists.emitMethodList(
3709 this, PD, ProtocolMethodLists::RequiredClassMethods));
3713 assert(Entry->hasPrivateLinkage());
3714 values.finishAndSetAsInitializer(Entry);
3716 Entry = values.finishAndCreateGlobal(
3718 false, llvm::GlobalValue::PrivateLinkage);
3719 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
3728llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD) {
3729 llvm::GlobalVariable *&Entry = Protocols[PD->
getIdentifier()];
3735 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolTy,
3736 false, llvm::GlobalValue::PrivateLinkage,
3737 nullptr,
"OBJC_PROTOCOL_" + PD->
getName());
3738 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
3740 Entry->setAlignment(llvm::Align(4));
3757CGObjCMac::EmitProtocolExtension(
const ObjCProtocolDecl *PD,
3758 const ProtocolMethodLists &methodLists) {
3759 auto optInstanceMethods = methodLists.emitMethodList(
3760 this, PD, ProtocolMethodLists::OptionalInstanceMethods);
3761 auto optClassMethods = methodLists.emitMethodList(
3762 this, PD, ProtocolMethodLists::OptionalClassMethods);
3764 auto extendedMethodTypes = EmitProtocolMethodTypes(
3765 "OBJC_PROTOCOL_METHOD_TYPES_" + PD->
getName(),
3766 methodLists.emitExtendedTypesArray(
this), ObjCTypes);
3768 auto instanceProperties = EmitPropertyList(
3769 "OBJC_$_PROP_PROTO_LIST_" + PD->
getName(),
nullptr, PD, ObjCTypes,
false);
3770 auto classProperties =
3771 EmitPropertyList(
"OBJC_$_CLASS_PROP_PROTO_LIST_" + PD->
getName(),
nullptr,
3772 PD, ObjCTypes,
true);
3775 if (optInstanceMethods->isNullValue() && optClassMethods->isNullValue() &&
3776 extendedMethodTypes->isNullValue() && instanceProperties->isNullValue() &&
3777 classProperties->isNullValue()) {
3778 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
3782 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
3784 ConstantInitBuilder builder(CGM);
3785 auto values = builder.beginStruct(ObjCTypes.ProtocolExtensionTy);
3786 values.addInt(ObjCTypes.IntTy, size);
3787 values.add(optInstanceMethods);
3788 values.add(optClassMethods);
3789 values.add(instanceProperties);
3790 values.add(extendedMethodTypes);
3791 values.add(classProperties);
3794 return CreateMetadataVar(
"_OBJC_PROTOCOLEXT_" + PD->
getName(), values,
3806CGObjCMac::EmitProtocolList(Twine name,
3810 auto PDs = GetRuntimeProtocolList(begin, end);
3812 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
3814 ConstantInitBuilder builder(CGM);
3815 auto values = builder.beginStruct();
3818 values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
3821 auto countSlot = values.addPlaceholder();
3823 auto refsArray = values.beginArray(ObjCTypes.ProtocolPtrTy);
3824 for (
const auto *Proto : PDs)
3825 refsArray.add(GetProtocolRef(Proto));
3827 auto count = refsArray.size();
3830 refsArray.addNullPointer(ObjCTypes.ProtocolPtrTy);
3832 refsArray.finishAndAddTo(values);
3833 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
3836 if (CGM.
getTriple().isOSBinFormatMachO())
3837 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3839 llvm::GlobalVariable *GV =
3840 CreateMetadataVar(name, values, section, CGM.
getPointerAlign(),
false);
3849 if (IsClassProperty != PD->isClassProperty())
3853 Properties.push_back(PD);
3856 for (
const auto *P : Proto->
protocols())
3872llvm::Constant *CGObjCCommonMac::EmitPropertyList(
3873 Twine Name,
const Decl *Container,
const ObjCContainerDecl *OCD,
3874 const ObjCCommonTypesHelper &ObjCTypes,
bool IsClassProperty) {
3875 if (IsClassProperty) {
3879 if ((Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 11)) ||
3880 (Triple.isiOS() && Triple.isOSVersionLT(9)))
3881 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3884 SmallVector<const ObjCPropertyDecl *, 16> Properties;
3885 llvm::SmallPtrSet<const IdentifierInfo *, 16> PropertySet;
3887 if (
const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD))
3888 for (
const ObjCCategoryDecl *ClassExt : OID->known_extensions())
3889 for (
auto *PD : ClassExt->properties()) {
3890 if (IsClassProperty != PD->isClassProperty())
3892 if (PD->isDirectProperty())
3895 Properties.push_back(PD);
3899 if (IsClassProperty != PD->isClassProperty())
3905 if (PD->isDirectProperty())
3907 Properties.push_back(PD);
3910 if (
const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) {
3911 for (
const auto *P : OID->all_referenced_protocols())
3913 }
else if (
const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD)) {
3914 for (
const auto *P : CD->protocols())
3919 if (Properties.empty())
3920 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3922 unsigned propertySize =
3925 ConstantInitBuilder builder(CGM);
3926 auto values = builder.beginStruct();
3927 values.addInt(ObjCTypes.IntTy, propertySize);
3928 values.addInt(ObjCTypes.IntTy, Properties.size());
3929 auto propertiesArray = values.beginArray(ObjCTypes.PropertyTy);
3930 for (
auto PD : Properties) {
3931 auto property = propertiesArray.beginStruct(ObjCTypes.PropertyTy);
3933 property.add(GetPropertyTypeString(PD, Container));
3934 property.finishAndAddTo(propertiesArray);
3936 propertiesArray.finishAndAddTo(values);
3939 if (CGM.
getTriple().isOSBinFormatMachO())
3940 Section = (ObjCABI == 2) ?
"__DATA, __objc_const"
3941 :
"__OBJC,__property,regular,no_dead_strip";
3943 llvm::GlobalVariable *GV =
3944 CreateMetadataVar(Name, values, Section, CGM.
getPointerAlign(),
true);
3948llvm::Constant *CGObjCCommonMac::EmitProtocolMethodTypes(
3949 Twine Name, ArrayRef<llvm::Constant *> MethodTypes,
3950 const ObjCCommonTypesHelper &ObjCTypes) {
3952 if (MethodTypes.empty())
3953 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy);
3955 llvm::ArrayType *AT =
3956 llvm::ArrayType::get(ObjCTypes.Int8PtrTy, MethodTypes.size());
3957 llvm::Constant *
Init = llvm::ConstantArray::get(AT, MethodTypes);
3960 if (CGM.
getTriple().isOSBinFormatMachO() && ObjCABI == 2)
3961 Section =
"__DATA, __objc_const";
3963 llvm::GlobalVariable *GV =
3980void CGObjCMac::GenerateCategory(
const ObjCCategoryImplDecl *OCD) {
3988 const ObjCCategoryDecl *Category =
3991 SmallString<256> ExtName;
3992 llvm::raw_svector_ostream(ExtName)
3995 ConstantInitBuilder Builder(CGM);
3996 auto Values = Builder.beginStruct(ObjCTypes.CategoryTy);
3998 enum { InstanceMethods, ClassMethods, NumMethodLists };
3999 SmallVector<const ObjCMethodDecl *, 16> Methods[NumMethodLists];
4000 for (
const auto *MD : OCD->
methods()) {
4001 if (!MD->isDirectMethod())
4002 Methods[unsigned(MD->isClassMethod())].push_back(MD);
4005 Values.add(GetClassName(OCD->
getName()));
4006 Values.add(GetClassName(
Interface->getObjCRuntimeNameAsString()));
4007 LazySymbols.insert(
Interface->getIdentifier());
4009 Values.add(emitMethodList(ExtName, MethodListType::CategoryInstanceMethods,
4010 Methods[InstanceMethods]));
4011 Values.add(emitMethodList(ExtName, MethodListType::CategoryClassMethods,
4012 Methods[ClassMethods]));
4014 Values.add(EmitProtocolList(
"OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
4015 Category->protocol_begin(),
4016 Category->protocol_end()));
4018 Values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
4020 Values.addInt(ObjCTypes.IntTy, Size);
4024 Values.add(EmitPropertyList(
"_OBJC_$_PROP_LIST_" + ExtName.str(), OCD,
4025 Category, ObjCTypes,
false));
4026 Values.add(EmitPropertyList(
"_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(), OCD,
4027 Category, ObjCTypes,
true));
4029 Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
4030 Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
4033 llvm::GlobalVariable *GV = CreateMetadataVar(
4034 "OBJC_CATEGORY_" + ExtName.str(), Values,
4035 "__OBJC,__category,regular,no_dead_strip", CGM.
getPointerAlign(),
true);
4036 DefinedCategories.push_back(GV);
4037 DefinedCategoryNames.insert(llvm::CachedHashString(ExtName));
4039 MethodDefinitions.clear();
4100 if (
auto *RD =
type->getAsRecordDecl()) {
4101 for (
auto *field : RD->
fields()) {
4120 ID->getClassInterface()->all_declared_ivar_begin();
4148void CGObjCMac::GenerateClass(
const ObjCImplementationDecl *ID) {
4149 IdentifierInfo *RuntimeName =
4151 DefinedSymbols.insert(RuntimeName);
4153 std::string ClassName =
ID->getNameAsString();
4156 const_cast<ObjCInterfaceDecl *
>(
ID->getClassInterface());
4157 llvm::Constant *Protocols =
4158 EmitProtocolList(
"OBJC_CLASS_PROTOCOLS_" +
ID->getName(),
4159 Interface->all_referenced_protocol_begin(),
4160 Interface->all_referenced_protocol_end());
4162 if (
ID->hasNonZeroConstructors() ||
ID->hasDestructors())
4165 bool hasMRCWeak =
false;
4180 enum { InstanceMethods, ClassMethods, NumMethodLists };
4181 SmallVector<const ObjCMethodDecl *, 16> Methods[NumMethodLists];
4182 for (
const auto *MD :
ID->methods()) {
4183 if (!MD->isDirectMethod())
4184 Methods[unsigned(MD->isClassMethod())].push_back(MD);
4187 for (
const auto *PID :
ID->property_impls()) {
4189 if (PID->getPropertyDecl()->isDirectProperty())
4191 if (ObjCMethodDecl *MD = PID->getGetterMethodDecl())
4192 if (GetMethodDefinition(MD))
4193 Methods[InstanceMethods].push_back(MD);
4194 if (ObjCMethodDecl *MD = PID->getSetterMethodDecl())
4195 if (GetMethodDefinition(MD))
4196 Methods[InstanceMethods].push_back(MD);
4200 ConstantInitBuilder builder(CGM);
4201 auto values = builder.beginStruct(ObjCTypes.ClassTy);
4202 values.add(EmitMetaClass(ID, Protocols, Methods[ClassMethods]));
4203 if (ObjCInterfaceDecl *Super =
Interface->getSuperClass()) {
4205 LazySymbols.insert(Super->getIdentifier());
4207 values.add(GetClassName(Super->getObjCRuntimeNameAsString()));
4209 values.addNullPointer(ObjCTypes.ClassPtrTy);
4211 values.add(GetClassName(
ID->getObjCRuntimeNameAsString()));
4213 values.addInt(ObjCTypes.LongTy, 0);
4214 values.addInt(ObjCTypes.LongTy, Flags);
4215 values.addInt(ObjCTypes.LongTy,
Size.getQuantity());
4216 values.add(EmitIvarList(ID,
false));
4217 values.add(emitMethodList(
ID->getName(), MethodListType::InstanceMethods,
4218 Methods[InstanceMethods]));
4220 values.addNullPointer(ObjCTypes.CachePtrTy);
4221 values.add(Protocols);
4223 values.add(EmitClassExtension(ID, Size, hasMRCWeak,
4226 std::string Name(
"OBJC_CLASS_");
4228 const char *Section =
"__OBJC,__class,regular,no_dead_strip";
4230 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
4232 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4233 "Forward metaclass reference has incorrect type.");
4234 values.finishAndSetAsInitializer(GV);
4235 GV->setSection(Section);
4239 GV = CreateMetadataVar(Name, values, Section, CGM.
getPointerAlign(),
true);
4240 DefinedClasses.push_back(GV);
4241 ImplementedClasses.push_back(
Interface);
4243 MethodDefinitions.clear();
4247CGObjCMac::EmitMetaClass(
const ObjCImplementationDecl *ID,
4248 llvm::Constant *Protocols,
4249 ArrayRef<const ObjCMethodDecl *> Methods) {
4256 ConstantInitBuilder builder(CGM);
4257 auto values = builder.beginStruct(ObjCTypes.ClassTy);
4259 const ObjCInterfaceDecl *Root =
ID->getClassInterface();
4260 while (
const ObjCInterfaceDecl *Super = Root->
getSuperClass())
4266 if (ObjCInterfaceDecl *Super =
ID->getClassInterface()->getSuperClass()) {
4267 values.add(GetClassName(Super->getObjCRuntimeNameAsString()));
4269 values.addNullPointer(ObjCTypes.ClassPtrTy);
4271 values.add(GetClassName(
ID->getObjCRuntimeNameAsString()));
4273 values.addInt(ObjCTypes.LongTy, 0);
4274 values.addInt(ObjCTypes.LongTy, Flags);
4275 values.addInt(ObjCTypes.LongTy, Size);
4276 values.add(EmitIvarList(ID,
true));
4278 emitMethodList(
ID->getName(), MethodListType::ClassMethods, Methods));
4280 values.addNullPointer(ObjCTypes.CachePtrTy);
4281 values.add(Protocols);
4283 values.addNullPointer(ObjCTypes.Int8PtrTy);
4288 std::string Name(
"OBJC_METACLASS_");
4289 Name +=
ID->getName();
4292 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
4294 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4295 "Forward metaclass reference has incorrect type.");
4296 values.finishAndSetAsInitializer(GV);
4300 llvm::GlobalValue::PrivateLinkage);
4302 GV->setSection(
"__OBJC,__meta_class,regular,no_dead_strip");
4308llvm::Constant *CGObjCMac::EmitMetaClassRef(
const ObjCInterfaceDecl *ID) {
4309 std::string Name =
"OBJC_METACLASS_" +
ID->getNameAsString();
4319 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
4321 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
4322 llvm::GlobalValue::PrivateLinkage,
nullptr,
4325 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4326 "Forward metaclass reference has incorrect type.");
4330llvm::Value *CGObjCMac::EmitSuperClassRef(
const ObjCInterfaceDecl *ID) {
4331 std::string Name =
"OBJC_CLASS_" +
ID->getNameAsString();
4332 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
4335 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
4336 llvm::GlobalValue::PrivateLinkage,
nullptr,
4339 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4340 "Forward class metadata reference has incorrect type.");
4355llvm::Constant *CGObjCMac::EmitClassExtension(
const ObjCImplementationDecl *ID,
4356 CharUnits InstanceSize,
4360 llvm::Constant *layout;
4362 layout = llvm::ConstantPointerNull::get(CGM.
Int8PtrTy);
4369 llvm::Constant *propertyList =
4370 EmitPropertyList((isMetaclass ? Twine(
"_OBJC_$_CLASS_PROP_LIST_")
4371 : Twine(
"_OBJC_$_PROP_LIST_")) +
4373 ID,
ID->getClassInterface(), ObjCTypes, isMetaclass);
4376 if (layout->isNullValue() && propertyList->isNullValue()) {
4377 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
4381 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
4383 ConstantInitBuilder builder(CGM);
4384 auto values = builder.beginStruct(ObjCTypes.ClassExtensionTy);
4385 values.addInt(ObjCTypes.IntTy, size);
4387 values.add(propertyList);
4389 return CreateMetadataVar(
"OBJC_CLASSEXT_" +
ID->getName(), values,
4390 "__OBJC,__class_ext,regular,no_dead_strip",
4406llvm::Constant *CGObjCMac::EmitIvarList(
const ObjCImplementationDecl *ID,
4414 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
4416 const ObjCInterfaceDecl *OID =
ID->getClassInterface();
4418 ConstantInitBuilder builder(CGM);
4419 auto ivarList = builder.beginStruct();
4420 auto countSlot = ivarList.addPlaceholder();
4421 auto ivars = ivarList.beginArray(ObjCTypes.IvarTy);
4426 if (!IVD->getDeclName())
4429 auto ivar = ivars.beginStruct(ObjCTypes.IvarTy);
4430 ivar.add(GetMethodVarName(IVD->getIdentifier()));
4431 ivar.add(GetMethodVarType(IVD));
4432 ivar.addInt(ObjCTypes.IntTy, ComputeIvarBaseOffset(CGM, OID, IVD));
4433 ivar.finishAndAddTo(ivars);
4437 auto count = ivars.size();
4441 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
4444 ivars.finishAndAddTo(ivarList);
4445 ivarList.fillPlaceholderWithInt(countSlot, ObjCTypes.IntTy, count);
4447 llvm::GlobalVariable *GV;
4448 GV = CreateMetadataVar(
"OBJC_INSTANCE_VARIABLES_" +
ID->getName(), ivarList,
4449 "__OBJC,__instance_vars,regular,no_dead_strip",
4460void CGObjCMac::emitMethodDescriptionConstant(ConstantArrayBuilder &builder,
4461 const ObjCMethodDecl *MD) {
4462 auto description = builder.
beginStruct(ObjCTypes.MethodDescriptionTy);
4463 description.add(GetMethodVarName(MD->
getSelector()));
4464 description.add(GetMethodVarType(MD));
4465 description.finishAndAddTo(builder);
4475void CGObjCMac::emitMethodConstant(ConstantArrayBuilder &builder,
4476 const ObjCMethodDecl *MD) {
4477 llvm::Function *fn = GetMethodDefinition(MD);
4478 assert(fn &&
"no definition registered for method");
4480 auto method = builder.
beginStruct(ObjCTypes.MethodTy);
4482 method.add(GetMethodVarType(MD));
4484 method.finishAndAddTo(builder);
4501CGObjCMac::emitMethodList(Twine name, MethodListType MLT,
4502 ArrayRef<const ObjCMethodDecl *> methods) {
4505 bool forProtocol =
false;
4507 case MethodListType::CategoryInstanceMethods:
4508 prefix =
"OBJC_CATEGORY_INSTANCE_METHODS_";
4509 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
4510 forProtocol =
false;
4512 case MethodListType::CategoryClassMethods:
4513 prefix =
"OBJC_CATEGORY_CLASS_METHODS_";
4514 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
4515 forProtocol =
false;
4517 case MethodListType::InstanceMethods:
4518 prefix =
"OBJC_INSTANCE_METHODS_";
4519 section =
"__OBJC,__inst_meth,regular,no_dead_strip";
4520 forProtocol =
false;
4522 case MethodListType::ClassMethods:
4523 prefix =
"OBJC_CLASS_METHODS_";
4524 section =
"__OBJC,__cls_meth,regular,no_dead_strip";
4525 forProtocol =
false;
4527 case MethodListType::ProtocolInstanceMethods:
4528 prefix =
"OBJC_PROTOCOL_INSTANCE_METHODS_";
4529 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
4532 case MethodListType::ProtocolClassMethods:
4533 prefix =
"OBJC_PROTOCOL_CLASS_METHODS_";
4534 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
4537 case MethodListType::OptionalProtocolInstanceMethods:
4538 prefix =
"OBJC_PROTOCOL_INSTANCE_METHODS_OPT_";
4539 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
4542 case MethodListType::OptionalProtocolClassMethods:
4543 prefix =
"OBJC_PROTOCOL_CLASS_METHODS_OPT_";
4544 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
4550 if (methods.empty())
4551 return llvm::Constant::getNullValue(
4552 forProtocol ? ObjCTypes.MethodDescriptionListPtrTy
4553 : ObjCTypes.MethodListPtrTy);
4558 ConstantInitBuilder builder(CGM);
4560 values.addInt(ObjCTypes.IntTy, methods.size());
4561 auto methodArray = values.beginArray(ObjCTypes.MethodDescriptionTy);
4562 for (
auto MD : methods) {
4563 emitMethodDescriptionConstant(methodArray, MD);
4565 methodArray.finishAndAddTo(values);
4567 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
4573 ConstantInitBuilder builder(CGM);
4575 values.addNullPointer(ObjCTypes.Int8PtrTy);
4576 values.addInt(ObjCTypes.IntTy, methods.size());
4577 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
4578 for (
auto MD : methods) {
4580 emitMethodConstant(methodArray, MD);
4582 methodArray.finishAndAddTo(values);
4584 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
4589llvm::Function *CGObjCCommonMac::GenerateMethod(
const ObjCMethodDecl *OMD,
4590 const ObjCContainerDecl *CD) {
4595 DirectMethodInfo &Info = GenerateDirectMethod(OMD, CD);
4596 Method = Info.Implementation;
4598 auto Name = getSymbolNameForMethod(OMD);
4600 CodeGenTypes &Types = CGM.
getTypes();
4601 llvm::FunctionType *MethodTy =
4603 Method = llvm::Function::Create(
4604 MethodTy, llvm::GlobalValue::InternalLinkage, Name, &CGM.
getModule());
4607 MethodDefinitions.insert(std::make_pair(OMD,
Method));
4613CGObjCCommonMac::DirectMethodInfo &
4614CGObjCCommonMac::GenerateDirectMethod(
const ObjCMethodDecl *OMD,
4615 const ObjCContainerDecl *CD) {
4620 auto Cached = DirectMethodDefinitions.find(COMD);
4621 if (Cached != DirectMethodDefinitions.end()) {
4623 return Cached->second;
4626 CodeGenTypes &Types = CGM.
getTypes();
4627 llvm::FunctionType *MethodTy =
4630 getSymbolNameForMethod(OMD,
false,
4632 std::string ThunkName = Name +
"_thunk";
4635 auto ReplaceFunction = [](llvm::Function *OldFn, llvm::Function *NewFn) {
4636 NewFn->takeName(OldFn);
4637 OldFn->replaceAllUsesWith(NewFn);
4638 OldFn->eraseFromParent();
4643 llvm::Function *
Fn = CGM.
getModule().getFunction(Name);
4647 Fn = llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,
4649 return DirectMethodDefinitions.insert({COMD, DirectMethodInfo(Fn)})
4655 if (
Fn->getFunctionType() == MethodTy) {
4657 Fn->setLinkage(llvm::GlobalValue::ExternalLinkage);
4660 DirectMethodInfo Info(Fn);
4661 if (llvm::Function *Thunk = CGM.
getModule().getFunction(ThunkName))
4664 return DirectMethodDefinitions.insert({COMD, Info}).first->second;
4670 llvm::Function *NewFn = llvm::Function::Create(
4671 MethodTy, llvm::GlobalValue::ExternalLinkage,
"", &CGM.
getModule());
4672 ReplaceFunction(Fn, NewFn);
4675 DirectMethodInfo Info(NewFn);
4676 if (llvm::Function *OldThunk = CGM.
getModule().getFunction(ThunkName)) {
4677 llvm::Function *NewThunk = GenerateObjCDirectThunk(OMD, CD, NewFn);
4678 ReplaceFunction(OldThunk, NewThunk);
4679 Info.Thunk = NewThunk;
4682 if (Cached != DirectMethodDefinitions.end()) {
4683 Cached->second = Info;
4684 return Cached->second;
4686 return DirectMethodDefinitions.insert({COMD, Info}).first->second;
4752CGObjCCommonMac::GenerateObjCDirectThunk(
const ObjCMethodDecl *OMD,
4754 llvm::Function *Implementation) {
4757 "Should only generate thunk when optimization enabled");
4758 assert(Implementation &&
"Implementation must exist");
4760 llvm::FunctionType *ThunkTy = Implementation->getFunctionType();
4761 std::string ThunkName = Implementation->getName().str() +
"_thunk";
4764 llvm::Function *Thunk =
4765 llvm::Function::Create(ThunkTy, llvm::GlobalValue::LinkOnceODRLinkage,
4772 Thunk->setVisibility(llvm::GlobalValue::HiddenVisibility);
4773 Thunk->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4792 GenerateDirectMethodsPreconditionCheck(CGF, Thunk, OMD, CD);
4797 for (
auto &Arg : Thunk->args())
4798 Args.push_back(&Arg);
4801 llvm::CallInst *
Call = CGF.
Builder.CreateCall(Implementation, Args);
4802 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
4809 llvm::AttributeList Attrs;
4813 Call->setAttributes(Attrs);
4814 Call->setCallingConv(
static_cast<llvm::CallingConv::ID
>(
CallingConv));
4819 if (ThunkTy->getReturnType()->isVoidTy())
4829llvm::Function *CGObjCCommonMac::GetDirectMethodCallee(
4831 bool ReceiverCanBeNull,
bool ClassObjectCanBeUnrealized) {
4836 DirectMethodInfo Info = GenerateDirectMethod(OMD, CD);
4842 return Info.Implementation;
4846 auto getOrCreateThunk = [&]() {
4848 Info.Thunk = GenerateObjCDirectThunk(OMD, CD, Info.Implementation);
4858 return ReceiverCanBeNull ? getOrCreateThunk() : Info.Implementation;
4861 "OMD should either be a class method or instance method");
4865 return (ReceiverCanBeNull || ClassObjectCanBeUnrealized)
4866 ? getOrCreateThunk()
4867 : Info.Implementation;
4871CGObjCCommonMac::GenerateClassRealization(CodeGenFunction &CGF,
4872 llvm::Value *classObject,
4873 const ObjCInterfaceDecl *OID) {
4880 RValue result = GeneratePossiblySpecializedMessageSend(
4881 CGF, ReturnValueSlot(), ResultType, SelfSel, classObject, Args, OID,
4887void CGObjCCommonMac::GenerateDirectMethodsPreconditionCheck(
4888 CodeGenFunction &CGF, llvm::Function *Fn,
const ObjCMethodDecl *OMD,
4889 const ObjCContainerDecl *CD) {
4891 bool ReceiverCanBeNull =
true;
4893 auto selfValue = Builder.CreateLoad(selfAddr);
4908 "GenerateDirectMethod() should be called with the Class Interface");
4919 llvm::Value *realizedClass = GenerateClassRealization(CGF, selfValue, OID);
4920 Builder.CreateStore(realizedClass, selfAddr);
4925 ReceiverCanBeNull = isWeakLinkedClass(OID);
4929 if (ReceiverCanBeNull) {
4930 llvm::BasicBlock *SelfIsNilBlock =
4932 llvm::BasicBlock *ContBlock =
4937 auto Zero = llvm::ConstantPointerNull::get(selfTy);
4940 Builder.CreateCondBr(Builder.CreateICmpEQ(selfValue,
Zero), SelfIsNilBlock,
4941 ContBlock, MDHelper.createUnlikelyBranchWeights());
4947 Builder.SetInsertPoint(SelfIsNilBlock);
4948 if (!retTy->isVoidType()) {
4956 Builder.SetInsertPoint(ContBlock);
4960void CGObjCCommonMac::GenerateDirectMethodPrologue(
4961 CodeGenFunction &CGF, llvm::Function *Fn,
const ObjCMethodDecl *OMD,
4962 const ObjCContainerDecl *CD) {
4965 GenerateDirectMethodsPreconditionCheck(CGF, Fn, OMD, CD);
4974 Builder.CreateStore(GetSelector(CGF, OMD),
4979llvm::Function *CGObjCCommonMac::GenerateMethodSelectorStub(
4980 Selector Sel, StringRef ClassName,
const ObjCCommonTypesHelper &ObjCTypes) {
4981 assert((!ClassName.data() || !ClassName.empty()) &&
4982 "class name cannot be an empty string");
4983 auto Key = std::make_pair(Sel, ClassName);
4984 auto I = MethodSelectorStubs.find(Key);
4986 if (I != MethodSelectorStubs.end())
4989 auto *FnTy = llvm::FunctionType::get(
4990 ObjCTypes.ObjectPtrTy, {ObjCTypes.ObjectPtrTy, ObjCTypes.SelectorPtrTy},
4994 if (ClassName.data())
4995 FnName = (
"objc_msgSendClass$" + Sel.
getAsString() +
"$_OBJC_CLASS_$_" +
4996 llvm::Twine(ClassName))
5004 MethodSelectorStubs.insert(std::make_pair(Key, Fn));
5008llvm::GlobalVariable *
5009CGObjCCommonMac::CreateMetadataVar(Twine Name, ConstantStructBuilder &
Init,
5010 StringRef Section, CharUnits Align,
5012 llvm::GlobalValue::LinkageTypes
LT =
5014 llvm::GlobalVariable *GV =
5015 Init.finishAndCreateGlobal(Name, Align,
false, LT);
5016 if (!Section.empty())
5017 GV->setSection(Section);
5023llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
5024 llvm::Constant *
Init,
5028 llvm::Type *Ty =
Init->getType();
5029 llvm::GlobalValue::LinkageTypes
LT =
5031 llvm::GlobalVariable *GV =
5032 new llvm::GlobalVariable(CGM.
getModule(), Ty,
false, LT,
Init, Name);
5033 if (!Section.empty())
5034 GV->setSection(Section);
5041llvm::GlobalVariable *
5042CGObjCCommonMac::CreateCStringLiteral(StringRef Name, ObjCLabelType
Type,
5043 bool ForceNonFragileABI,
5044 bool NullTerminate) {
5047 case ObjCLabelType::ClassName:
5048 Label =
"OBJC_CLASS_NAME_";
5050 case ObjCLabelType::MethodVarName:
5051 Label =
"OBJC_METH_VAR_NAME_";
5053 case ObjCLabelType::MethodVarType:
5054 Label =
"OBJC_METH_VAR_TYPE_";
5056 case ObjCLabelType::PropertyName:
5057 Label =
"OBJC_PROP_NAME_ATTR_";
5059 case ObjCLabelType::LayoutBitMap:
5060 Label =
"OBJC_LAYOUT_BITMAP_";
5064 bool NonFragile = ForceNonFragileABI || isNonFragileABI();
5068 case ObjCLabelType::ClassName:
5069 Section = NonFragile ?
"__TEXT,__objc_classname,cstring_literals"
5070 :
"__TEXT,__cstring,cstring_literals";
5072 case ObjCLabelType::MethodVarName:
5073 Section = NonFragile ?
"__TEXT,__objc_methname,cstring_literals"
5074 :
"__TEXT,__cstring,cstring_literals";
5076 case ObjCLabelType::MethodVarType:
5077 Section = NonFragile ?
"__TEXT,__objc_methtype,cstring_literals"
5078 :
"__TEXT,__cstring,cstring_literals";
5080 case ObjCLabelType::PropertyName:
5081 Section = NonFragile ?
"__TEXT,__objc_methname,cstring_literals"
5082 :
"__TEXT,__cstring,cstring_literals";
5084 case ObjCLabelType::LayoutBitMap:
5085 Section =
"__TEXT,__cstring,cstring_literals";
5089 llvm::Constant *
Value =
5090 llvm::ConstantDataArray::getString(VMContext, Name, NullTerminate);
5091 llvm::GlobalVariable *GV =
new llvm::GlobalVariable(
5093 true, llvm::GlobalValue::PrivateLinkage,
Value, Label);
5094 if (CGM.
getTriple().isOSBinFormatMachO())
5095 GV->setSection(Section);
5096 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
5103llvm::Function *CGObjCMac::ModuleInitFunction() {
5109llvm::FunctionCallee CGObjCMac::GetPropertyGetFunction() {
5110 return ObjCTypes.getGetPropertyFn();
5113llvm::FunctionCallee CGObjCMac::GetPropertySetFunction() {
5114 return ObjCTypes.getSetPropertyFn();
5117llvm::FunctionCallee CGObjCMac::GetOptimizedPropertySetFunction(
bool atomic,
5119 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
5122llvm::FunctionCallee CGObjCMac::GetGetStructFunction() {
5123 return ObjCTypes.getCopyStructFn();
5126llvm::FunctionCallee CGObjCMac::GetSetStructFunction() {
5127 return ObjCTypes.getCopyStructFn();
5130llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectGetFunction() {
5131 return ObjCTypes.getCppAtomicObjectFunction();
5134llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectSetFunction() {
5135 return ObjCTypes.getCppAtomicObjectFunction();
5138llvm::FunctionCallee CGObjCMac::EnumerationMutationFunction() {
5139 return ObjCTypes.getEnumerationMutationFn();
5142void CGObjCMac::EmitTryStmt(CodeGenFunction &CGF,
const ObjCAtTryStmt &S) {
5143 return EmitTryOrSynchronizedStmt(CGF, S);
5146void CGObjCMac::EmitSynchronizedStmt(CodeGenFunction &CGF,
5147 const ObjCAtSynchronizedStmt &S) {
5148 return EmitTryOrSynchronizedStmt(CGF, S);
5152struct PerformFragileFinally final : EHScopeStack::Cleanup {
5157 ObjCTypesHelper &ObjCTypes;
5158 PerformFragileFinally(
const Stmt *S, Address SyncArgSlot,
5159 Address CallTryExitVar, Address ExceptionData,
5160 ObjCTypesHelper *ObjCTypes)
5161 : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
5162 ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
5164 void Emit(CodeGenFunction &CGF, Flags flags)
override {
5167 llvm::BasicBlock *FinallyCallExit =
5169 llvm::BasicBlock *FinallyNoCallExit =
5172 FinallyCallExit, FinallyNoCallExit);
5181 if (
const ObjCAtFinallyStmt *FinallyStmt =
5184 if (flags.isForEHCleanup())
5189 llvm::Value *CurCleanupDest =
5192 CGF.
EmitStmt(FinallyStmt->getFinallyBody());
5211class FragileHazards {
5212 CodeGenFunction &CGF;
5213 SmallVector<llvm::Value *, 20> Locals;
5214 llvm::DenseSet<llvm::BasicBlock *> BlocksBeforeTry;
5216 llvm::InlineAsm *ReadHazard;
5217 llvm::InlineAsm *WriteHazard;
5219 llvm::FunctionType *GetAsmFnType();
5221 void collectLocals();
5222 void emitReadHazard(CGBuilderTy &Builder);
5225 FragileHazards(CodeGenFunction &CGF);
5227 void emitWriteHazard();
5228 void emitHazardsInNewBlocks();
5237FragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) {
5244 for (llvm::BasicBlock &BB : *CGF.
CurFn)
5245 BlocksBeforeTry.insert(&BB);
5247 llvm::FunctionType *AsmFnTy = GetAsmFnType();
5255 std::string Constraint;
5256 for (
unsigned I = 0, E = Locals.size(); I != E; ++I) {
5262 ReadHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
5270 std::string Constraint;
5271 for (
unsigned I = 0, E = Locals.size(); I != E; ++I) {
5274 Constraint +=
"=*m";
5277 WriteHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
5282void FragileHazards::emitWriteHazard() {
5287 for (
auto Pair : llvm::enumerate(Locals))
5290 llvm::Attribute::get(
5295void FragileHazards::emitReadHazard(
CGBuilderTy &Builder) {
5296 assert(!Locals.empty());
5297 llvm::CallInst *call = Builder.CreateCall(ReadHazard, Locals);
5298 call->setDoesNotThrow();
5300 for (
auto Pair : llvm::enumerate(Locals))
5303 llvm::Attribute::get(
5304 Builder.getContext(), llvm::Attribute::ElementType,
5310void FragileHazards::emitHazardsInNewBlocks() {
5317 for (llvm::BasicBlock &BB : *CGF.
CurFn) {
5318 if (BlocksBeforeTry.count(&BB))
5322 for (llvm::BasicBlock::iterator BI = BB.begin(), BE = BB.end(); BI != BE;
5324 llvm::Instruction &I = *BI;
5343 Builder.SetInsertPoint(&BB, BI);
5344 emitReadHazard(Builder);
5351 if (llvm::Value *Ptr =
V.getBasePointer())
5355void FragileHazards::collectLocals() {
5357 llvm::DenseSet<llvm::Value *> AllocasToIgnore;
5363 llvm::BasicBlock &Entry = CGF.
CurFn->getEntryBlock();
5364 for (llvm::Instruction &I : Entry)
5366 Locals.push_back(&I);
5369llvm::FunctionType *FragileHazards::GetAsmFnType() {
5370 SmallVector<llvm::Type *, 16> tys(Locals.size());
5371 for (
unsigned i = 0, e = Locals.size(); i != e; ++i)
5372 tys[i] = Locals[i]->getType();
5373 return llvm::FunctionType::get(CGF.
VoidTy, tys,
false);
5484void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
5505 llvm::Value *SyncArg =
5507 SyncArg = CGF.
Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
5518 ObjCTypes.ExceptionDataTy, CGF.
getPointerAlign(),
"exceptiondata.ptr");
5524 FragileHazards Hazards(CGF);
5543 SyncArgSlot, CallTryExitVar,
5544 ExceptionData, &ObjCTypes);
5550 ExceptionData.emitRawPointer(CGF));
5553 llvm::Constant *
Zero = llvm::ConstantInt::get(CGF.
Builder.getInt32Ty(), 0);
5556 ObjCTypes.ExceptionDataTy, ExceptionData.emitRawPointer(CGF), GEPIndexes,
5559 ObjCTypes.getSetJmpFn(), SetJmpBuffer,
"setjmp_result");
5560 SetJmpResult->setCanReturnTwice();
5566 llvm::Value *DidCatch =
5567 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
5568 CGF.
Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
5576 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.
Builder.saveAndClearIP();
5582 Hazards.emitWriteHazard();
5596 ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF),
5607 llvm::BasicBlock *CatchBlock =
nullptr;
5608 llvm::BasicBlock *CatchHandler =
nullptr;
5619 ExceptionData.emitRawPointer(CGF));
5622 ObjCTypes.getSetJmpFn(), SetJmpBuffer,
"setjmp.result");
5623 SetJmpResult->setCanReturnTwice();
5625 llvm::Value *Threw =
5626 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
5630 CGF.
Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
5640 bool AllMatched =
false;
5641 for (
const ObjCAtCatchStmt *CatchStmt : AtTryStmt->
catch_stmts()) {
5642 const VarDecl *CatchParam = CatchStmt->getCatchParamDecl();
5643 const ObjCObjectPointerType *OPT =
nullptr;
5649 OPT = CatchParam->
getType()->
getAs<ObjCObjectPointerType>();
5668 EmitInitOfCatchParam(CGF, Caught, CatchParam);
5671 CGF.
EmitStmt(CatchStmt->getCatchBody());
5674 CatchVarCleanups.ForceCleanup();
5680 assert(OPT &&
"Unexpected non-object pointer type in @catch");
5684 ObjCInterfaceDecl *IDecl = ObjTy->getInterface();
5685 assert(IDecl &&
"Catch parameter must have Objective-C type!");
5688 llvm::Value *
Class = EmitClassRef(CGF, IDecl);
5690 llvm::Value *matchArgs[] = {
Class, Caught};
5692 ObjCTypes.getExceptionMatchFn(), matchArgs,
"match");
5698 MatchedBlock, NextCatchBlock);
5711 llvm::Value *Tmp = CGF.
Builder.CreateBitCast(
5713 EmitInitOfCatchParam(CGF, Tmp, CatchParam);
5715 CGF.
EmitStmt(CatchStmt->getCatchBody());
5718 CatchVarCleanups.ForceCleanup();
5729 if (Caught->use_empty())
5730 Caught->eraseFromParent();
5746 assert(PropagatingExnVar.
isValid());
5748 ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF),
5759 Hazards.emitHazardsInNewBlocks();
5762 CGF.
Builder.restoreIP(TryFallthroughIP);
5769 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
5773 llvm::Value *PropagatingExn;
5774 if (PropagatingExnVar.
isValid()) {
5780 ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF));
5781 PropagatingExn = Caught;
5786 CGF.
Builder.CreateUnreachable();
5789 CGF.
Builder.restoreIP(SavedIP);
5792void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
5793 const ObjCAtThrowStmt &S,
5794 bool ClearInsertionPoint) {
5795 llvm::Value *ExceptionAsObject;
5800 CGF.
Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
5803 "Unexpected rethrow outside @catch block.");
5807 CGF.
EmitRuntimeCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
5808 ->setDoesNotReturn();
5809 CGF.
Builder.CreateUnreachable();
5812 if (ClearInsertionPoint)
5813 CGF.
Builder.ClearInsertionPoint();
5819llvm::Value *CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
5822 llvm::Value *AddrWeakObjVal = CGF.
Builder.CreateBitCast(
5825 ObjCTypes.getGcReadWeakFn(), AddrWeakObjVal,
"weakread");
5826 read_weak = CGF.
Builder.CreateBitCast(read_weak, DestTy);
5833void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
5834 llvm::Value *src,
Address dst) {
5835 llvm::Type *SrcTy = src->getType();
5838 assert(Size <= 8 && "does not support size > 8
");
5839 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
5840 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
5841 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5843 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5844 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
5845 ObjCTypes.PtrObjectPtrTy);
5846 llvm::Value *args[] = {src, dstVal};
5847 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), args,
5854void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
5855 llvm::Value *src, Address dst,
5857 llvm::Type *SrcTy = src->getType();
5858 if (!isa<llvm::PointerType>(SrcTy)) {
5859 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
5860 assert(Size <= 8 && "does
not support size > 8
");
5861 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
5862 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
5863 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5865 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5866 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
5867 ObjCTypes.PtrObjectPtrTy);
5868 llvm::Value *args[] = {src, dstVal};
5870 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), args,
5873 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(), args,
5874 "threadlocalassign
");
5880void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
5881 llvm::Value *src, Address dst,
5882 llvm::Value *ivarOffset) {
5883 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset
is NULL");
5884 llvm::Type *SrcTy = src->getType();
5885 if (!isa<llvm::PointerType>(SrcTy)) {
5886 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
5887 assert(Size <= 8 && "does
not support size > 8
");
5888 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
5889 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
5890 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5892 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5893 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
5894 ObjCTypes.PtrObjectPtrTy);
5895 llvm::Value *args[] = {src, dstVal, ivarOffset};
5896 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
5902void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
5903 llvm::Value *src, Address dst) {
5904 llvm::Type *SrcTy = src->getType();
5905 if (!isa<llvm::PointerType>(SrcTy)) {
5906 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
5907 assert(Size <= 8 && "does
not support size > 8
");
5908 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
5909 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
5910 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5912 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5913 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
5914 ObjCTypes.PtrObjectPtrTy);
5915 llvm::Value *args[] = {src, dstVal};
5916 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), args,
5920void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
5921 Address DestPtr, Address SrcPtr,
5922 llvm::Value *size) {
5923 llvm::Value *args[] = {DestPtr.emitRawPointer(CGF),
5924 SrcPtr.emitRawPointer(CGF), size};
5925 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
5930LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
5932 llvm::Value *BaseValue,
5933 const ObjCIvarDecl *Ivar,
5934 unsigned CVRQualifiers) {
5935 const ObjCInterfaceDecl *ID =
5936 ObjectTy->castAs<ObjCObjectType>()->getInterface();
5937 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
5938 EmitIvarOffset(CGF, ID, Ivar));
5941llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
5942 const ObjCInterfaceDecl *Interface,
5943 const ObjCIvarDecl *Ivar) {
5944 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
5945 return llvm::ConstantInt::get(
5946 CGM.getTypes().ConvertType(CGM.getContext().LongTy), Offset);
5949/* *** Private Interface *** */
5951std::string CGObjCCommonMac::GetSectionName(StringRef Section,
5952 StringRef MachOAttributes) {
5953 switch (CGM.getTriple().getObjectFormat()) {
5954 case llvm::Triple::UnknownObjectFormat:
5955 llvm_unreachable("unexpected
object file format
");
5956 case llvm::Triple::MachO: {
5957 if (MachOAttributes.empty())
5958 return ("__DATA,
" + Section).str();
5959 return ("__DATA,
" + Section + ",
" + MachOAttributes).str();
5961 case llvm::Triple::ELF:
5962 assert(Section.starts_with("__
") && "expected the name to begin with __
");
5963 return Section.substr(2).str();
5964 case llvm::Triple::COFF:
5965 assert(Section.starts_with("__
") && "expected the name to begin with __
");
5966 return (".
" + Section.substr(2) + "$B
").str();
5967 case llvm::Triple::Wasm:
5968 case llvm::Triple::GOFF:
5969 case llvm::Triple::SPIRV:
5970 case llvm::Triple::XCOFF:
5971 case llvm::Triple::DXContainer:
5972 llvm::report_fatal_error(
5973 "Objective-
C support
is unimplemented
for object file format
");
5976 llvm_unreachable("Unhandled llvm::Triple::ObjectFormatType
enum");
5988enum ImageInfoFlags {
5989 eImageInfo_FixAndContinue = (1 << 0), // This flag is no longer set by clang.
5990 eImageInfo_GarbageCollected = (1 << 1),
5991 eImageInfo_GCOnly = (1 << 2),
5992 eImageInfo_OptimizedByDyld = (1 << 3), // This flag is set by the dyld shared cache.
5994 eImageInfo_SignedClassRO = (1 << 4), // Reused (was _CorrectedSynthesize)
5995 eImageInfo_ImageIsSimulated = (1 << 5),
5996 eImageInfo_ClassProperties = (1 << 6)
6000void CGObjCCommonMac::EmitImageInfo() {
6001 unsigned version = 0; // Version is unused?
6002 std::string Section =
6004 ? "__OBJC,__image_info,regular
"
6005 : GetSectionName("__objc_imageinfo
", "regular,no_dead_strip
");
6007 // Generate module-level named metadata to convey this information to the
6008 // linker and code-gen.
6009 llvm::Module &Mod = CGM.getModule();
6011 // Add the ObjC ABI version to the module flags.
6012 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Version
", ObjCABI);
6013 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Image Info Version
",
6015 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Image Info Section
",
6016 llvm::MDString::get(VMContext, Section));
6018 auto Int8Ty = llvm::Type::getInt8Ty(VMContext);
6019 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
6020 // Non-GC overrides those files which specify GC.
6021 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Garbage Collection
",
6022 llvm::ConstantInt::get(Int8Ty, 0));
6024 // Add the ObjC garbage collection value.
6026 llvm::Module::Error, "Objective-
C Garbage Collection
",
6027 llvm::ConstantInt::get(Int8Ty, (uint8_t)eImageInfo_GarbageCollected));
6029 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
6030 // Add the ObjC GC Only value.
6031 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C GC Only
",
6034 // Require that GC be specified and set to eImageInfo_GarbageCollected.
6035 llvm::Metadata *Ops[2] = {
6036 llvm::MDString::get(VMContext, "Objective-
C Garbage Collection
"),
6037 llvm::ConstantAsMetadata::get(
6038 llvm::ConstantInt::get(Int8Ty, eImageInfo_GarbageCollected))};
6039 Mod.addModuleFlag(llvm::Module::Require, "Objective-
C GC Only
",
6040 llvm::MDNode::get(VMContext, Ops));
6044 // Indicate whether we're compiling this to run on a simulator.
6045 if (CGM.getTarget().getTriple().isSimulatorEnvironment())
6046 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Is Simulated
",
6047 eImageInfo_ImageIsSimulated);
6049 // Indicate whether we are generating class properties.
6050 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Class Properties
",
6051 eImageInfo_ClassProperties);
6053 // Indicate whether we want enforcement of pointer signing for class_ro_t
6055 if (CGM.getLangOpts().PointerAuthObjcClassROPointers)
6056 Mod.addModuleFlag(llvm::Module::Error,
6057 "Objective-
C Enforce ClassRO
Pointer Signing
",
6058 eImageInfo_SignedClassRO);
6060 Mod.addModuleFlag(llvm::Module::Error,
6061 "Objective-
C Enforce ClassRO
Pointer Signing
",
6062 llvm::ConstantInt::get(Int8Ty, 0));
6065// struct objc_module {
6066// unsigned long version;
6067// unsigned long size;
6072// FIXME: Get from somewhere
6073static const int ModuleVersion = 7;
6075void CGObjCMac::EmitModuleInfo() {
6076 uint64_t Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ModuleTy);
6078 ConstantInitBuilder builder(CGM);
6079 auto values = builder.beginStruct(ObjCTypes.ModuleTy);
6080 values.addInt(ObjCTypes.LongTy, ModuleVersion);
6081 values.addInt(ObjCTypes.LongTy, Size);
6082 // This used to be the filename, now it is unused. <rdr://4327263>
6083 values.add(GetClassName(StringRef("")));
6084 values.add(EmitModuleSymbols());
6085 CreateMetadataVar("OBJC_MODULES
", values,
6086 "__OBJC,__module_info,regular,no_dead_strip
",
6087 CGM.getPointerAlign(), true);
6090llvm::Constant *CGObjCMac::EmitModuleSymbols() {
6091 unsigned NumClasses = DefinedClasses.size();
6092 unsigned NumCategories = DefinedCategories.size();
6094 // Return null if no symbols were defined.
6095 if (!NumClasses && !NumCategories)
6096 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
6098 ConstantInitBuilder builder(CGM);
6099 auto values = builder.beginStruct();
6100 values.addInt(ObjCTypes.LongTy, 0);
6101 values.addNullPointer(ObjCTypes.SelectorPtrTy);
6102 values.addInt(ObjCTypes.ShortTy, NumClasses);
6103 values.addInt(ObjCTypes.ShortTy, NumCategories);
6105 // The runtime expects exactly the list of defined classes followed
6106 // by the list of defined categories, in a single array.
6107 auto array = values.beginArray(ObjCTypes.Int8PtrTy);
6108 for (unsigned i = 0; i < NumClasses; i++) {
6109 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
6111 if (ObjCImplementationDecl *IMP = ID->getImplementation())
6112 // We are implementing a weak imported interface. Give it external linkage
6113 if (ID->isWeakImported() && !IMP->isWeakImported())
6114 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
6116 array.add(DefinedClasses[i]);
6118 for (unsigned i = 0; i < NumCategories; i++)
6119 array.add(DefinedCategories[i]);
6121 array.finishAndAddTo(values);
6123 llvm::GlobalVariable *GV = CreateMetadataVar(
6124 "OBJC_SYMBOLS
", values, "__OBJC,__symbols,regular,no_dead_strip
",
6125 CGM.getPointerAlign(), true);
6129llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF,
6130 IdentifierInfo *II) {
6131 LazySymbols.insert(II);
6133 llvm::GlobalVariable *&Entry = ClassReferences[II];
6137 CreateMetadataVar("OBJC_CLASS_REFERENCES_
", GetClassName(II->getName()),
6138 "__OBJC,__cls_refs,literal_pointers,no_dead_strip
",
6139 CGM.getPointerAlign(), true);
6142 return CGF.Builder.CreateAlignedLoad(Entry->getValueType(), Entry,
6143 CGF.getPointerAlign());
6146llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF,
6147 const ObjCInterfaceDecl *ID) {
6148 // If the class has the objc_runtime_visible attribute, we need to
6149 // use the Objective-C runtime to get the class.
6150 if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
6151 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
6153 IdentifierInfo *RuntimeName =
6154 &CGM.getContext().Idents.get(ID->getObjCRuntimeNameAsString());
6155 return EmitClassRefFromId(CGF, RuntimeName);
6158llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
6159 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool
");
6160 return EmitClassRefFromId(CGF, II);
6163llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel) {
6164 return CGF.Builder.CreateLoad(EmitSelectorAddr(Sel));
6167ConstantAddress CGObjCMac::EmitSelectorAddr(Selector Sel) {
6168 CharUnits Align = CGM.getPointerAlign();
6170 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
6172 Entry = CreateMetadataVar(
6173 "OBJC_SELECTOR_REFERENCES_
", GetMethodVarName(Sel),
6174 "__OBJC,__message_refs,literal_pointers,no_dead_strip
", Align, true);
6175 Entry->setExternallyInitialized(true);
6178 return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align);
6181llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) {
6182 llvm::GlobalVariable *&Entry = ClassNames[RuntimeName];
6184 Entry = CreateCStringLiteral(RuntimeName, ObjCLabelType::ClassName);
6185 return getConstantGEP(VMContext, Entry, 0, 0);
6188llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
6189 return MethodDefinitions.lookup(MD);
6195CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
6196 const ObjCCommonTypesHelper &ObjCTypes) {
6197 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
6200void IvarLayoutBuilder::visitRecord(const RecordType *RT, CharUnits offset) {
6201 const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
6203 // If this is a union, remember that we had one, because it might mess
6204 // up the ordering of layout entries.
6206 IsDisordered = true;
6208 const ASTRecordLayout *recLayout = nullptr;
6209 visitAggregate(RD->field_begin(), RD->field_end(), offset,
6210 [&](const FieldDecl *field) -> CharUnits {
6212 recLayout = &CGM.getContext().getASTRecordLayout(RD);
6214 recLayout->getFieldOffset(field->getFieldIndex());
6215 return CGM.getContext().toCharUnitsFromBits(offsetInBits);
6219template <class Iterator, class GetOffsetFn>
6220void IvarLayoutBuilder::visitAggregate(Iterator begin, Iterator end,
6221 CharUnits aggregateOffset,
6222 const GetOffsetFn &getOffset) {
6223 for (; begin != end; ++begin) {
6224 auto field = *begin;
6226 // Skip over bitfields.
6227 if (field->isBitField()) {
6231 // Compute the offset of the field within the aggregate.
6232 CharUnits fieldOffset = aggregateOffset + getOffset(field);
6234 visitField(field, fieldOffset);
6239void IvarLayoutBuilder::visitField(const FieldDecl *field,
6240 CharUnits fieldOffset) {
6241 QualType fieldType = field->getType();
6243 // Drill down into arrays.
6244 uint64_t numElts = 1;
6245 if (auto arrayType = CGM.getContext().getAsIncompleteArrayType(fieldType)) {
6247 fieldType = arrayType->getElementType();
6249 // Unlike incomplete arrays, constant arrays can be nested.
6250 while (auto arrayType = CGM.getContext().getAsConstantArrayType(fieldType)) {
6251 numElts *= arrayType->getZExtSize();
6252 fieldType = arrayType->getElementType();
6255 assert(!fieldType->isArrayType() && "ivar of non-constant array
type?
");
6257 // If we ended up with a zero-sized array, we've done what we can do within
6258 // the limits of this layout encoding.
6262 // Recurse if the base element type is a record type.
6263 if (const auto *recType = fieldType->getAsCanonical<RecordType>()) {
6264 size_t oldEnd = IvarsInfo.size();
6266 visitRecord(recType, fieldOffset);
6268 // If we have an array, replicate the first entry's layout information.
6269 auto numEltEntries = IvarsInfo.size() - oldEnd;
6270 if (numElts != 1 && numEltEntries != 0) {
6271 CharUnits eltSize = CGM.getContext().getTypeSizeInChars(recType);
6272 for (uint64_t eltIndex = 1; eltIndex != numElts; ++eltIndex) {
6273 // Copy the last numEltEntries onto the end of the array, adjusting
6274 // each for the element size.
6275 for (size_t i = 0; i != numEltEntries; ++i) {
6276 auto firstEntry = IvarsInfo[oldEnd + i];
6277 IvarsInfo.push_back(IvarInfo(firstEntry.Offset + eltIndex * eltSize,
6278 firstEntry.SizeInWords));
6286 // Classify the element type.
6287 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), fieldType);
6289 // If it matches what we're looking for, add an entry.
6290 if ((ForStrongLayout && GCAttr == Qualifiers::Strong) ||
6291 (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
6292 assert(CGM.getContext().getTypeSizeInChars(fieldType) ==
6293 CGM.getPointerSize());
6294 IvarsInfo.push_back(IvarInfo(fieldOffset, numElts));
6302IvarLayoutBuilder::buildBitmap(CGObjCCommonMac &CGObjC,
6303 llvm::SmallVectorImpl<unsigned char> &buffer) {
6304 // The bitmap is a series of skip/scan instructions, aligned to word
6305 // boundaries. The skip is performed first.
6306 const unsigned char MaxNibble = 0xF;
6307 const unsigned char SkipMask = 0xF0, SkipShift = 4;
6308 const unsigned char ScanMask = 0x0F, ScanShift = 0;
6310 assert(!IvarsInfo.empty() && "generating bitmap
for no data
");
6312 // Sort the ivar info on byte position in case we encounterred a
6313 // union nested in the ivar list.
6315 // This isn't a stable sort, but our algorithm should handle it fine.
6316 llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end());
6318 assert(llvm::is_sorted(IvarsInfo));
6320 assert(IvarsInfo.back().Offset < InstanceEnd);
6322 assert(buffer.empty());
6324 // Skip the next N words.
6325 auto skip = [&](unsigned numWords) {
6326 assert(numWords > 0);
6328 // Try to merge into the previous byte. Since scans happen second, we
6329 // can't do this if it includes a scan.
6330 if (!buffer.empty() && !(buffer.back() & ScanMask)) {
6331 unsigned lastSkip = buffer.back() >> SkipShift;
6332 if (lastSkip < MaxNibble) {
6333 unsigned claimed = std::min(MaxNibble - lastSkip, numWords);
6334 numWords -= claimed;
6335 lastSkip += claimed;
6336 buffer.back() = (lastSkip << SkipShift);
6340 while (numWords >= MaxNibble) {
6341 buffer.push_back(MaxNibble << SkipShift);
6342 numWords -= MaxNibble;
6345 buffer.push_back(numWords << SkipShift);
6349 // Scan the next N words.
6350 auto scan = [&](unsigned numWords) {
6351 assert(numWords > 0);
6353 // Try to merge into the previous byte. Since scans happen second, we can
6354 // do this even if it includes a skip.
6355 if (!buffer.empty()) {
6356 unsigned lastScan = (buffer.back() & ScanMask) >> ScanShift;
6357 if (lastScan < MaxNibble) {
6358 unsigned claimed = std::min(MaxNibble - lastScan, numWords);
6359 numWords -= claimed;
6360 lastScan += claimed;
6361 buffer.back() = (buffer.back() & SkipMask) | (lastScan << ScanShift);
6365 while (numWords >= MaxNibble) {
6366 buffer.push_back(MaxNibble << ScanShift);
6367 numWords -= MaxNibble;
6370 buffer.push_back(numWords << ScanShift);
6374 // One past the end of the last scan.
6375 unsigned endOfLastScanInWords = 0;
6376 const CharUnits WordSize = CGM.getPointerSize();
6378 // Consider all the scan requests.
6379 for (auto &request : IvarsInfo) {
6380 CharUnits beginOfScan = request.Offset - InstanceBegin;
6382 // Ignore scan requests that don't start at an even multiple of the
6383 // word size. We can't encode them.
6384 if (!beginOfScan.isMultipleOf(WordSize))
6387 // Ignore scan requests that start before the instance start.
6388 // This assumes that scans never span that boundary. The boundary
6389 // isn't the true start of the ivars, because in the fragile-ARC case
6390 // it's rounded up to word alignment, but the test above should leave
6391 // us ignoring that possibility.
6392 if (beginOfScan.isNegative()) {
6393 assert(request.Offset + request.SizeInWords * WordSize <= InstanceBegin);
6397 unsigned beginOfScanInWords = beginOfScan / WordSize;
6398 unsigned endOfScanInWords = beginOfScanInWords + request.SizeInWords;
6400 // If the scan starts some number of words after the last one ended,
6402 if (beginOfScanInWords > endOfLastScanInWords) {
6403 skip(beginOfScanInWords - endOfLastScanInWords);
6405 // Otherwise, start scanning where the last left off.
6407 beginOfScanInWords = endOfLastScanInWords;
6409 // If that leaves us with nothing to scan, ignore this request.
6410 if (beginOfScanInWords >= endOfScanInWords)
6414 // Scan to the end of the request.
6415 assert(beginOfScanInWords < endOfScanInWords);
6416 scan(endOfScanInWords - beginOfScanInWords);
6417 endOfLastScanInWords = endOfScanInWords;
6421 return llvm::ConstantPointerNull::get(CGM.Int8PtrTy);
6423 // For GC layouts, emit a skip to the end of the allocation so that we
6424 // have precise information about the entire thing. This isn't useful
6425 // or necessary for the ARC-style layout strings.
6426 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
6427 unsigned lastOffsetInWords =
6428 (InstanceEnd - InstanceBegin + WordSize - CharUnits::One()) / WordSize;
6429 if (lastOffsetInWords > endOfLastScanInWords) {
6430 skip(lastOffsetInWords - endOfLastScanInWords);
6434 // Null terminate the string.
6435 buffer.push_back(0);
6437 auto *Entry = CGObjC.CreateCStringLiteral(
6438 reinterpret_cast<char *>(buffer.data()), ObjCLabelType::LayoutBitMap);
6439 return getConstantGEP(CGM.getLLVMContext(), Entry, 0, 0);
6459CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD,
6460 CharUnits beginOffset, CharUnits endOffset,
6461 bool ForStrongLayout, bool HasMRCWeakIvars) {
6462 // If this is MRC, and we're either building a strong layout or there
6463 // are no weak ivars, bail out early.
6464 llvm::Type *PtrTy = CGM.Int8PtrTy;
6465 if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
6466 !CGM.getLangOpts().ObjCAutoRefCount &&
6467 (ForStrongLayout || !HasMRCWeakIvars))
6468 return llvm::Constant::getNullValue(PtrTy);
6470 const ObjCInterfaceDecl *OI = OMD->getClassInterface();
6471 SmallVector<const ObjCIvarDecl *, 32> ivars;
6473 // GC layout strings include the complete object layout, possibly
6474 // inaccurately in the non-fragile ABI; the runtime knows how to fix this
6477 // ARC layout strings only include the class's ivars. In non-fragile
6478 // runtimes, that means starting at InstanceStart, rounded up to word
6479 // alignment. In fragile runtimes, there's no InstanceStart, so it means
6480 // starting at the offset of the first ivar, rounded up to word alignment.
6482 // MRC weak layout strings follow the ARC style.
6483 CharUnits baseOffset;
6484 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
6485 for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin(); IVD;
6486 IVD = IVD->getNextIvar())
6487 ivars.push_back(IVD);
6489 if (isNonFragileABI()) {
6490 baseOffset = beginOffset; // InstanceStart
6491 } else if (!ivars.empty()) {
6493 CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivars[0]));
6495 baseOffset = CharUnits::Zero();
6498 baseOffset = baseOffset.alignTo(CGM.getPointerAlign());
6500 CGM.getContext().DeepCollectObjCIvars(OI, true, ivars);
6502 baseOffset = CharUnits::Zero();
6506 return llvm::Constant::getNullValue(PtrTy);
6508 IvarLayoutBuilder builder(CGM, baseOffset, endOffset, ForStrongLayout);
6510 builder.visitAggregate(ivars.begin(), ivars.end(), CharUnits::Zero(),
6511 [&](const ObjCIvarDecl *ivar) -> CharUnits {
6512 return CharUnits::fromQuantity(
6513 ComputeIvarBaseOffset(CGM, OMD, ivar));
6516 if (!builder.hasBitmapData())
6517 return llvm::Constant::getNullValue(PtrTy);
6519 llvm::SmallVector<unsigned char, 4> buffer;
6520 llvm::Constant *C = builder.buildBitmap(*this, buffer);
6522 if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
6523 printf("\n%
s ivar layout
for class '%s':
",
6524 ForStrongLayout ? "strong
" : "weak
",
6525 OMD->getClassInterface()->getName().str().c_str());
6526 builder.dump(buffer);
6531llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
6532 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
6533 // FIXME: Avoid std::string in "Sel.
getAsString()
"
6536 CreateCStringLiteral(Sel.getAsString(), ObjCLabelType::MethodVarName);
6537 return getConstantGEP(VMContext, Entry, 0, 0);
6540// FIXME: Merge into a single cstring creation function.
6541llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
6542 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
6545llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
6546 std::string TypeStr;
6547 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
6549 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
6551 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType);
6552 return getConstantGEP(VMContext, Entry, 0, 0);
6555llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D,
6557 std::string TypeStr =
6558 CGM.getContext().getObjCEncodingForMethodDecl(D, Extended);
6560 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
6562 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType);
6563 return getConstantGEP(VMContext, Entry, 0, 0);
6566// FIXME: Merge into a single cstring creation function.
6567llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
6568 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
6570 Entry = CreateCStringLiteral(Ident->getName(), ObjCLabelType::PropertyName);
6571 return getConstantGEP(VMContext, Entry, 0, 0);
6574// FIXME: Merge into a single cstring creation function.
6575// FIXME: This Decl should be more precise.
6577CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
6578 const Decl *Container) {
6579 std::string TypeStr =
6580 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container);
6581 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
6584void CGObjCMac::FinishModule() {
6587 // Emit the dummy bodies for any protocols which were referenced but
6589 for (auto &entry : Protocols) {
6590 llvm::GlobalVariable *global = entry.second;
6591 if (global->hasInitializer())
6594 ConstantInitBuilder builder(CGM);
6595 auto values = builder.beginStruct(ObjCTypes.ProtocolTy);
6596 values.addNullPointer(ObjCTypes.ProtocolExtensionPtrTy);
6597 values.add(GetClassName(entry.first->getName()));
6598 values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
6599 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy);
6600 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy);
6601 values.finishAndSetAsInitializer(global);
6602 CGM.addCompilerUsedGlobal(global);
6605 // Add assembler directives to add lazy undefined symbol references
6606 // for classes which are referenced but not defined. This is
6607 // important for correct linker interaction.
6609 // FIXME: It would be nice if we had an LLVM construct for this.
6610 if ((!LazySymbols.empty() || !DefinedSymbols.empty()) &&
6611 CGM.getTriple().isOSBinFormatMachO()) {
6612 SmallString<256> Asm;
6613 Asm += CGM.getModule().getModuleInlineAsm();
6614 if (!Asm.empty() && Asm.back() != '\n')
6617 llvm::raw_svector_ostream OS(Asm);
6618 for (const auto *Sym : DefinedSymbols)
6619 OS << "\t.objc_class_name_
" << Sym->getName() << "=0\n
"
6620 << "\t.globl .objc_class_name_
" << Sym->getName() << "\n
";
6621 for (const auto *Sym : LazySymbols)
6622 OS << "\t.lazy_reference .objc_class_name_
" << Sym->getName() << "\n
";
6623 for (const auto &Category : DefinedCategoryNames)
6624 OS << "\t.objc_category_name_
" << Category << "=0\n
"
6625 << "\t.globl .objc_category_name_
" << Category << "\n
";
6627 CGM.getModule().setModuleInlineAsm(OS.str());
6631CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
6632 : CGObjCCommonMac(cgm), ObjCTypes(cgm), ObjCEmptyCacheVar(nullptr),
6633 ObjCEmptyVtableVar(nullptr) {
6639ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
6640 : VMContext(cgm.getLLVMContext()), CGM(cgm) {
6641 CodeGen::CodeGenTypes &Types = CGM.getTypes();
6642 ASTContext &Ctx = CGM.getContext();
6643 unsigned ProgramAS = CGM.getDataLayout().getProgramAddressSpace();
6645 ShortTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.ShortTy));
6647 LongTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.LongTy));
6648 Int8PtrTy = CGM.Int8PtrTy;
6649 Int8PtrProgramASTy = llvm::PointerType::get(CGM.getLLVMContext(), ProgramAS);
6650 Int8PtrPtrTy = CGM.Int8PtrPtrTy;
6652 // arm64 targets use "int" ivar offset variables. All others,
6653 // including OS X x86_64 and Windows x86_64, use "long" ivar offsets.
6654 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::aarch64)
6655 IvarOffsetVarTy = IntTy;
6657 IvarOffsetVarTy = LongTy;
6659 ObjectPtrTy = cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCIdType()));
6660 PtrObjectPtrTy = llvm::PointerType::getUnqual(VMContext);
6662 cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCSelType()));
6664 // I'm not sure I like this. The implicit coordination is a bit
6665 // gross. We should solve this in a reasonable fashion because this
6666 // is a pretty common task (match some runtime data structure with
6667 // an LLVM data structure).
6669 // FIXME: This is leaked.
6670 // FIXME: Merge with rewriter code?
6672 // struct _objc_super {
6676 RecordDecl *RD = RecordDecl::Create(
6677 Ctx, TagTypeKind::Struct, Ctx.getTranslationUnitDecl(), SourceLocation(),
6678 SourceLocation(), &Ctx.Idents.get("_objc_super
"));
6679 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
6680 nullptr, Ctx.getObjCIdType(), nullptr, nullptr,
6681 false, ICIS_NoInit));
6682 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
6683 nullptr, Ctx.getObjCClassType(), nullptr,
6684 nullptr, false, ICIS_NoInit));
6685 RD->completeDefinition();
6687 SuperCTy = Ctx.getCanonicalTagType(RD);
6688 SuperPtrCTy = Ctx.getPointerType(SuperCTy);
6690 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
6691 SuperPtrTy = llvm::PointerType::getUnqual(VMContext);
6695 // char *attributes;
6697 PropertyTy = llvm::StructType::create("struct._prop_t
", Int8PtrTy, Int8PtrTy);
6699 // struct _prop_list_t {
6700 // uint32_t entsize; // sizeof(struct _prop_t)
6701 // uint32_t count_of_properties;
6702 // struct _prop_t prop_list[count_of_properties];
6704 PropertyListTy = llvm::StructType::create(
6705 "struct._prop_list_t
", IntTy, IntTy, llvm::ArrayType::get(PropertyTy, 0));
6706 // struct _prop_list_t *
6707 PropertyListPtrTy = llvm::PointerType::getUnqual(VMContext);
6709 // struct _objc_method {
6711 // char *method_type;
6714 MethodTy = llvm::StructType::create("struct._objc_method
", SelectorPtrTy,
6715 Int8PtrTy, Int8PtrProgramASTy);
6717 // struct _objc_cache *
6718 CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache
");
6719 CachePtrTy = llvm::PointerType::getUnqual(VMContext);
6722ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
6723 : ObjCCommonTypesHelper(cgm) {
6724 // struct _objc_method_description {
6728 MethodDescriptionTy = llvm::StructType::create(
6729 "struct._objc_method_description
", SelectorPtrTy, Int8PtrTy);
6731 // struct _objc_method_description_list {
6733 // struct _objc_method_description[1];
6735 MethodDescriptionListTy =
6736 llvm::StructType::create("struct._objc_method_description_list
", IntTy,
6737 llvm::ArrayType::get(MethodDescriptionTy, 0));
6739 // struct _objc_method_description_list *
6740 MethodDescriptionListPtrTy = llvm::PointerType::getUnqual(VMContext);
6742 // Protocol description structures
6744 // struct _objc_protocol_extension {
6745 // uint32_t size; // sizeof(struct _objc_protocol_extension)
6746 // struct _objc_method_description_list *optional_instance_methods;
6747 // struct _objc_method_description_list *optional_class_methods;
6748 // struct _objc_property_list *instance_properties;
6749 // const char ** extendedMethodTypes;
6750 // struct _objc_property_list *class_properties;
6752 ProtocolExtensionTy = llvm::StructType::create(
6753 "struct._objc_protocol_extension
", IntTy, MethodDescriptionListPtrTy,
6754 MethodDescriptionListPtrTy, PropertyListPtrTy, Int8PtrPtrTy,
6757 // struct _objc_protocol_extension *
6758 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(VMContext);
6760 // Handle construction of Protocol and ProtocolList types
6762 // struct _objc_protocol {
6763 // struct _objc_protocol_extension *isa;
6764 // char *protocol_name;
6765 // struct _objc_protocol **_objc_protocol_list;
6766 // struct _objc_method_description_list *instance_methods;
6767 // struct _objc_method_description_list *class_methods;
6769 ProtocolTy = llvm::StructType::create(
6770 {ProtocolExtensionPtrTy, Int8PtrTy,
6771 llvm::PointerType::getUnqual(VMContext), MethodDescriptionListPtrTy,
6772 MethodDescriptionListPtrTy},
6773 "struct._objc_protocol
");
6776 llvm::StructType::create({llvm::PointerType::getUnqual(VMContext), LongTy,
6777 llvm::ArrayType::get(ProtocolTy, 0)},
6778 "struct._objc_protocol_list
");
6780 // struct _objc_protocol_list *
6781 ProtocolListPtrTy = llvm::PointerType::getUnqual(VMContext);
6783 ProtocolPtrTy = llvm::PointerType::getUnqual(VMContext);
6785 // Class description structures
6787 // struct _objc_ivar {
6792 IvarTy = llvm::StructType::create("struct._objc_ivar
", Int8PtrTy, Int8PtrTy,
6795 // struct _objc_ivar_list *
6796 IvarListTy = llvm::StructType::create(VMContext, "struct._objc_ivar_list
");
6797 IvarListPtrTy = llvm::PointerType::getUnqual(VMContext);
6799 // struct _objc_method_list *
6801 llvm::StructType::create(VMContext, "struct._objc_method_list
");
6802 MethodListPtrTy = llvm::PointerType::getUnqual(VMContext);
6804 // struct _objc_class_extension *
6805 ClassExtensionTy = llvm::StructType::create(
6806 "struct._objc_class_extension
", IntTy, Int8PtrTy, PropertyListPtrTy);
6807 ClassExtensionPtrTy = llvm::PointerType::getUnqual(VMContext);
6809 // struct _objc_class {
6811 // Class super_class;
6815 // long instance_size;
6816 // struct _objc_ivar_list *ivars;
6817 // struct _objc_method_list *methods;
6818 // struct _objc_cache *cache;
6819 // struct _objc_protocol_list *protocols;
6820 // char *ivar_layout;
6821 // struct _objc_class_ext *ext;
6823 ClassTy = llvm::StructType::create(
6824 {llvm::PointerType::getUnqual(VMContext),
6825 llvm::PointerType::getUnqual(VMContext), Int8PtrTy, LongTy, LongTy,
6826 LongTy, IvarListPtrTy, MethodListPtrTy, CachePtrTy, ProtocolListPtrTy,
6827 Int8PtrTy, ClassExtensionPtrTy},
6828 "struct._objc_class
");
6830 ClassPtrTy = llvm::PointerType::getUnqual(VMContext);
6832 // struct _objc_category {
6833 // char *category_name;
6834 // char *class_name;
6835 // struct _objc_method_list *instance_method;
6836 // struct _objc_method_list *class_method;
6837 // struct _objc_protocol_list *protocols;
6838 // uint32_t size; // sizeof(struct _objc_category)
6839 // struct _objc_property_list *instance_properties;// category's @property
6840 // struct _objc_property_list *class_properties;
6842 CategoryTy = llvm::StructType::create(
6843 "struct._objc_category
", Int8PtrTy, Int8PtrTy, MethodListPtrTy,
6844 MethodListPtrTy, ProtocolListPtrTy, IntTy, PropertyListPtrTy,
6847 // Global metadata structures
6849 // struct _objc_symtab {
6850 // long sel_ref_cnt;
6852 // short cls_def_cnt;
6853 // short cat_def_cnt;
6854 // char *defs[cls_def_cnt + cat_def_cnt];
6856 SymtabTy = llvm::StructType::create("struct._objc_symtab
", LongTy,
6857 SelectorPtrTy, ShortTy, ShortTy,
6858 llvm::ArrayType::get(Int8PtrTy, 0));
6859 SymtabPtrTy = llvm::PointerType::getUnqual(VMContext);
6861 // struct _objc_module {
6863 // long size; // sizeof(struct _objc_module)
6865 // struct _objc_symtab* symtab;
6867 ModuleTy = llvm::StructType::create("struct._objc_module
", LongTy, LongTy,
6868 Int8PtrTy, SymtabPtrTy);
6870 // FIXME: This is the size of the setjmp buffer and should be target
6871 // specific. 18 is what's used on 32-bit X86.
6872 uint64_t SetJmpBufferSize = 18;
6875 llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4);
6877 ExceptionDataTy = llvm::StructType::create(
6878 "struct._objc_exception_data
",
6879 llvm::ArrayType::get(CGM.Int32Ty, SetJmpBufferSize), StackPtrTy);
6882ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(
6883 CodeGen::CodeGenModule &cgm)
6884 : ObjCCommonTypesHelper(cgm) {
6885 // struct _method_list_t {
6886 // uint32_t entsize; // sizeof(struct _objc_method)
6887 // uint32_t method_count;
6888 // struct _objc_method method_list[method_count];
6891 llvm::StructType::create("struct.__method_list_t
", IntTy, IntTy,
6892 llvm::ArrayType::get(MethodTy, 0));
6893 // struct method_list_t *
6894 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6896 // struct _protocol_t {
6898 // const char * const protocol_name;
6899 // const struct _protocol_list_t * protocol_list; // super protocols
6900 // const struct method_list_t * const instance_methods;
6901 // const struct method_list_t * const class_methods;
6902 // const struct method_list_t *optionalInstanceMethods;
6903 // const struct method_list_t *optionalClassMethods;
6904 // const struct _prop_list_t * properties;
6905 // const uint32_t size; // sizeof(struct _protocol_t)
6906 // const uint32_t flags; // = 0
6907 // const char ** extendedMethodTypes;
6908 // const char *demangledName;
6909 // const struct _prop_list_t * class_properties;
6912 ProtocolnfABITy = llvm::StructType::create(
6913 "struct._protocol_t
", ObjectPtrTy, Int8PtrTy,
6914 llvm::PointerType::getUnqual(VMContext), MethodListnfABIPtrTy,
6915 MethodListnfABIPtrTy, MethodListnfABIPtrTy, MethodListnfABIPtrTy,
6916 PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy, Int8PtrTy,
6919 // struct _protocol_t*
6920 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6922 // struct _protocol_list_t {
6923 // long protocol_count; // Note, this is 32/64 bit
6924 // struct _protocol_t *[protocol_count];
6926 ProtocolListnfABITy = llvm::StructType::create(
6927 {LongTy, llvm::ArrayType::get(ProtocolnfABIPtrTy, 0)},
6928 "struct._objc_protocol_list
");
6930 // struct _objc_protocol_list*
6931 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6934 // unsigned [long] int *offset; // pointer to ivar offset location
6937 // uint32_t alignment;
6940 IvarnfABITy = llvm::StructType::create(
6941 "struct._ivar_t
", llvm::PointerType::getUnqual(VMContext), Int8PtrTy,
6942 Int8PtrTy, IntTy, IntTy);
6944 // struct _ivar_list_t {
6945 // uint32 entsize; // sizeof(struct _ivar_t)
6947 // struct _iver_t list[count];
6950 llvm::StructType::create("struct._ivar_list_t
", IntTy, IntTy,
6951 llvm::ArrayType::get(IvarnfABITy, 0));
6953 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6955 // struct _class_ro_t {
6956 // uint32_t const flags;
6957 // uint32_t const instanceStart;
6958 // uint32_t const instanceSize;
6959 // uint32_t const reserved; // only when building for 64bit targets
6960 // const uint8_t * const ivarLayout;
6961 // const char *const name;
6962 // const struct _method_list_t * const baseMethods;
6963 // const struct _objc_protocol_list *const baseProtocols;
6964 // const struct _ivar_list_t *const ivars;
6965 // const uint8_t * const weakIvarLayout;
6966 // const struct _prop_list_t * const properties;
6969 // FIXME. Add 'reserved' field in 64bit abi mode!
6970 ClassRonfABITy = llvm::StructType::create(
6971 "struct._class_ro_t
", IntTy, IntTy, IntTy, Int8PtrTy, Int8PtrTy,
6972 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, IvarListnfABIPtrTy,
6973 Int8PtrTy, PropertyListPtrTy);
6975 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
6976 ImpnfABITy = CGM.DefaultPtrTy;
6978 // struct _class_t {
6979 // struct _class_t *isa;
6980 // struct _class_t * const superclass;
6983 // struct class_ro_t *ro;
6986 ClassnfABITy = llvm::StructType::create(
6987 {llvm::PointerType::getUnqual(VMContext),
6988 llvm::PointerType::getUnqual(VMContext), CachePtrTy,
6989 llvm::PointerType::getUnqual(VMContext),
6990 llvm::PointerType::getUnqual(VMContext)},
6993 // LLVM for struct _class_t *
6994 ClassnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6996 // struct _category_t {
6997 // const char * const name;
6998 // struct _class_t *const cls;
6999 // const struct _method_list_t * const instance_methods;
7000 // const struct _method_list_t * const class_methods;
7001 // const struct _protocol_list_t * const protocols;
7002 // const struct _prop_list_t * const properties;
7003 // const struct _prop_list_t * const class_properties;
7004 // const uint32_t size;
7006 CategorynfABITy = llvm::StructType::create(
7007 "struct._category_t
", Int8PtrTy, ClassnfABIPtrTy, MethodListnfABIPtrTy,
7008 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, PropertyListPtrTy,
7009 PropertyListPtrTy, IntTy);
7011 // New types for nonfragile abi messaging.
7012 CodeGen::CodeGenTypes &Types = CGM.getTypes();
7013 ASTContext &Ctx = CGM.getContext();
7015 // MessageRefTy - LLVM for:
7016 // struct _message_ref_t {
7021 // First the clang type for struct _message_ref_t
7022 RecordDecl *RD = RecordDecl::Create(
7023 Ctx, TagTypeKind::Struct, Ctx.getTranslationUnitDecl(), SourceLocation(),
7024 SourceLocation(), &Ctx.Idents.get("_message_ref_t
"));
7025 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
7026 nullptr, Ctx.VoidPtrTy, nullptr, nullptr, false,
7028 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
7029 nullptr, Ctx.getObjCSelType(), nullptr, nullptr,
7030 false, ICIS_NoInit));
7031 RD->completeDefinition();
7033 MessageRefCTy = Ctx.getCanonicalTagType(RD);
7034 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy);
7035 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy));
7037 // MessageRefPtrTy - LLVM for struct _message_ref_t*
7038 MessageRefPtrTy = llvm::PointerType::getUnqual(VMContext);
7040 // SuperMessageRefTy - LLVM for:
7041 // struct _super_message_ref_t {
7042 // SUPER_IMP messenger;
7045 SuperMessageRefTy = llvm::StructType::create("struct._super_message_ref_t
",
7046 ImpnfABITy, SelectorPtrTy);
7048 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
7049 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(VMContext);
7051 // struct objc_typeinfo {
7052 // const void** vtable; // objc_ehtype_vtable + 2
7053 // const char* name; // c++ typeinfo string
7056 EHTypeTy = llvm::StructType::create("struct._objc_typeinfo
",
7057 llvm::PointerType::getUnqual(VMContext),
7058 Int8PtrTy, ClassnfABIPtrTy);
7059 EHTypePtrTy = llvm::PointerType::getUnqual(VMContext);
7062llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
7063 FinishNonFragileABIModule();
7068void CGObjCNonFragileABIMac::AddModuleClassList(
7069 ArrayRef<llvm::GlobalValue *> Container, StringRef SymbolName,
7070 StringRef SectionName) {
7071 unsigned NumClasses = Container.size();
7076 SmallVector<llvm::Constant *, 8> Symbols(NumClasses);
7077 for (unsigned i = 0; i < NumClasses; i++)
7078 Symbols[i] = Container[i];
7080 llvm::Constant *Init = llvm::ConstantArray::get(
7081 llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Symbols.size()), Symbols);
7083 // Section name is obtained by calling GetSectionName, which returns
7084 // sections in the __DATA segment on MachO.
7085 assert((!CGM.getTriple().isOSBinFormatMachO() ||
7086 SectionName.starts_with("__DATA
")) &&
7087 "SectionName expected to start with __DATA on
MachO");
7088 llvm::GlobalVariable *GV = new llvm::GlobalVariable(
7089 CGM.getModule(), Init->getType(), false,
7090 llvm::GlobalValue::PrivateLinkage, Init, SymbolName);
7091 GV->setAlignment(CGM.getDataLayout().getABITypeAlign(Init->getType()));
7092 GV->setSection(SectionName);
7093 CGM.addCompilerUsedGlobal(GV);
7096void CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
7097 // nonfragile abi has no module definition.
7099 // Build list of all implemented class addresses in array
7100 // L_OBJC_LABEL_CLASS_$.
7102 for (unsigned i = 0, NumClasses = ImplementedClasses.size(); i < NumClasses;
7104 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
7106 if (ObjCImplementationDecl *IMP = ID->getImplementation())
7107 // We are implementing a weak imported interface. Give it external linkage
7108 if (ID->isWeakImported() && !IMP->isWeakImported()) {
7109 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
7110 DefinedMetaClasses[i]->setLinkage(
7111 llvm::GlobalVariable::ExternalLinkage);
7116 DefinedClasses, "OBJC_LABEL_CLASS_$
",
7117 GetSectionName("__objc_classlist
", "regular,no_dead_strip
"));
7120 DefinedNonLazyClasses, "OBJC_LABEL_NONLAZY_CLASS_$
",
7121 GetSectionName("__objc_nlclslist
", "regular,no_dead_strip
"));
7123 // Build list of all implemented category addresses in array
7124 // L_OBJC_LABEL_CATEGORY_$.
7125 AddModuleClassList(DefinedCategories, "OBJC_LABEL_CATEGORY_$
",
7126 GetSectionName("__objc_catlist
", "regular,no_dead_strip
"));
7128 DefinedStubCategories, "OBJC_LABEL_STUB_CATEGORY_$
",
7129 GetSectionName("__objc_catlist2
", "regular,no_dead_strip
"));
7131 DefinedNonLazyCategories, "OBJC_LABEL_NONLAZY_CATEGORY_$
",
7132 GetSectionName("__objc_nlcatlist
", "regular,no_dead_strip
"));
7141bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
7142 // At various points we've experimented with using vtable-based
7143 // dispatch for all methods.
7144 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
7145 case CodeGenOptions::Legacy:
7147 case CodeGenOptions::NonLegacy:
7149 case CodeGenOptions::Mixed:
7153 // If so, see whether this selector is in the white-list of things which must
7154 // use the new dispatch convention. We lazily build a dense set for this.
7155 if (VTableDispatchMethods.empty()) {
7156 VTableDispatchMethods.insert(GetNullarySelector("alloc
"));
7157 VTableDispatchMethods.insert(GetNullarySelector("class"));
7158 VTableDispatchMethods.insert(GetNullarySelector("self
"));
7159 VTableDispatchMethods.insert(GetNullarySelector("isFlipped
"));
7160 VTableDispatchMethods.insert(GetNullarySelector("length"));
7161 VTableDispatchMethods.insert(GetNullarySelector("count
"));
7163 // These are vtable-based if GC is disabled.
7164 // Optimistically use vtable dispatch for hybrid compiles.
7165 if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) {
7166 VTableDispatchMethods.insert(GetNullarySelector("retain
"));
7167 VTableDispatchMethods.insert(GetNullarySelector("release
"));
7168 VTableDispatchMethods.insert(GetNullarySelector("autorelease
"));
7171 VTableDispatchMethods.insert(GetUnarySelector("allocWithZone
"));
7172 VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass
"));
7173 VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector
"));
7174 VTableDispatchMethods.insert(GetUnarySelector("objectForKey
"));
7175 VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex
"));
7176 VTableDispatchMethods.insert(GetUnarySelector("isEqualToString
"));
7177 VTableDispatchMethods.insert(GetUnarySelector("isEqual
"));
7179 // These are vtable-based if GC is enabled.
7180 // Optimistically use vtable dispatch for hybrid compiles.
7181 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
7182 VTableDispatchMethods.insert(GetNullarySelector("hash
"));
7183 VTableDispatchMethods.insert(GetUnarySelector("addObject
"));
7185 // "countByEnumeratingWithState:objects:count
"
7186 const IdentifierInfo *KeyIdents[] = {
7187 &CGM.getContext().Idents.get("countByEnumeratingWithState
"),
7188 &CGM.getContext().Idents.get("objects
"),
7189 &CGM.getContext().Idents.get("count
")};
7190 VTableDispatchMethods.insert(
7191 CGM.getContext().Selectors.getSelector(3, KeyIdents));
7195 return VTableDispatchMethods.count(Sel);
7213llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassRoTInitializer(
7214 unsigned flags, unsigned InstanceStart, unsigned InstanceSize,
7215 const ObjCImplementationDecl *ID) {
7216 std::string ClassName = std::string(ID->getObjCRuntimeNameAsString());
7218 CharUnits beginInstance = CharUnits::fromQuantity(InstanceStart);
7219 CharUnits endInstance = CharUnits::fromQuantity(InstanceSize);
7221 bool hasMRCWeak = false;
7222 if (CGM.getLangOpts().ObjCAutoRefCount)
7223 flags |= NonFragileABI_Class_CompiledByARC;
7224 else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))
7225 flags |= NonFragileABI_Class_HasMRCWeakIvars;
7227 ConstantInitBuilder builder(CGM);
7228 auto values = builder.beginStruct(ObjCTypes.ClassRonfABITy);
7230 values.addInt(ObjCTypes.IntTy, flags);
7231 values.addInt(ObjCTypes.IntTy, InstanceStart);
7232 values.addInt(ObjCTypes.IntTy, InstanceSize);
7233 values.add((flags & NonFragileABI_Class_Meta)
7234 ? GetIvarLayoutName(nullptr, ObjCTypes)
7235 : BuildStrongIvarLayout(ID, beginInstance, endInstance));
7236 values.add(GetClassName(ID->getObjCRuntimeNameAsString()));
7238 // const struct _method_list_t * const baseMethods;
7239 SmallVector<const ObjCMethodDecl *, 16> methods;
7240 if (flags & NonFragileABI_Class_Meta) {
7241 for (const auto *MD : ID->class_methods())
7242 if (!MD->isDirectMethod())
7243 methods.push_back(MD);
7245 for (const auto *MD : ID->instance_methods())
7246 if (!MD->isDirectMethod())
7247 methods.push_back(MD);
7250 llvm::Constant *MethListPtr = emitMethodList(
7251 ID->getObjCRuntimeNameAsString(),
7252 (flags & NonFragileABI_Class_Meta) ? MethodListType::ClassMethods
7253 : MethodListType::InstanceMethods,
7256 const PointerAuthSchema &MethListSchema =
7257 CGM.getCodeGenOpts().PointerAuth.ObjCMethodListPointer;
7258 if (!MethListPtr->isNullValue())
7259 values.addSignedPointer(MethListPtr, MethListSchema, GlobalDecl(),
7262 values.add(MethListPtr);
7264 const ObjCInterfaceDecl *OID = ID->getClassInterface();
7265 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer
");
7266 values.add(EmitProtocolList("_OBJC_CLASS_PROTOCOLS_$_
" +
7267 OID->getObjCRuntimeNameAsString(),
7268 OID->all_referenced_protocol_begin(),
7269 OID->all_referenced_protocol_end()));
7271 if (flags & NonFragileABI_Class_Meta) {
7272 values.addNullPointer(ObjCTypes.IvarListnfABIPtrTy);
7273 values.add(GetIvarLayoutName(nullptr, ObjCTypes));
7274 values.add(EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_
" +
7275 ID->getObjCRuntimeNameAsString(),
7276 ID, ID->getClassInterface(), ObjCTypes, true));
7278 values.add(EmitIvarList(ID));
7279 values.add(BuildWeakIvarLayout(ID, beginInstance, endInstance, hasMRCWeak));
7280 values.add(EmitPropertyList("_OBJC_$_PROP_LIST_
" +
7281 ID->getObjCRuntimeNameAsString(),
7282 ID, ID->getClassInterface(), ObjCTypes, false));
7285 llvm::SmallString<64> roLabel;
7286 llvm::raw_svector_ostream(roLabel)
7287 << ((flags & NonFragileABI_Class_Meta) ? "_OBJC_METACLASS_RO_$_
"
7288 : "_OBJC_CLASS_RO_$_
")
7291 return finishAndCreateGlobal(values, roLabel, CGM);
7304llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassObject(
7305 const ObjCInterfaceDecl *CI, bool isMetaclass, llvm::Constant *IsAGV,
7306 llvm::Constant *SuperClassGV, llvm::Constant *ClassRoGV,
7307 bool HiddenVisibility) {
7308 ConstantInitBuilder builder(CGM);
7309 auto values = builder.beginStruct(ObjCTypes.ClassnfABITy);
7310 const PointerAuthOptions &PointerAuthOpts = CGM.getCodeGenOpts().PointerAuth;
7311 values.addSignedPointer(IsAGV, PointerAuthOpts.ObjCIsaPointers, GlobalDecl(),
7314 values.addSignedPointer(SuperClassGV, PointerAuthOpts.ObjCSuperPointers,
7315 GlobalDecl(), QualType());
7317 values.addNullPointer(ObjCTypes.ClassnfABIPtrTy);
7319 values.add(ObjCEmptyCacheVar);
7320 values.add(ObjCEmptyVtableVar);
7322 values.addSignedPointer(ClassRoGV, PointerAuthOpts.ObjCClassROPointers,
7323 GlobalDecl(), QualType());
7325 llvm::GlobalVariable *GV = cast<llvm::GlobalVariable>(
7326 GetClassGlobal(CI, isMetaclass, ForDefinition));
7327 values.finishAndSetAsInitializer(GV);
7329 if (CGM.getTriple().isOSBinFormatMachO())
7330 GV->setSection("__DATA, __objc_data
");
7331 GV->setAlignment(CGM.getDataLayout().getABITypeAlign(ObjCTypes.ClassnfABITy));
7332 if (!CGM.getTriple().isOSBinFormatCOFF())
7333 if (HiddenVisibility)
7334 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
7335 if (CGM.getCodeGenOpts().ObjCMsgSendClassSelectorStubs && !isMetaclass)
7336 CGM.addUsedGlobal(GV);
7340bool CGObjCNonFragileABIMac::ImplementationIsNonLazy(
7341 const ObjCImplDecl *OD) const {
7342 return OD->getClassMethod(GetNullarySelector("load
")) != nullptr ||
7343 OD->getClassInterface()->hasAttr<ObjCNonLazyClassAttr>() ||
7344 OD->hasAttr<ObjCNonLazyClassAttr>();
7347void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
7348 uint32_t &InstanceStart,
7349 uint32_t &InstanceSize) {
7350 const ASTRecordLayout &RL =
7351 CGM.getContext().getASTObjCInterfaceLayout(OID->getClassInterface());
7353 // InstanceSize is really instance end.
7354 InstanceSize = RL.getDataSize().getQuantity();
7356 // If there are no fields, the start is the same as the end.
7357 if (!RL.getFieldCount())
7358 InstanceStart = InstanceSize;
7360 InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth();
7363static llvm::GlobalValue::DLLStorageClassTypes getStorage(CodeGenModule &CGM,
7365 IdentifierInfo &II = CGM.getContext().Idents.get(Name);
7366 TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl();
7367 DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl);
7369 const VarDecl *VD = nullptr;
7370 for (const auto *Result : DC->lookup(&II))
7371 if ((VD = dyn_cast<VarDecl>(Result)))
7375 return llvm::GlobalValue::DLLImportStorageClass;
7376 if (VD->hasAttr<DLLExportAttr>())
7377 return llvm::GlobalValue::DLLExportStorageClass;
7378 if (VD->hasAttr<DLLImportAttr>())
7379 return llvm::GlobalValue::DLLImportStorageClass;
7380 return llvm::GlobalValue::DefaultStorageClass;
7383void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
7384 if (!ObjCEmptyCacheVar) {
7385 ObjCEmptyCacheVar = new llvm::GlobalVariable(
7386 CGM.getModule(), ObjCTypes.CacheTy, false,
7387 llvm::GlobalValue::ExternalLinkage, nullptr, "_objc_empty_cache
");
7388 if (CGM.getTriple().isOSBinFormatCOFF())
7389 ObjCEmptyCacheVar->setDLLStorageClass(
7390 getStorage(CGM, "_objc_empty_cache
"));
7392 // Only OS X with deployment version <10.9 use the empty vtable symbol
7393 const llvm::Triple &Triple = CGM.getTarget().getTriple();
7394 if (Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 9))
7395 ObjCEmptyVtableVar = new llvm::GlobalVariable(
7396 CGM.getModule(), ObjCTypes.ImpnfABITy, false,
7397 llvm::GlobalValue::ExternalLinkage, nullptr, "_objc_empty_vtable
");
7399 ObjCEmptyVtableVar = llvm::ConstantPointerNull::get(CGM.DefaultPtrTy);
7402 // FIXME: Is this correct (that meta class size is never computed)?
7403 uint32_t InstanceStart =
7404 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy);
7405 uint32_t InstanceSize = InstanceStart;
7406 uint32_t flags = NonFragileABI_Class_Meta;
7408 llvm::Constant *SuperClassGV, *IsAGV;
7410 const auto *CI = ID->getClassInterface();
7411 assert(CI && "CGObjCNonFragileABIMac::GenerateClass -
class is 0
");
7413 // Build the flags for the metaclass.
7414 bool classIsHidden = (CGM.getTriple().isOSBinFormatCOFF())
7415 ? !CI->hasAttr<DLLExportAttr>()
7416 : CI->getVisibility() == HiddenVisibility;
7418 flags |= NonFragileABI_Class_Hidden;
7420 // FIXME: why is this flag set on the metaclass?
7421 // ObjC metaclasses have no fields and don't really get constructed.
7422 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
7423 flags |= NonFragileABI_Class_HasCXXStructors;
7424 if (!ID->hasNonZeroConstructors())
7425 flags |= NonFragileABI_Class_HasCXXDestructorOnly;
7428 if (!CI->getSuperClass()) {
7430 flags |= NonFragileABI_Class_Root;
7432 SuperClassGV = GetClassGlobal(CI, /*metaclass*/ false, NotForDefinition);
7433 IsAGV = GetClassGlobal(CI, /*metaclass*/ true, NotForDefinition);
7435 // Has a root. Current class is not a root.
7436 const ObjCInterfaceDecl *Root = ID->getClassInterface();
7437 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
7440 const auto *Super = CI->getSuperClass();
7441 IsAGV = GetClassGlobal(Root, /*metaclass*/ true, NotForDefinition);
7442 SuperClassGV = GetClassGlobal(Super, /*metaclass*/ true, NotForDefinition);
7445 llvm::GlobalVariable *CLASS_RO_GV =
7446 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
7448 llvm::GlobalVariable *MetaTClass = BuildClassObject(
7449 CI, /*metaclass*/ true, IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden);
7450 CGM.setGVProperties(MetaTClass, CI);
7451 DefinedMetaClasses.push_back(MetaTClass);
7453 // Metadata for the class
7456 flags |= NonFragileABI_Class_Hidden;
7458 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
7459 flags |= NonFragileABI_Class_HasCXXStructors;
7461 // Set a flag to enable a runtime optimization when a class has
7462 // fields that require destruction but which don't require
7463 // anything except zero-initialization during construction. This
7464 // is most notably true of __strong and __weak types, but you can
7465 // also imagine there being C++ types with non-trivial default
7466 // constructors that merely set all fields to null.
7467 if (!ID->hasNonZeroConstructors())
7468 flags |= NonFragileABI_Class_HasCXXDestructorOnly;
7471 if (hasObjCExceptionAttribute(CGM.getContext(), CI))
7472 flags |= NonFragileABI_Class_Exception;
7474 if (!CI->getSuperClass()) {
7475 flags |= NonFragileABI_Class_Root;
7476 SuperClassGV = nullptr;
7478 // Has a root. Current class is not a root.
7479 const auto *Super = CI->getSuperClass();
7480 SuperClassGV = GetClassGlobal(Super, /*metaclass*/ false, NotForDefinition);
7483 GetClassSizeInfo(ID, InstanceStart, InstanceSize);
7485 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
7487 llvm::GlobalVariable *ClassMD =
7488 BuildClassObject(CI, /*metaclass*/ false, MetaTClass, SuperClassGV,
7489 CLASS_RO_GV, classIsHidden);
7490 CGM.setGVProperties(ClassMD, CI);
7491 DefinedClasses.push_back(ClassMD);
7492 ImplementedClasses.push_back(CI);
7494 // Determine if this class is also "non-lazy
".
7495 if (ImplementationIsNonLazy(ID))
7496 DefinedNonLazyClasses.push_back(ClassMD);
7498 // Force the definition of the EHType if necessary.
7499 if (flags & NonFragileABI_Class_Exception)
7500 (void)GetInterfaceEHType(CI, ForDefinition);
7501 // Make sure method definition entries are all clear for next implementation.
7502 MethodDefinitions.clear();
7514CGObjCNonFragileABIMac::GenerateProtocolRef(CodeGenFunction &CGF,
7515 const ObjCProtocolDecl *PD) {
7517 // This routine is called for @protocol only. So, we must build definition
7518 // of protocol's meta-data (not a reference to it!)
7519 assert(!PD->isNonRuntimeProtocol() &&
7520 "attempting to get a protocol ref to a
static protocol.
");
7521 llvm::Constant *Init = GetOrEmitProtocol(PD);
7523 std::string ProtocolName("_OBJC_PROTOCOL_REFERENCE_$_
");
7524 ProtocolName += PD->getObjCRuntimeNameAsString();
7526 CharUnits Align = CGF.getPointerAlign();
7528 llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);
7530 return CGF.Builder.CreateAlignedLoad(PTGV->getValueType(), PTGV, Align);
7531 PTGV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
7532 llvm::GlobalValue::WeakAnyLinkage, Init,
7535 GetSectionName("__objc_protorefs
", "coalesced,no_dead_strip
"));
7536 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
7537 PTGV->setAlignment(Align.getAsAlign());
7538 if (!CGM.getTriple().isOSBinFormatMachO())
7539 PTGV->setComdat(CGM.getModule().getOrInsertComdat(ProtocolName));
7540 CGM.addUsedGlobal(PTGV);
7541 return CGF.Builder.CreateAlignedLoad(PTGV->getValueType(), PTGV, Align);
7556void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
7557 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
7558 const char *Prefix = "_OBJC_$_CATEGORY_
";
7560 llvm::SmallString<64> ExtCatName(Prefix);
7561 ExtCatName += Interface->getObjCRuntimeNameAsString();
7562 ExtCatName += "_$_
";
7563 ExtCatName += OCD->getNameAsString();
7565 ConstantInitBuilder builder(CGM);
7566 auto values = builder.beginStruct(ObjCTypes.CategorynfABITy);
7567 values.add(GetClassName(OCD->getIdentifier()->getName()));
7568 // meta-class entry symbol
7569 values.add(GetClassGlobal(Interface, /*metaclass*/ false, NotForDefinition));
7570 std::string listName =
7571 (Interface->getObjCRuntimeNameAsString() + "_$_
" + OCD->getName()).str();
7573 SmallVector<const ObjCMethodDecl *, 16> instanceMethods;
7574 SmallVector<const ObjCMethodDecl *, 8> classMethods;
7575 for (const auto *MD : OCD->methods()) {
7576 if (MD->isDirectMethod())
7578 if (MD->isInstanceMethod()) {
7579 instanceMethods.push_back(MD);
7581 classMethods.push_back(MD);
7585 llvm::Constant *InstanceMethodList = emitMethodList(
7586 listName, MethodListType::CategoryInstanceMethods, instanceMethods);
7587 const PointerAuthSchema &MethListSchema =
7588 CGM.getCodeGenOpts().PointerAuth.ObjCMethodListPointer;
7589 if (!InstanceMethodList->isNullValue())
7590 values.addSignedPointer(InstanceMethodList, MethListSchema, GlobalDecl(),
7593 values.add(InstanceMethodList);
7595 llvm::Constant *ClassMethodList = emitMethodList(
7596 listName, MethodListType::CategoryClassMethods, classMethods);
7597 if (!ClassMethodList->isNullValue())
7598 values.addSignedPointer(ClassMethodList, MethListSchema, GlobalDecl(),
7601 values.add(ClassMethodList);
7603 // Keep track of whether we have actual metadata to emit.
7604 bool isEmptyCategory =
7605 InstanceMethodList->isNullValue() && ClassMethodList->isNullValue();
7607 const ObjCCategoryDecl *Category =
7608 Interface->FindCategoryDeclaration(OCD->getIdentifier());
7610 SmallString<256> ExtName;
7611 llvm::raw_svector_ostream(ExtName)
7612 << Interface->getObjCRuntimeNameAsString() << "_$_
" << OCD->getName();
7614 EmitProtocolList("_OBJC_CATEGORY_PROTOCOLS_$_
" +
7615 Interface->getObjCRuntimeNameAsString() + "_$_
" +
7616 Category->getName(),
7617 Category->protocol_begin(), Category->protocol_end());
7618 auto propertyList = EmitPropertyList("_OBJC_$_PROP_LIST_
" + ExtName.str(),
7619 OCD, Category, ObjCTypes, false);
7620 auto classPropertyList =
7621 EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_
" + ExtName.str(), OCD,
7622 Category, ObjCTypes, true);
7623 values.add(protocolList);
7624 values.add(propertyList);
7625 values.add(classPropertyList);
7626 isEmptyCategory &= protocolList->isNullValue() &&
7627 propertyList->isNullValue() &&
7628 classPropertyList->isNullValue();
7630 values.addNullPointer(ObjCTypes.ProtocolListnfABIPtrTy);
7631 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
7632 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
7635 if (isEmptyCategory) {
7636 // Empty category, don't emit any metadata.
7638 MethodDefinitions.clear();
7643 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.CategorynfABITy);
7644 values.addInt(ObjCTypes.IntTy, Size);
7646 llvm::GlobalVariable *GCATV =
7647 finishAndCreateGlobal(values, ExtCatName.str(), CGM);
7648 CGM.addCompilerUsedGlobal(GCATV);
7649 if (Interface->hasAttr<ObjCClassStubAttr>())
7650 DefinedStubCategories.push_back(GCATV);
7652 DefinedCategories.push_back(GCATV);
7654 // Determine if this category is also "non-lazy
".
7655 if (ImplementationIsNonLazy(OCD))
7656 DefinedNonLazyCategories.push_back(GCATV);
7657 // method definition entries must be clear for next implementation.
7658 MethodDefinitions.clear();
7670void CGObjCNonFragileABIMac::emitMethodConstant(ConstantArrayBuilder &builder,
7671 const ObjCMethodDecl *MD,
7673 auto method = builder.beginStruct(ObjCTypes.MethodTy);
7674 method.add(GetMethodVarName(MD->getSelector()));
7675 method.add(GetMethodVarType(MD));
7678 // Protocol methods have no implementation. So, this entry is always NULL.
7679 method.addNullPointer(ObjCTypes.Int8PtrProgramASTy);
7681 llvm::Function *fn = GetMethodDefinition(MD);
7682 assert(fn && "no definition
for method?
");
7683 if (const PointerAuthSchema &Schema =
7684 CGM.getCodeGenOpts().PointerAuth.ObjCMethodListFunctionPointers) {
7685 llvm::Constant *Bitcast =
7686 llvm::ConstantExpr::getBitCast(fn, ObjCTypes.Int8PtrProgramASTy);
7687 method.addSignedPointer(Bitcast, Schema, GlobalDecl(), QualType());
7692 method.finishAndAddTo(builder);
7703llvm::Constant *CGObjCNonFragileABIMac::emitMethodList(
7704 Twine name, MethodListType kind, ArrayRef<const ObjCMethodDecl *> methods) {
7705 // Return null for empty list.
7706 if (methods.empty())
7707 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
7712 case MethodListType::CategoryInstanceMethods:
7713 prefix = "_OBJC_$_CATEGORY_INSTANCE_METHODS_
";
7714 forProtocol = false;
7716 case MethodListType::CategoryClassMethods:
7717 prefix = "_OBJC_$_CATEGORY_CLASS_METHODS_
";
7718 forProtocol = false;
7720 case MethodListType::InstanceMethods:
7721 prefix = "_OBJC_$_INSTANCE_METHODS_
";
7722 forProtocol = false;
7724 case MethodListType::ClassMethods:
7725 prefix = "_OBJC_$_CLASS_METHODS_
";
7726 forProtocol = false;
7729 case MethodListType::ProtocolInstanceMethods:
7730 prefix = "_OBJC_$_PROTOCOL_INSTANCE_METHODS_
";
7733 case MethodListType::ProtocolClassMethods:
7734 prefix = "_OBJC_$_PROTOCOL_CLASS_METHODS_
";
7737 case MethodListType::OptionalProtocolInstanceMethods:
7738 prefix = "_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_
";
7741 case MethodListType::OptionalProtocolClassMethods:
7742 prefix = "_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_
";
7747 ConstantInitBuilder builder(CGM);
7748 auto values = builder.beginStruct();
7750 // sizeof(struct _objc_method)
7751 unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.MethodTy);
7752 values.addInt(ObjCTypes.IntTy, Size);
7754 values.addInt(ObjCTypes.IntTy, methods.size());
7755 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
7756 for (auto MD : methods)
7757 emitMethodConstant(methodArray, MD, forProtocol);
7758 methodArray.finishAndAddTo(values);
7760 llvm::GlobalVariable *GV = finishAndCreateGlobal(values, prefix + name, CGM);
7761 CGM.addCompilerUsedGlobal(GV);
7767llvm::GlobalVariable *
7768CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
7769 const ObjCIvarDecl *Ivar) {
7770 const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
7771 llvm::SmallString<64> Name("OBJC_IVAR_$_
");
7772 Name += Container->getObjCRuntimeNameAsString();
7774 Name += Ivar->getName();
7775 llvm::GlobalVariable *IvarOffsetGV = CGM.getModule().getGlobalVariable(Name);
7776 if (!IvarOffsetGV) {
7777 IvarOffsetGV = new llvm::GlobalVariable(
7778 CGM.getModule(), ObjCTypes.IvarOffsetVarTy, false,
7779 llvm::GlobalValue::ExternalLinkage, nullptr, Name.str());
7780 if (CGM.getTriple().isOSBinFormatCOFF()) {
7781 bool IsPrivateOrPackage =
7782 Ivar->getAccessControl() == ObjCIvarDecl::Private ||
7783 Ivar->getAccessControl() == ObjCIvarDecl::Package;
7785 const ObjCInterfaceDecl *ContainingID = Ivar->getContainingInterface();
7787 if (ContainingID->hasAttr<DLLImportAttr>())
7788 IvarOffsetGV->setDLLStorageClass(
7789 llvm::GlobalValue::DLLImportStorageClass);
7790 else if (ContainingID->hasAttr<DLLExportAttr>() && !IsPrivateOrPackage)
7791 IvarOffsetGV->setDLLStorageClass(
7792 llvm::GlobalValue::DLLExportStorageClass);
7795 return IvarOffsetGV;
7799CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
7800 const ObjCIvarDecl *Ivar,
7801 unsigned long int Offset) {
7802 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
7803 IvarOffsetGV->setInitializer(
7804 llvm::ConstantInt::get(ObjCTypes.IvarOffsetVarTy, Offset));
7805 IvarOffsetGV->setAlignment(
7806 CGM.getDataLayout().getABITypeAlign(ObjCTypes.IvarOffsetVarTy));
7808 if (!CGM.getTriple().isOSBinFormatCOFF()) {
7809 // FIXME: This matches gcc, but shouldn't the visibility be set on the use
7810 // as well (i.e., in ObjCIvarOffsetVariable).
7811 if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
7812 Ivar->getAccessControl() == ObjCIvarDecl::Package ||
7813 ID->getVisibility() == HiddenVisibility)
7814 IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
7816 IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility);
7819 // If ID's layout is known, then make the global constant. This serves as a
7820 // useful assertion: we'll never use this variable to calculate ivar offsets,
7821 // so if the runtime tries to patch it then we should crash.
7822 if (isClassLayoutKnownStatically(ID))
7823 IvarOffsetGV->setConstant(true);
7825 if (CGM.getTriple().isOSBinFormatMachO())
7826 IvarOffsetGV->setSection("__DATA, __objc_ivar
");
7827 return IvarOffsetGV;
7848CGObjCNonFragileABIMac::EmitIvarList(const ObjCImplementationDecl *ID) {
7850 ConstantInitBuilder builder(CGM);
7851 auto ivarList = builder.beginStruct();
7852 ivarList.addInt(ObjCTypes.IntTy,
7853 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.IvarnfABITy));
7854 auto ivarCountSlot = ivarList.addPlaceholder();
7855 auto ivars = ivarList.beginArray(ObjCTypes.IvarnfABITy);
7857 const ObjCInterfaceDecl *OID = ID->getClassInterface();
7858 assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface
");
7860 // FIXME. Consolidate this with similar code in GenerateClass.
7862 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin(); IVD;
7863 IVD = IVD->getNextIvar()) {
7864 // Ignore unnamed bit-fields.
7865 if (!IVD->getDeclName())
7868 auto ivar = ivars.beginStruct(ObjCTypes.IvarnfABITy);
7869 ivar.add(EmitIvarOffsetVar(ID->getClassInterface(), IVD,
7870 ComputeIvarBaseOffset(CGM, ID, IVD)));
7871 ivar.add(GetMethodVarName(IVD->getIdentifier()));
7872 ivar.add(GetMethodVarType(IVD));
7873 llvm::Type *FieldTy = CGM.getTypes().ConvertTypeForMem(IVD->getType());
7874 unsigned Size = CGM.getDataLayout().getTypeAllocSize(FieldTy);
7876 CGM.getContext().getPreferredTypeAlign(IVD->getType().getTypePtr()) >>
7878 Align = llvm::Log2_32(Align);
7879 ivar.addInt(ObjCTypes.IntTy, Align);
7880 // NOTE. Size of a bitfield does not match gcc's, because of the
7881 // way bitfields are treated special in each. But I am told that
7882 // 'size' for bitfield ivars is ignored by the runtime so it does
7883 // not matter. If it matters, there is enough info to get the
7885 ivar.addInt(ObjCTypes.IntTy, Size);
7886 ivar.finishAndAddTo(ivars);
7888 // Return null for empty list.
7889 if (ivars.empty()) {
7892 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
7895 auto ivarCount = ivars.size();
7896 ivars.finishAndAddTo(ivarList);
7897 ivarList.fillPlaceholderWithInt(ivarCountSlot, ObjCTypes.IntTy, ivarCount);
7899 const char *Prefix = "_OBJC_$_INSTANCE_VARIABLES_
";
7900 llvm::GlobalVariable *GV = finishAndCreateGlobal(
7901 ivarList, Prefix + OID->getObjCRuntimeNameAsString(), CGM);
7902 CGM.addCompilerUsedGlobal(GV);
7907CGObjCNonFragileABIMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {
7908 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
7910 assert(!PD->isNonRuntimeProtocol() &&
7911 "attempting to GetOrEmit a non-runtime protocol
");
7913 // We use the initializer as a marker of whether this is a forward
7914 // reference or not. At module finalization we add the empty
7915 // contents for protocols which were referenced but never defined.
7916 llvm::SmallString<64> Protocol;
7917 llvm::raw_svector_ostream(Protocol)
7918 << "_OBJC_PROTOCOL_$_
" << PD->getObjCRuntimeNameAsString();
7920 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
7921 false, llvm::GlobalValue::ExternalLinkage,
7923 if (!CGM.getTriple().isOSBinFormatMachO())
7924 Entry->setComdat(CGM.getModule().getOrInsertComdat(Protocol));
7951CGObjCNonFragileABIMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
7952 llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
7954 // Early exit if a defining object has already been generated.
7955 if (Entry && Entry->hasInitializer())
7958 // Use the protocol definition, if there is one.
7959 assert(PD->hasDefinition() &&
7960 "emitting protocol metadata without definition
");
7961 PD = PD->getDefinition();
7963 auto methodLists = ProtocolMethodLists::get(PD);
7965 ConstantInitBuilder builder(CGM);
7966 auto values = builder.beginStruct(ObjCTypes.ProtocolnfABITy);
7969 values.addNullPointer(ObjCTypes.ObjectPtrTy);
7970 values.add(GetClassName(PD->getObjCRuntimeNameAsString()));
7971 values.add(EmitProtocolList("_OBJC_$_PROTOCOL_REFS_
" +
7972 PD->getObjCRuntimeNameAsString(),
7973 PD->protocol_begin(), PD->protocol_end()));
7974 values.add(methodLists.emitMethodList(
7975 this, PD, ProtocolMethodLists::RequiredInstanceMethods));
7976 values.add(methodLists.emitMethodList(
7977 this, PD, ProtocolMethodLists::RequiredClassMethods));
7978 values.add(methodLists.emitMethodList(
7979 this, PD, ProtocolMethodLists::OptionalInstanceMethods));
7980 values.add(methodLists.emitMethodList(
7981 this, PD, ProtocolMethodLists::OptionalClassMethods));
7983 EmitPropertyList("_OBJC_$_PROP_LIST_
" + PD->getObjCRuntimeNameAsString(),
7984 nullptr, PD, ObjCTypes, false));
7986 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
7987 values.addInt(ObjCTypes.IntTy, Size);
7988 values.addInt(ObjCTypes.IntTy, 0);
7989 values.add(EmitProtocolMethodTypes(
7990 "_OBJC_$_PROTOCOL_METHOD_TYPES_
" + PD->getObjCRuntimeNameAsString(),
7991 methodLists.emitExtendedTypesArray(this), ObjCTypes));
7993 // const char *demangledName;
7994 values.addNullPointer(ObjCTypes.Int8PtrTy);
7996 values.add(EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_
" +
7997 PD->getObjCRuntimeNameAsString(),
7998 nullptr, PD, ObjCTypes, true));
8001 // Already created, fix the linkage and update the initializer.
8002 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
8003 values.finishAndSetAsInitializer(Entry);
8005 llvm::SmallString<64> symbolName;
8006 llvm::raw_svector_ostream(symbolName)
8007 << "_OBJC_PROTOCOL_$_
" << PD->getObjCRuntimeNameAsString();
8009 Entry = values.finishAndCreateGlobal(symbolName, CGM.getPointerAlign(),
8011 llvm::GlobalValue::WeakAnyLinkage);
8012 if (!CGM.getTriple().isOSBinFormatMachO())
8013 Entry->setComdat(CGM.getModule().getOrInsertComdat(symbolName));
8015 Protocols[PD->getIdentifier()] = Entry;
8017 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
8018 CGM.addUsedGlobal(Entry);
8020 // Use this protocol meta-data to build protocol list table in section
8021 // __DATA, __objc_protolist
8022 llvm::SmallString<64> ProtocolRef;
8023 llvm::raw_svector_ostream(ProtocolRef)
8024 << "_OBJC_LABEL_PROTOCOL_$_
" << PD->getObjCRuntimeNameAsString();
8026 llvm::GlobalVariable *PTGV = new llvm::GlobalVariable(
8027 CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy, false,
8028 llvm::GlobalValue::WeakAnyLinkage, Entry, ProtocolRef);
8029 if (!CGM.getTriple().isOSBinFormatMachO())
8030 PTGV->setComdat(CGM.getModule().getOrInsertComdat(ProtocolRef));
8032 CGM.getDataLayout().getABITypeAlign(ObjCTypes.ProtocolnfABIPtrTy));
8034 GetSectionName("__objc_protolist
", "coalesced,no_dead_strip
"));
8035 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
8036 CGM.addUsedGlobal(PTGV);
8048llvm::Constant *CGObjCNonFragileABIMac::EmitProtocolList(
8049 Twine Name, ObjCProtocolDecl::protocol_iterator begin,
8050 ObjCProtocolDecl::protocol_iterator end) {
8051 // Just return null for empty protocol lists
8052 auto Protocols = GetRuntimeProtocolList(begin, end);
8053 if (Protocols.empty())
8054 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
8056 SmallVector<llvm::Constant *, 16> ProtocolRefs;
8057 ProtocolRefs.reserve(Protocols.size());
8059 for (const auto *PD : Protocols)
8060 ProtocolRefs.push_back(GetProtocolRef(PD));
8062 // If all of the protocols in the protocol list are objc_non_runtime_protocol
8064 if (ProtocolRefs.size() == 0)
8065 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
8067 // FIXME: We shouldn't need to do this lookup here, should we?
8068 SmallString<256> TmpName;
8069 Name.toVector(TmpName);
8070 llvm::GlobalVariable *GV =
8071 CGM.getModule().getGlobalVariable(TmpName.str(), true);
8075 ConstantInitBuilder builder(CGM);
8076 auto values = builder.beginStruct();
8077 auto countSlot = values.addPlaceholder();
8079 // A null-terminated array of protocols.
8080 auto array = values.beginArray(ObjCTypes.ProtocolnfABIPtrTy);
8081 for (auto const &proto : ProtocolRefs)
8083 auto count = array.size();
8084 array.addNullPointer(ObjCTypes.ProtocolnfABIPtrTy);
8086 array.finishAndAddTo(values);
8087 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
8089 GV = finishAndCreateGlobal(values, Name, CGM);
8090 CGM.addCompilerUsedGlobal(GV);
8100LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
8101 CodeGen::CodeGenFunction &CGF, QualType ObjectTy, llvm::Value *BaseValue,
8102 const ObjCIvarDecl *Ivar, unsigned CVRQualifiers) {
8103 ObjCInterfaceDecl *ID = ObjectTy->castAs<ObjCObjectType>()->getInterface();
8104 llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
8105 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
8110CGObjCNonFragileABIMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
8111 const ObjCInterfaceDecl *Interface,
8112 const ObjCIvarDecl *Ivar) {
8113 llvm::Value *IvarOffsetValue;
8114 if (isClassLayoutKnownStatically(Interface)) {
8115 IvarOffsetValue = llvm::ConstantInt::get(
8116 ObjCTypes.IvarOffsetVarTy,
8117 ComputeIvarBaseOffset(CGM, Interface->getImplementation(), Ivar));
8119 llvm::GlobalVariable *GV = ObjCIvarOffsetVariable(Interface, Ivar);
8120 IvarOffsetValue = CGF.Builder.CreateAlignedLoad(GV->getValueType(), GV,
8121 CGF.getSizeAlign(), "ivar
");
8122 if (IsIvarOffsetKnownIdempotent(CGF, Ivar))
8123 cast<llvm::LoadInst>(IvarOffsetValue)
8124 ->setMetadata(llvm::LLVMContext::MD_invariant_load,
8125 llvm::MDNode::get(VMContext, {}));
8128 // This could be 32bit int or 64bit integer depending on the architecture.
8129 // Cast it to 64bit integer value, if it is a 32bit integer ivar offset value
8130 // as this is what caller always expects.
8131 if (ObjCTypes.IvarOffsetVarTy == ObjCTypes.IntTy)
8132 IvarOffsetValue = CGF.Builder.CreateIntCast(
8133 IvarOffsetValue, ObjCTypes.LongTy, true, "ivar.conv
");
8134 return IvarOffsetValue;
8137static void appendSelectorForMessageRefTable(std::string &buffer,
8138 Selector selector) {
8139 if (selector.isUnarySelector()) {
8140 buffer += selector.getNameForSlot(0);
8144 for (unsigned i = 0, e = selector.getNumArgs(); i != e; ++i) {
8145 buffer += selector.getNameForSlot(i);
8160RValue CGObjCNonFragileABIMac::EmitVTableMessageSend(
8161 CodeGenFunction &CGF, ReturnValueSlot returnSlot, QualType resultType,
8162 Selector selector, llvm::Value *arg0, QualType arg0Type, bool isSuper,
8163 const CallArgList &formalArgs, const ObjCMethodDecl *method) {
8164 // Compute the actual arguments.
8167 // First argument: the receiver / super-call structure.
8169 arg0 = CGF.Builder.CreateBitCast(arg0, ObjCTypes.ObjectPtrTy);
8170 args.add(RValue::get(arg0), arg0Type);
8172 // Second argument: a pointer to the message ref structure. Leave
8173 // the actual argument value blank for now.
8174 args.add(RValue::get(nullptr), ObjCTypes.MessageRefCPtrTy);
8176 llvm::append_range(args, formalArgs);
8178 MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);
8180 NullReturnState nullReturn;
8182 // Find the function to call and the mangled name for the message
8183 // ref structure. Using a different mangled name wouldn't actually
8184 // be a problem; it would just be a waste.
8186 // The runtime currently never uses vtable dispatch for anything
8187 // except normal, non-super message-sends.
8188 // FIXME: don't use this for that.
8189 llvm::FunctionCallee fn = nullptr;
8190 std::string messageRefName("_
");
8191 if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
8193 fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
8194 messageRefName += "objc_msgSendSuper2_stret_fixup
";
8196 nullReturn.init(CGF, arg0);
8197 fn = ObjCTypes.getMessageSendStretFixupFn();
8198 messageRefName += "objc_msgSend_stret_fixup
";
8200 } else if (!isSuper && CGM.ReturnTypeUsesFPRet(resultType)) {
8201 fn = ObjCTypes.getMessageSendFpretFixupFn();
8202 messageRefName += "objc_msgSend_fpret_fixup
";
8205 fn = ObjCTypes.getMessageSendSuper2FixupFn();
8206 messageRefName += "objc_msgSendSuper2_fixup
";
8208 fn = ObjCTypes.getMessageSendFixupFn();
8209 messageRefName += "objc_msgSend_fixup
";
8212 assert(fn && "CGObjCNonFragileABIMac::EmitMessageSend
");
8213 messageRefName += '_';
8215 // Append the selector name, except use underscores anywhere we
8216 // would have used colons.
8217 appendSelectorForMessageRefTable(messageRefName, selector);
8219 llvm::GlobalVariable *messageRef =
8220 CGM.getModule().getGlobalVariable(messageRefName);
8222 // Build the message ref structure.
8223 ConstantInitBuilder builder(CGM);
8224 auto values = builder.beginStruct();
8225 values.add(cast<llvm::Constant>(fn.getCallee()));
8226 values.add(GetMethodVarName(selector));
8227 messageRef = values.finishAndCreateGlobal(
8228 messageRefName, CharUnits::fromQuantity(16),
8229 /*constant*/ false, llvm::GlobalValue::WeakAnyLinkage);
8230 messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility);
8231 messageRef->setSection(GetSectionName("__objc_msgrefs
", "coalesced
"));
8234 bool requiresnullCheck = false;
8235 if (CGM.getLangOpts().ObjCAutoRefCount && method)
8236 for (const auto *ParamDecl : method->parameters()) {
8237 if (ParamDecl->isDestroyedInCallee()) {
8238 if (!nullReturn.NullBB)
8239 nullReturn.init(CGF, arg0);
8240 requiresnullCheck = true;
8246 Address(CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy),
8247 ObjCTypes.MessageRefTy, CGF.getPointerAlign());
8249 // Update the message ref argument.
8250 args[1].setRValue(RValue::get(mref, CGF));
8252 // Load the function to call from the message ref table.
8253 Address calleeAddr = CGF.Builder.CreateStructGEP(mref, 0);
8254 llvm::Value *calleePtr = CGF.Builder.CreateLoad(calleeAddr, "msgSend_fn
");
8256 calleePtr = CGF.Builder.CreateBitCast(calleePtr, MSI.MessengerType);
8257 CGCallee callee(CGCalleeInfo(), calleePtr);
8259 RValue result = CGF.EmitCall(MSI.CallInfo, callee, returnSlot, args);
8260 return nullReturn.complete(CGF, returnSlot, result, resultType, formalArgs,
8261 requiresnullCheck ? method : nullptr);
8265CodeGen::RValue CGObjCNonFragileABIMac::GenerateMessageSend(
8266 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
8267 Selector Sel, llvm::Value *Receiver, const CallArgList &CallArgs,
8268 const ObjCInterfaceDecl *Class, const ObjCMethodDecl *Method) {
8269 return isVTableDispatchedSelector(Sel)
8270 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel, Receiver,
8271 CGF.getContext().getObjCIdType(), false,
8273 : EmitMessageSend(CGF, Return, ResultType, Sel, Receiver,
8274 CGF.getContext().getObjCIdType(), false,
8275 CallArgs, Method, Class, ObjCTypes);
8279CGObjCNonFragileABIMac::GetClassGlobal(const ObjCInterfaceDecl *ID,
8281 ForDefinition_t isForDefinition) {
8283 (metaclass ? getMetaclassSymbolPrefix() : getClassSymbolPrefix());
8284 return GetClassGlobal((prefix + ID->getObjCRuntimeNameAsString()).str(),
8285 isForDefinition, ID->isWeakImported(),
8287 CGM.getTriple().isOSBinFormatCOFF() &&
8288 ID->hasAttr<DLLImportAttr>());
8292CGObjCNonFragileABIMac::GetClassGlobal(StringRef Name,
8293 ForDefinition_t IsForDefinition,
8294 bool Weak, bool DLLImport) {
8295 llvm::GlobalValue::LinkageTypes L =
8296 Weak ? llvm::GlobalValue::ExternalWeakLinkage
8297 : llvm::GlobalValue::ExternalLinkage;
8299 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
8300 if (!GV || GV->getValueType() != ObjCTypes.ClassnfABITy) {
8301 auto *NewGV = new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, L,
8305 NewGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
8308 GV->replaceAllUsesWith(NewGV);
8309 GV->eraseFromParent();
8312 CGM.getModule().insertGlobalVariable(GV);
8315 assert(GV->getLinkage() == L);
8320CGObjCNonFragileABIMac::GetClassGlobalForClassRef(const ObjCInterfaceDecl *ID) {
8321 llvm::Constant *ClassGV =
8322 GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition);
8324 if (!ID->hasAttr<ObjCClassStubAttr>())
8327 ClassGV = llvm::ConstantExpr::getPointerCast(ClassGV, ObjCTypes.Int8PtrTy);
8329 // Stub classes are pointer-aligned. Classrefs pointing at stub classes
8330 // must set the least significant bit set to 1.
8331 auto *Idx = llvm::ConstantInt::get(CGM.Int32Ty, 1);
8332 return llvm::ConstantExpr::getPtrAdd(ClassGV, Idx);
8336CGObjCNonFragileABIMac::EmitLoadOfClassRef(CodeGenFunction &CGF,
8337 const ObjCInterfaceDecl *ID,
8338 llvm::GlobalVariable *Entry) {
8339 if (ID && ID->hasAttr<ObjCClassStubAttr>()) {
8340 // Classrefs pointing at Objective-C stub classes must be loaded by calling
8341 // a special runtime function.
8342 return CGF.EmitRuntimeCall(ObjCTypes.getLoadClassrefFn(), Entry,
8343 "load_classref_result
");
8346 CharUnits Align = CGF.getPointerAlign();
8347 return CGF.Builder.CreateAlignedLoad(Entry->getValueType(), Entry, Align);
8350llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(
8351 CodeGenFunction &CGF, IdentifierInfo *II, const ObjCInterfaceDecl *ID) {
8352 llvm::GlobalVariable *&Entry = ClassReferences[II];
8355 llvm::Constant *ClassGV;
8357 ClassGV = GetClassGlobalForClassRef(ID);
8359 ClassGV = GetClassGlobal((getClassSymbolPrefix() + II->getName()).str(),
8361 assert(ClassGV->getType() == ObjCTypes.ClassnfABIPtrTy &&
8362 "classref was emitted with the wrong
type?
");
8365 std::string SectionName =
8366 GetSectionName("__objc_classrefs
", "regular,no_dead_strip
");
8367 Entry = new llvm::GlobalVariable(
8368 CGM.getModule(), ClassGV->getType(), false,
8369 getLinkageTypeForObjCMetadata(CGM, SectionName), ClassGV,
8370 "OBJC_CLASSLIST_REFERENCES_$_
");
8371 Entry->setAlignment(CGF.getPointerAlign().getAsAlign());
8372 if (!ID || !ID->hasAttr<ObjCClassStubAttr>())
8373 Entry->setSection(SectionName);
8375 CGM.addCompilerUsedGlobal(Entry);
8378 return EmitLoadOfClassRef(CGF, ID, Entry);
8381llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CodeGenFunction &CGF,
8382 const ObjCInterfaceDecl *ID) {
8383 // If the class has the objc_runtime_visible attribute, we need to
8384 // use the Objective-C runtime to get the class.
8385 if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
8386 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
8388 return EmitClassRefFromId(CGF, ID->getIdentifier(), ID);
8392CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
8393 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool
");
8394 return EmitClassRefFromId(CGF, II, nullptr);
8398CGObjCNonFragileABIMac::EmitSuperClassRef(CodeGenFunction &CGF,
8399 const ObjCInterfaceDecl *ID) {
8400 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
8403 llvm::Constant *ClassGV = GetClassGlobalForClassRef(ID);
8404 std::string SectionName =
8405 GetSectionName("__objc_superrefs
", "regular,no_dead_strip
");
8406 Entry = new llvm::GlobalVariable(CGM.getModule(), ClassGV->getType(), false,
8407 llvm::GlobalValue::PrivateLinkage, ClassGV,
8408 "OBJC_CLASSLIST_SUP_REFS_$_
");
8409 Entry->setAlignment(CGF.getPointerAlign().getAsAlign());
8410 Entry->setSection(SectionName);
8411 CGM.addCompilerUsedGlobal(Entry);
8414 return EmitLoadOfClassRef(CGF, ID, Entry);
8420llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(
8421 CodeGenFunction &CGF, const ObjCInterfaceDecl *ID, bool Weak) {
8422 CharUnits Align = CGF.getPointerAlign();
8423 llvm::GlobalVariable *&Entry = MetaClassReferences[ID->getIdentifier()];
8425 auto MetaClassGV = GetClassGlobal(ID, /*metaclass*/ true, NotForDefinition);
8426 std::string SectionName =
8427 GetSectionName("__objc_superrefs
", "regular,no_dead_strip
");
8428 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
8429 false, llvm::GlobalValue::PrivateLinkage,
8430 MetaClassGV, "OBJC_CLASSLIST_SUP_REFS_$_
");
8431 Entry->setAlignment(Align.getAsAlign());
8432 Entry->setSection(SectionName);
8433 CGM.addCompilerUsedGlobal(Entry);
8436 return CGF.Builder.CreateAlignedLoad(ObjCTypes.ClassnfABIPtrTy, Entry, Align);
8441llvm::Value *CGObjCNonFragileABIMac::GetClass(CodeGenFunction &CGF,
8442 const ObjCInterfaceDecl *ID) {
8443 if (ID->isWeakImported()) {
8444 auto ClassGV = GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition);
8446 assert(!isa<llvm::GlobalVariable>(ClassGV) ||
8447 cast<llvm::GlobalVariable>(ClassGV)->hasExternalWeakLinkage());
8450 return EmitClassRef(CGF, ID);
8456CodeGen::RValue CGObjCNonFragileABIMac::GenerateMessageSendSuper(
8457 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
8458 Selector Sel, const ObjCInterfaceDecl *Class, bool isCategoryImpl,
8459 llvm::Value *Receiver, bool IsClassMessage,
8460 const CodeGen::CallArgList &CallArgs, const ObjCMethodDecl *Method) {
8462 // Create and init a super structure; this is a (receiver, class)
8463 // pair we will pass to objc_msgSendSuper.
8464 RawAddress ObjCSuper = CGF.CreateTempAlloca(
8465 ObjCTypes.SuperTy, CGF.getPointerAlign(), "objc_super
");
8467 llvm::Value *ReceiverAsObject =
8468 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
8469 CGF.Builder.CreateStore(ReceiverAsObject,
8470 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
8472 // If this is a class message the metaclass is passed as the target.
8473 llvm::Value *Target;
8475 Target = EmitMetaClassRef(CGF, Class, Class->isWeakImported());
8477 Target = EmitSuperClassRef(CGF, Class);
8479 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
8481 llvm::Type *ClassTy =
8482 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
8483 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
8484 CGF.Builder.CreateStore(Target, CGF.Builder.CreateStructGEP(ObjCSuper, 1));
8486 return (isVTableDispatchedSelector(Sel))
8487 ? EmitVTableMessageSend(
8488 CGF, Return, ResultType, Sel, ObjCSuper.getPointer(),
8489 ObjCTypes.SuperPtrCTy, true, CallArgs, Method)
8490 : EmitMessageSend(CGF, Return, ResultType, Sel,
8491 ObjCSuper.getPointer(), ObjCTypes.SuperPtrCTy,
8492 true, CallArgs, Method, Class, ObjCTypes);
8495llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CodeGenFunction &CGF,
8497 Address Addr = EmitSelectorAddr(Sel);
8499 llvm::LoadInst *LI = CGF.Builder.CreateLoad(Addr);
8500 LI->setMetadata(llvm::LLVMContext::MD_invariant_load,
8501 llvm::MDNode::get(VMContext, {}));
8505ConstantAddress CGObjCNonFragileABIMac::EmitSelectorAddr(Selector Sel) {
8506 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
8507 CharUnits Align = CGM.getPointerAlign();
8509 std::string SectionName =
8510 GetSectionName("__objc_selrefs
", "literal_pointers,no_dead_strip
");
8511 Entry = new llvm::GlobalVariable(
8512 CGM.getModule(), ObjCTypes.SelectorPtrTy, false,
8513 getLinkageTypeForObjCMetadata(CGM, SectionName), GetMethodVarName(Sel),
8514 "OBJC_SELECTOR_REFERENCES_
");
8515 Entry->setExternallyInitialized(true);
8516 Entry->setSection(SectionName);
8517 Entry->setAlignment(Align.getAsAlign());
8518 CGM.addCompilerUsedGlobal(Entry);
8521 return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align);
8527void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
8528 llvm::Value *src, Address dst,
8529 llvm::Value *ivarOffset) {
8530 llvm::Type *SrcTy = src->getType();
8531 if (!isa<llvm::PointerType>(SrcTy)) {
8532 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
8533 assert(Size <= 8 && "does
not support size > 8
");
8534 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
8535 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
8536 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
8538 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
8539 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
8540 ObjCTypes.PtrObjectPtrTy);
8541 llvm::Value *args[] = {src, dstVal, ivarOffset};
8542 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
8548void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
8549 CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dst) {
8550 llvm::Type *SrcTy = src->getType();
8551 if (!isa<llvm::PointerType>(SrcTy)) {
8552 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
8553 assert(Size <= 8 && "does
not support size > 8
");
8554 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
8555 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
8556 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
8558 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
8559 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
8560 ObjCTypes.PtrObjectPtrTy);
8561 llvm::Value *args[] = {src, dstVal};
8562 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), args,
8566void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
8567 CodeGen::CodeGenFunction &CGF, Address DestPtr, Address SrcPtr,
8568 llvm::Value *Size) {
8569 llvm::Value *args[] = {DestPtr.emitRawPointer(CGF),
8570 SrcPtr.emitRawPointer(CGF), Size};
8571 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
8578CGObjCNonFragileABIMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
8579 Address AddrWeakObj) {
8580 llvm::Type *DestTy = AddrWeakObj.getElementType();
8581 llvm::Value *AddrWeakObjVal = CGF.Builder.CreateBitCast(
8582 AddrWeakObj.emitRawPointer(CGF), ObjCTypes.PtrObjectPtrTy);
8583 llvm::Value *read_weak = CGF.EmitNounwindRuntimeCall(
8584 ObjCTypes.getGcReadWeakFn(), AddrWeakObjVal, "weakread
");
8585 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
8592void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
8593 llvm::Value *src, Address dst) {
8594 llvm::Type *SrcTy = src->getType();
8595 if (!isa<llvm::PointerType>(SrcTy)) {
8596 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
8597 assert(Size <= 8 && "does
not support size > 8
");
8598 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
8599 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
8600 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
8602 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
8603 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
8604 ObjCTypes.PtrObjectPtrTy);
8605 llvm::Value *args[] = {src, dstVal};
8606 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), args,
8613void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
8614 llvm::Value *src, Address dst,
8616 llvm::Type *SrcTy = src->getType();
8617 if (!isa<llvm::PointerType>(SrcTy)) {
8618 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
8619 assert(Size <= 8 && "does
not support size > 8
");
8620 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
8621 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
8622 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
8624 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
8625 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
8626 ObjCTypes.PtrObjectPtrTy);
8627 llvm::Value *args[] = {src, dstVal};
8629 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), args,
8632 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(), args,
8633 "threadlocalassign
");
8636void CGObjCNonFragileABIMac::EmitSynchronizedStmt(
8637 CodeGen::CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S) {
8638 EmitAtSynchronizedStmt(CGF, S, ObjCTypes.getSyncEnterFn(),
8639 ObjCTypes.getSyncExitFn());
8642llvm::Constant *CGObjCNonFragileABIMac::GetEHType(QualType T) {
8643 // There's a particular fixed type info for 'id'.
8644 if (T->isObjCIdType() || T->isObjCQualifiedIdType()) {
8645 auto *IDEHType = CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id
");
8647 IDEHType = new llvm::GlobalVariable(
8648 CGM.getModule(), ObjCTypes.EHTypeTy, false,
8649 llvm::GlobalValue::ExternalLinkage, nullptr, "OBJC_EHTYPE_id
");
8650 if (CGM.getTriple().isOSBinFormatCOFF())
8651 IDEHType->setDLLStorageClass(getStorage(CGM, "OBJC_EHTYPE_id
"));
8656 // All other types should be Objective-C interface pointer types.
8657 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
8660 const ObjCInterfaceType *IT = PT->getInterfaceType();
8661 assert(IT && "Invalid
@catch type.
");
8663 return GetInterfaceEHType(IT->getDecl(), NotForDefinition);
8666void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
8667 const ObjCAtTryStmt &S) {
8668 EmitTryCatchStmt(CGF, S, ObjCTypes.getObjCBeginCatchFn(),
8669 ObjCTypes.getObjCEndCatchFn(),
8670 ObjCTypes.getExceptionRethrowFn());
8674void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
8675 const ObjCAtThrowStmt &S,
8676 bool ClearInsertionPoint) {
8677 if (const Expr *ThrowExpr = S.getThrowExpr()) {
8678 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
8679 Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
8680 llvm::CallBase *Call =
8681 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception);
8682 Call->setDoesNotReturn();
8684 llvm::CallBase *Call =
8685 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionRethrowFn());
8686 Call->setDoesNotReturn();
8689 CGF.Builder.CreateUnreachable();
8690 if (ClearInsertionPoint)
8691 CGF.Builder.ClearInsertionPoint();
8695CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
8696 ForDefinition_t IsForDefinition) {
8697 llvm::GlobalVariable *&Entry = EHTypeReferences[ID->getIdentifier()];
8698 StringRef ClassName = ID->getObjCRuntimeNameAsString();
8700 // If we don't need a definition, return the entry if found or check
8701 // if we use an external reference.
8702 if (!IsForDefinition) {
8706 // If this type (or a super class) has the __objc_exception__
8707 // attribute, emit an external reference.
8708 if (hasObjCExceptionAttribute(CGM.getContext(), ID)) {
8709 std::string EHTypeName = ("OBJC_EHTYPE_$_
" + ClassName).str();
8710 Entry = new llvm::GlobalVariable(
8711 CGM.getModule(), ObjCTypes.EHTypeTy, false,
8712 llvm::GlobalValue::ExternalLinkage, nullptr, EHTypeName);
8713 CGM.setGVProperties(Entry, ID);
8718 // Otherwise we need to either make a new entry or fill in the initializer.
8719 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition
");
8721 std::string VTableName = "objc_ehtype_vtable
";
8722 auto *VTableGV = CGM.getModule().getGlobalVariable(VTableName);
8724 VTableGV = new llvm::GlobalVariable(
8725 CGM.getModule(), ObjCTypes.Int8PtrTy, false,
8726 llvm::GlobalValue::ExternalLinkage, nullptr, VTableName);
8727 if (CGM.getTriple().isOSBinFormatCOFF())
8728 VTableGV->setDLLStorageClass(getStorage(CGM, VTableName));
8731 llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2);
8732 llvm::Constant *VTablePtr = llvm::ConstantExpr::getInBoundsGetElementPtr(
8733 VTableGV->getValueType(), VTableGV, VTableIdx);
8735 ConstantInitBuilder builder(CGM);
8736 auto values = builder.beginStruct(ObjCTypes.EHTypeTy);
8737 const PointerAuthSchema &TypeInfoSchema =
8738 CGM.getCodeGenOpts().PointerAuth.CXXTypeInfoVTablePointer;
8739 values.addSignedPointer(VTablePtr, TypeInfoSchema, GlobalDecl(), QualType());
8741 values.add(GetClassName(ClassName));
8742 values.add(GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition));
8744 llvm::GlobalValue::LinkageTypes L = IsForDefinition
8745 ? llvm::GlobalValue::ExternalLinkage
8746 : llvm::GlobalValue::WeakAnyLinkage;
8748 values.finishAndSetAsInitializer(Entry);
8749 Entry->setAlignment(CGM.getPointerAlign().getAsAlign());
8751 Entry = values.finishAndCreateGlobal("OBJC_EHTYPE_$_
" + ClassName,
8752 CGM.getPointerAlign(),
8753 /*constant*/ false, L);
8754 if (hasObjCExceptionAttribute(CGM.getContext(), ID))
8755 CGM.setGVProperties(Entry, ID);
8757 assert(Entry->getLinkage() == L);
8759 if (!CGM.getTriple().isOSBinFormatCOFF())
8760 if (ID->getVisibility() == HiddenVisibility)
8761 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
8763 if (IsForDefinition)
8764 if (CGM.getTriple().isOSBinFormatMachO())
8765 Entry->setSection("__DATA,__objc_const
");
8772CodeGen::CGObjCRuntime *
8773CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
8774 switch (CGM.getLangOpts().ObjCRuntime.getKind()) {
8775 case ObjCRuntime::FragileMacOSX:
8776 return new CGObjCMac(CGM);
8778 case ObjCRuntime::MacOSX:
8779 case ObjCRuntime::iOS:
8780 case ObjCRuntime::WatchOS:
8781 return new CGObjCNonFragileABIMac(CGM);
8783 case ObjCRuntime::GNUstep:
8784 case ObjCRuntime::GCC:
8785 case ObjCRuntime::ObjFW:
8786 llvm_unreachable("these runtimes are
not Mac runtimes
");
8788 llvm_unreachable("bad runtime
");
8791// Public wrapper function for external compilers (e.g., Swift) to access
8792// the Mac runtime's GetDirectMethodCallee functionality.
8793llvm::Function *clang::CodeGen::getObjCDirectMethodCallee(
8794 CodeGenModule &CGM, const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD,
8795 bool ReceiverCanBeNull, bool ClassObjectCanBeUnrealized) {
8796 // This function should only be called when targeting Darwin platforms,
8797 // which always use the Mac runtime.
8798 assert(CGM.getLangOpts().ObjCRuntime.isNeXTFamily() &&
8800 CGObjCCommonMac *MacRuntime =
8801 static_cast<CGObjCCommonMac *>(&CGM.getObjCRuntime());
8802 return MacRuntime->GetDirectMethodCallee(OMD, CD, ReceiverCanBeNull,
8803 ClassObjectCanBeUnrealized);
Defines the clang::ASTContext interface.
@ FragileABI_Class_Meta
Is a meta-class.
@ FragileABI_Class_Hidden
Has hidden visibility.
@ FragileABI_Class_Factory
Apparently: is not a meta-class.
@ FragileABI_Class_HasCXXStructors
Has a non-trivial constructor or destructor.
@ FragileABI_Class_HasMRCWeakIvars
Class implementation was compiled under MRC and has MRC weak ivars.
@ FragileABI_Class_CompiledByARC
Class implementation was compiled under ARC.
static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT, bool pointee=false)
static bool hasWeakMember(QualType type)
static std::string getBlockLayoutInfoString(const SmallVectorImpl< CGObjCCommonMac::RUN_SKIP > &RunSkipBlockVars, bool HasCopyDisposeHelpers)
static llvm::StringMapEntry< llvm::GlobalVariable * > & GetConstantStringEntry(llvm::StringMap< llvm::GlobalVariable * > &Map, const StringLiteral *Literal, unsigned &StringLength)
static llvm::GlobalValue::LinkageTypes getLinkageTypeForObjCMetadata(CodeGenModule &CGM, StringRef Section)
static void addIfPresent(llvm::DenseSet< llvm::Value * > &S, Address V)
@ kCFTaggedObjectID_Integer
static void PushProtocolProperties(llvm::SmallPtrSet< const IdentifierInfo *, 16 > &PropertySet, SmallVectorImpl< const ObjCPropertyDecl * > &Properties, const ObjCProtocolDecl *Proto, bool IsClassProperty)
static llvm::GlobalVariable * finishAndCreateGlobal(ConstantInitBuilder::StructBuilder &Builder, const llvm::Twine &Name, CodeGenModule &CGM)
A helper function to create an internal or private global variable.
static bool hasMRCWeakIvars(CodeGenModule &CGM, const ObjCImplementationDecl *ID)
For compatibility, we only want to set the "HasMRCWeakIvars" flag (and actually fill in a layout stri...
@ NonFragileABI_Class_HasCXXDestructorOnly
Class has non-trivial destructors, but zero-initialization is okay.
@ NonFragileABI_Class_Hidden
Has hidden visibility.
@ NonFragileABI_Class_HasCXXStructors
Has a non-trivial constructor or destructor.
@ NonFragileABI_Class_Exception
Has the exception attribute.
@ NonFragileABI_Class_HasIvarReleaser
(Obsolete) ARC-specific: this class has a .release_ivars method
@ NonFragileABI_Class_Root
Is a root class.
@ NonFragileABI_Class_Meta
Is a meta-class.
@ NonFragileABI_Class_HasMRCWeakIvars
Class implementation was compiled under MRC and has MRC weak ivars.
@ NonFragileABI_Class_CompiledByARC
Class implementation was compiled under ARC.
static llvm::Constant * getConstantGEP(llvm::LLVMContext &VMContext, llvm::GlobalVariable *C, unsigned idx0, unsigned idx1)
getConstantGEP() - Help routine to construct simple GEPs.
static bool hasObjCExceptionAttribute(ASTContext &Context, const ObjCInterfaceDecl *OID)
hasObjCExceptionAttribute - Return true if this class or any super class has the objc_exception attri...
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
Result
Implement __builtin_bit_cast and related operations.
Defines the clang::LangOptions interface.
llvm::MachO::Target Target
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
Defines the Objective-C statement AST node classes.
__device__ __2f16 float __ockl_bool s
__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
Selector getSelector(unsigned NumArgs, const IdentifierInfo **IIV)
Can create any sort of selector.
std::string getAsString() const
Derive the full selector name (e.g.
StringLiteral - This represents a string literal expression, e.g.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
unsigned getCharWidth() const
bool isBlockPointerType() const
CanQualType getCanonicalTypeUnqualified() const
bool isObjCQualifiedIdType() const
bool isObjCIdType() const
bool isObjCObjectPointerType() const
bool isObjCQualifiedClassType() const
bool isObjCClassType() const
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
const T * castAsCanonical() const
Return this type's canonical type cast to the specified type.
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
llvm::Function * getObjCDirectMethodCallee(CodeGenModule &CGM, const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD, bool ReceiverCanBeNull, bool ClassObjectCanBeUnrealized)
Get the appropriate callee for an ObjC direct method.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, BlockDecl > blockDecl
Matches block declarations.
bool LT(InterpState &S, CodePtr OpPC)
@ Address
A pointer to a ValueDecl.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
@ Match
This is not an overload because the signature exactly matches an existing declaration.
bool isa(CodeGen::Address addr)
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
Selector GetUnarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing an unary selector.
Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
@ Type
The name was classified as a type.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
U cast(CodeGen::Address addr)
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ HiddenVisibility
Objects with "hidden" visibility are not seen by the dynamic linker.
CLINKAGE int printf(__constant const char *st,...) __attribute__((format(printf
float __ovld __cnfn length(float)
Return the length of vector p, i.e., sqrt(p.x2 + p.y 2 + ...)
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.