31#include "llvm/ADT/CachedHashString.h"
32#include "llvm/ADT/DenseSet.h"
33#include "llvm/ADT/SetVector.h"
34#include "llvm/ADT/SmallPtrSet.h"
35#include "llvm/ADT/SmallString.h"
36#include "llvm/IR/DataLayout.h"
37#include "llvm/IR/InlineAsm.h"
38#include "llvm/IR/IntrinsicInst.h"
39#include "llvm/IR/LLVMContext.h"
40#include "llvm/IR/Module.h"
41#include "llvm/Support/ScopedPrinter.h"
42#include "llvm/Support/raw_ostream.h"
54class ObjCCommonTypesHelper {
56 llvm::LLVMContext &VMContext;
66 llvm::FunctionCallee getMessageSendFn()
const {
69 llvm::Type *params[] = {ObjectPtrTy, SelectorPtrTy};
70 return CGM.CreateRuntimeFunction(
71 llvm::FunctionType::get(ObjectPtrTy, params,
true),
"objc_msgSend",
72 llvm::AttributeList::get(CGM.getLLVMContext(),
73 llvm::AttributeList::FunctionIndex,
74 llvm::Attribute::NonLazyBind));
82 llvm::FunctionCallee getMessageSendStretFn()
const {
83 llvm::Type *params[] = {ObjectPtrTy, SelectorPtrTy};
84 return CGM.CreateRuntimeFunction(
85 llvm::FunctionType::get(CGM.VoidTy, params,
true),
86 "objc_msgSend_stret");
94 llvm::FunctionCallee getMessageSendFpretFn()
const {
95 llvm::Type *params[] = {ObjectPtrTy, SelectorPtrTy};
96 return CGM.CreateRuntimeFunction(
97 llvm::FunctionType::get(CGM.DoubleTy, params,
true),
98 "objc_msgSend_fpret");
106 llvm::FunctionCallee getMessageSendFp2retFn()
const {
107 llvm::Type *params[] = {ObjectPtrTy, SelectorPtrTy};
108 llvm::Type *longDoubleType = llvm::Type::getX86_FP80Ty(VMContext);
109 llvm::Type *resultType =
110 llvm::StructType::get(longDoubleType, longDoubleType);
112 return CGM.CreateRuntimeFunction(
113 llvm::FunctionType::get(resultType, params,
true),
114 "objc_msgSend_fp2ret");
122 llvm::FunctionCallee getMessageSendSuperFn()
const {
123 llvm::Type *params[] = {SuperPtrTy, SelectorPtrTy};
124 return CGM.CreateRuntimeFunction(
125 llvm::FunctionType::get(ObjectPtrTy, params,
true),
126 "objc_msgSendSuper");
133 llvm::FunctionCallee getMessageSendSuperFn2()
const {
134 llvm::Type *params[] = {SuperPtrTy, SelectorPtrTy};
135 return CGM.CreateRuntimeFunction(
136 llvm::FunctionType::get(ObjectPtrTy, params,
true),
137 "objc_msgSendSuper2");
144 llvm::FunctionCallee getMessageSendSuperStretFn()
const {
145 llvm::Type *params[] = {Int8PtrTy, SuperPtrTy, SelectorPtrTy};
146 return CGM.CreateRuntimeFunction(
147 llvm::FunctionType::get(CGM.VoidTy, params,
true),
148 "objc_msgSendSuper_stret");
155 llvm::FunctionCallee getMessageSendSuperStretFn2()
const {
156 llvm::Type *params[] = {Int8PtrTy, SuperPtrTy, SelectorPtrTy};
157 return CGM.CreateRuntimeFunction(
158 llvm::FunctionType::get(CGM.VoidTy, params,
true),
159 "objc_msgSendSuper2_stret");
162 llvm::FunctionCallee getMessageSendSuperFpretFn()
const {
164 return getMessageSendSuperFn();
167 llvm::FunctionCallee getMessageSendSuperFpretFn2()
const {
169 return getMessageSendSuperFn2();
173 CodeGen::CodeGenModule &CGM;
176 llvm::IntegerType *ShortTy, *IntTy, *LongTy;
177 llvm::PointerType *Int8PtrTy, *Int8PtrPtrTy;
178 llvm::PointerType *Int8PtrProgramASTy;
179 llvm::Type *IvarOffsetVarTy;
182 llvm::PointerType *ObjectPtrTy;
185 llvm::PointerType *PtrObjectPtrTy;
188 llvm::PointerType *SelectorPtrTy;
193 QualType SuperPtrCTy;
196 llvm::StructType *SuperTy;
198 llvm::PointerType *SuperPtrTy;
202 llvm::StructType *PropertyTy;
206 llvm::StructType *PropertyListTy;
208 llvm::PointerType *PropertyListPtrTy;
211 llvm::StructType *MethodTy;
216 llvm::PointerType *CachePtrTy;
218 llvm::FunctionCallee getGetPropertyFn() {
219 CodeGen::CodeGenTypes &Types = CGM.getTypes();
220 ASTContext &Ctx = CGM.getContext();
229 return CGM.CreateRuntimeFunction(FTy,
"objc_getProperty");
232 llvm::FunctionCallee getSetPropertyFn() {
233 CodeGen::CodeGenTypes &Types = CGM.getTypes();
234 ASTContext &Ctx = CGM.getContext();
247 return CGM.CreateRuntimeFunction(FTy,
"objc_setProperty");
250 llvm::FunctionCallee getOptimizedSetPropertyFn(
bool atomic,
bool copy) {
251 CodeGen::CodeGenTypes &Types = CGM.getTypes();
252 ASTContext &Ctx = CGM.getContext();
262 SmallVector<CanQualType, 4> Params;
265 Params.push_back(IdType);
266 Params.push_back(SelType);
267 Params.push_back(IdType);
273 name =
"objc_setProperty_atomic_copy";
274 else if (atomic && !copy)
275 name =
"objc_setProperty_atomic";
276 else if (!atomic && copy)
277 name =
"objc_setProperty_nonatomic_copy";
279 name =
"objc_setProperty_nonatomic";
281 return CGM.CreateRuntimeFunction(FTy, name);
284 llvm::FunctionCallee getCopyStructFn() {
285 CodeGen::CodeGenTypes &Types = CGM.getTypes();
286 ASTContext &Ctx = CGM.getContext();
288 SmallVector<CanQualType, 5> Params;
292 Params.push_back(Ctx.
BoolTy);
293 Params.push_back(Ctx.
BoolTy);
296 return CGM.CreateRuntimeFunction(FTy,
"objc_copyStruct");
303 llvm::FunctionCallee getCppAtomicObjectFunction() {
304 CodeGen::CodeGenTypes &Types = CGM.getTypes();
305 ASTContext &Ctx = CGM.getContext();
308 SmallVector<CanQualType, 3> Params;
314 return CGM.CreateRuntimeFunction(FTy,
"objc_copyCppObjectAtomic");
317 llvm::FunctionCallee getEnumerationMutationFn() {
318 CodeGen::CodeGenTypes &Types = CGM.getTypes();
319 ASTContext &Ctx = CGM.getContext();
321 SmallVector<CanQualType, 1> Params;
325 return CGM.CreateRuntimeFunction(FTy,
"objc_enumerationMutation");
328 llvm::FunctionCallee getLookUpClassFn() {
329 CodeGen::CodeGenTypes &Types = CGM.getTypes();
330 ASTContext &Ctx = CGM.getContext();
332 SmallVector<CanQualType, 1> Params;
335 llvm::FunctionType *FTy =
338 return CGM.CreateRuntimeFunction(FTy,
"objc_lookUpClass");
342 llvm::FunctionCallee getGcReadWeakFn() {
344 llvm::Type *args[] = {CGM.DefaultPtrTy};
345 llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, args,
false);
346 return CGM.CreateRuntimeFunction(FTy,
"objc_read_weak");
350 llvm::FunctionCallee getGcAssignWeakFn() {
352 llvm::Type *args[] = {ObjectPtrTy, CGM.DefaultPtrTy};
353 llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, args,
false);
354 return CGM.CreateRuntimeFunction(FTy,
"objc_assign_weak");
358 llvm::FunctionCallee getGcAssignGlobalFn() {
360 llvm::Type *args[] = {ObjectPtrTy, CGM.DefaultPtrTy};
361 llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, args,
false);
362 return CGM.CreateRuntimeFunction(FTy,
"objc_assign_global");
366 llvm::FunctionCallee getGcAssignThreadLocalFn() {
368 llvm::Type *args[] = {ObjectPtrTy, CGM.DefaultPtrTy};
369 llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, args,
false);
370 return CGM.CreateRuntimeFunction(FTy,
"objc_assign_threadlocal");
374 llvm::FunctionCallee getGcAssignIvarFn() {
376 llvm::Type *args[] = {ObjectPtrTy, CGM.DefaultPtrTy, CGM.PtrDiffTy};
377 llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, args,
false);
378 return CGM.CreateRuntimeFunction(FTy,
"objc_assign_ivar");
382 llvm::FunctionCallee GcMemmoveCollectableFn() {
384 llvm::Type *args[] = {Int8PtrTy, Int8PtrTy, LongTy};
385 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, args,
false);
386 return CGM.CreateRuntimeFunction(FTy,
"objc_memmove_collectable");
390 llvm::FunctionCallee getGcAssignStrongCastFn() {
392 llvm::Type *args[] = {ObjectPtrTy, CGM.DefaultPtrTy};
393 llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, args,
false);
394 return CGM.CreateRuntimeFunction(FTy,
"objc_assign_strongCast");
398 llvm::FunctionCallee getExceptionThrowFn() {
400 llvm::Type *args[] = {ObjectPtrTy};
401 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy, args,
false);
402 return CGM.CreateRuntimeFunction(FTy,
"objc_exception_throw");
406 llvm::FunctionCallee getExceptionRethrowFn() {
408 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy,
false);
409 return CGM.CreateRuntimeFunction(FTy,
"objc_exception_rethrow");
413 llvm::FunctionCallee getSyncEnterFn() {
415 llvm::Type *args[] = {ObjectPtrTy};
416 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.IntTy, args,
false);
417 return CGM.CreateRuntimeFunction(FTy,
"objc_sync_enter");
421 llvm::FunctionCallee getSyncExitFn() {
423 llvm::Type *args[] = {ObjectPtrTy};
424 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.IntTy, args,
false);
425 return CGM.CreateRuntimeFunction(FTy,
"objc_sync_exit");
428 llvm::FunctionCallee getSendFn(
bool IsSuper)
const {
429 return IsSuper ? getMessageSendSuperFn() : getMessageSendFn();
432 llvm::FunctionCallee getSendFn2(
bool IsSuper)
const {
433 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();
436 llvm::FunctionCallee getSendStretFn(
bool IsSuper)
const {
437 return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();
440 llvm::FunctionCallee getSendStretFn2(
bool IsSuper)
const {
441 return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();
444 llvm::FunctionCallee getSendFpretFn(
bool IsSuper)
const {
445 return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();
448 llvm::FunctionCallee getSendFpretFn2(
bool IsSuper)
const {
449 return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();
452 llvm::FunctionCallee getSendFp2retFn(
bool IsSuper)
const {
453 return IsSuper ? getMessageSendSuperFn() : getMessageSendFp2retFn();
456 llvm::FunctionCallee getSendFp2RetFn2(
bool IsSuper)
const {
457 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFp2retFn();
460 ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm);
465class ObjCTypesHelper :
public ObjCCommonTypesHelper {
468 llvm::StructType *SymtabTy;
470 llvm::PointerType *SymtabPtrTy;
472 llvm::StructType *ModuleTy;
475 llvm::StructType *ProtocolTy;
477 llvm::PointerType *ProtocolPtrTy;
480 llvm::StructType *ProtocolExtensionTy;
483 llvm::PointerType *ProtocolExtensionPtrTy;
486 llvm::StructType *MethodDescriptionTy;
489 llvm::StructType *MethodDescriptionListTy;
492 llvm::PointerType *MethodDescriptionListPtrTy;
494 llvm::StructType *ProtocolListTy;
496 llvm::PointerType *ProtocolListPtrTy;
498 llvm::StructType *CategoryTy;
500 llvm::StructType *ClassTy;
502 llvm::PointerType *ClassPtrTy;
504 llvm::StructType *ClassExtensionTy;
506 llvm::PointerType *ClassExtensionPtrTy;
508 llvm::StructType *IvarTy;
510 llvm::StructType *IvarListTy;
512 llvm::PointerType *IvarListPtrTy;
514 llvm::StructType *MethodListTy;
516 llvm::PointerType *MethodListPtrTy;
519 llvm::StructType *ExceptionDataTy;
522 llvm::FunctionCallee getExceptionTryEnterFn() {
525 llvm::FunctionType::get(CGM.
VoidTy, params,
false),
526 "objc_exception_try_enter");
530 llvm::FunctionCallee getExceptionTryExitFn() {
533 llvm::FunctionType::get(CGM.
VoidTy, params,
false),
534 "objc_exception_try_exit");
538 llvm::FunctionCallee getExceptionExtractFn() {
541 llvm::FunctionType::get(ObjectPtrTy, params,
false),
542 "objc_exception_extract");
546 llvm::FunctionCallee getExceptionMatchFn() {
547 llvm::Type *params[] = {ClassPtrTy, ObjectPtrTy};
549 llvm::FunctionType::get(CGM.
Int32Ty, params,
false),
550 "objc_exception_match");
554 llvm::FunctionCallee getSetJmpFn() {
558 llvm::FunctionType::get(CGM.
Int32Ty, params,
false),
"_setjmp",
560 llvm::AttributeList::FunctionIndex,
561 llvm::Attribute::NonLazyBind));
565 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
570class ObjCNonFragileABITypesHelper :
public ObjCCommonTypesHelper {
573 llvm::StructType *MethodListnfABITy;
576 llvm::PointerType *MethodListnfABIPtrTy;
579 llvm::StructType *ProtocolnfABITy;
582 llvm::PointerType *ProtocolnfABIPtrTy;
585 llvm::StructType *ProtocolListnfABITy;
588 llvm::PointerType *ProtocolListnfABIPtrTy;
591 llvm::StructType *ClassnfABITy;
594 llvm::PointerType *ClassnfABIPtrTy;
597 llvm::StructType *IvarnfABITy;
600 llvm::StructType *IvarListnfABITy;
603 llvm::PointerType *IvarListnfABIPtrTy;
606 llvm::StructType *ClassRonfABITy;
609 llvm::PointerType *ImpnfABITy;
612 llvm::StructType *CategorynfABITy;
621 llvm::StructType *MessageRefTy;
623 QualType MessageRefCTy;
626 llvm::Type *MessageRefPtrTy;
628 QualType MessageRefCPtrTy;
635 llvm::StructType *SuperMessageRefTy;
638 llvm::PointerType *SuperMessageRefPtrTy;
640 llvm::FunctionCallee getMessageSendFixupFn() {
642 llvm::Type *params[] = {ObjectPtrTy, MessageRefPtrTy};
644 llvm::FunctionType::get(ObjectPtrTy, params,
true),
645 "objc_msgSend_fixup");
648 llvm::FunctionCallee getMessageSendFpretFixupFn() {
650 llvm::Type *params[] = {ObjectPtrTy, MessageRefPtrTy};
652 llvm::FunctionType::get(ObjectPtrTy, params,
true),
653 "objc_msgSend_fpret_fixup");
656 llvm::FunctionCallee getMessageSendStretFixupFn() {
658 llvm::Type *params[] = {ObjectPtrTy, MessageRefPtrTy};
660 llvm::FunctionType::get(ObjectPtrTy, params,
true),
661 "objc_msgSend_stret_fixup");
664 llvm::FunctionCallee getMessageSendSuper2FixupFn() {
667 llvm::Type *params[] = {SuperPtrTy, SuperMessageRefPtrTy};
669 llvm::FunctionType::get(ObjectPtrTy, params,
true),
670 "objc_msgSendSuper2_fixup");
673 llvm::FunctionCallee getMessageSendSuper2StretFixupFn() {
676 llvm::Type *params[] = {SuperPtrTy, SuperMessageRefPtrTy};
678 llvm::FunctionType::get(ObjectPtrTy, params,
true),
679 "objc_msgSendSuper2_stret_fixup");
682 llvm::FunctionCallee getObjCEndCatchFn() {
687 llvm::FunctionCallee getObjCBeginCatchFn() {
688 llvm::Type *params[] = {Int8PtrTy};
690 llvm::FunctionType::get(Int8PtrTy, params,
false),
"objc_begin_catch");
698 llvm::FunctionCallee getLoadClassrefFn()
const {
704 llvm::Type *params[] = {Int8PtrPtrTy};
706 llvm::AttributeSet AS = llvm::AttributeSet::get(
708 llvm::Attribute::get(
C, llvm::Attribute::NonLazyBind),
709 llvm::Attribute::getWithMemoryEffects(
710 C, llvm::MemoryEffects::none()),
711 llvm::Attribute::get(
C, llvm::Attribute::NoUnwind),
714 llvm::FunctionType::get(ClassnfABIPtrTy, params,
false),
717 llvm::AttributeList::FunctionIndex, AS));
718 if (!CGM.
getTriple().isOSBinFormatCOFF())
720 ->setLinkage(llvm::Function::ExternalWeakLinkage);
725 llvm::StructType *EHTypeTy;
726 llvm::Type *EHTypePtrTy;
728 ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm);
731enum class ObjCLabelType {
748 SKIP_SCAN(
unsigned _skip = 0,
unsigned _scan = 0)
749 : skip(_skip), scan(_scan) {}
757 enum BLOCK_LAYOUT_OPCODE {
764 BLOCK_LAYOUT_OPERATOR = 0,
770 BLOCK_LAYOUT_NON_OBJECT_BYTES = 1,
775 BLOCK_LAYOUT_NON_OBJECT_WORDS = 2,
779 BLOCK_LAYOUT_STRONG = 3,
782 BLOCK_LAYOUT_BYREF = 4,
786 BLOCK_LAYOUT_WEAK = 5,
790 BLOCK_LAYOUT_UNRETAINED = 6
808 enum BLOCK_LAYOUT_OPCODE opcode;
809 CharUnits block_var_bytepos;
810 CharUnits block_var_size;
811 RUN_SKIP(
enum BLOCK_LAYOUT_OPCODE Opcode = BLOCK_LAYOUT_OPERATOR,
814 : opcode(
Opcode), block_var_bytepos(BytePos), block_var_size(
Size) {}
817 bool operator<(
const RUN_SKIP &b)
const {
818 return block_var_bytepos < b.block_var_bytepos;
823 llvm::LLVMContext &VMContext;
828 SmallVector<RUN_SKIP, 16> RunSkipBlockVars;
832 llvm::SetVector<IdentifierInfo *> LazySymbols;
838 llvm::SetVector<IdentifierInfo *> DefinedSymbols;
841 llvm::StringMap<llvm::GlobalVariable *> ClassNames;
844 llvm::DenseMap<Selector, llvm::GlobalVariable *> MethodVarNames;
847 llvm::SmallSetVector<llvm::CachedHashString, 16> DefinedCategoryNames;
851 llvm::StringMap<llvm::GlobalVariable *> MethodVarTypes;
855 llvm::DenseMap<const ObjCMethodDecl *, llvm::Function *> MethodDefinitions;
858 struct DirectMethodInfo {
861 llvm::Function *Thunk;
863 DirectMethodInfo(llvm::Function *Impl, llvm::Function *Thunk =
nullptr)
864 : Implementation(Impl), Thunk(Thunk) {}
869 llvm::DenseMap<const ObjCMethodDecl *, DirectMethodInfo>
870 DirectMethodDefinitions;
873 llvm::DenseMap<std::pair<Selector, StringRef>, llvm::Function *>
877 llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> PropertyNames;
880 llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> ClassReferences;
883 llvm::DenseMap<Selector, llvm::GlobalVariable *> SelectorReferences;
888 llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> Protocols;
892 llvm::DenseSet<IdentifierInfo *> DefinedProtocols;
895 SmallVector<llvm::GlobalValue *, 16> DefinedClasses;
898 SmallVector<const ObjCInterfaceDecl *, 16> ImplementedClasses;
901 SmallVector<llvm::GlobalValue *, 16> DefinedNonLazyClasses;
904 SmallVector<llvm::GlobalValue *, 16> DefinedCategories;
907 SmallVector<llvm::GlobalValue *, 16> DefinedStubCategories;
910 SmallVector<llvm::GlobalValue *, 16> DefinedNonLazyCategories;
914 llvm::WeakTrackingVH ConstantStringClassRef;
915 llvm::WeakTrackingVH ConstantArrayClassRef;
916 llvm::WeakTrackingVH ConstantDictionaryClassRef;
918 llvm::WeakTrackingVH ConstantIntegerNumberClassRef;
919 llvm::WeakTrackingVH ConstantFloatNumberClassRef;
920 llvm::WeakTrackingVH ConstantDoubleNumberClassRef;
923 llvm::StructType *NSConstantStringType =
nullptr;
924 llvm::StructType *NSConstantArrayType =
nullptr;
925 llvm::StructType *NSConstantDictionaryType =
nullptr;
927 llvm::StructType *NSConstantIntegerNumberType =
nullptr;
928 llvm::StructType *NSConstantFloatNumberType =
nullptr;
929 llvm::StructType *NSConstantDoubleNumberType =
nullptr;
931 llvm::StringMap<llvm::GlobalVariable *> NSConstantStringMap;
934 llvm::GlobalVariable *DefinedCFBooleanTrue =
nullptr;
935 llvm::GlobalVariable *DefinedCFBooleanFalse =
nullptr;
938 llvm::DenseMap<NSConstantNumberMapInfo, llvm::GlobalVariable *>
942 llvm::GlobalVariable *DefinedEmptyNSDictionary =
nullptr;
943 llvm::GlobalVariable *DefinedEmptyNSArray =
nullptr;
947 llvm::Constant *GetMethodVarName(Selector Sel);
948 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
954 llvm::Constant *GetMethodVarType(
const ObjCMethodDecl *D,
955 bool Extended =
false);
956 llvm::Constant *GetMethodVarType(
const FieldDecl *D);
960 llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
963 llvm::Constant *GetPropertyTypeString(
const ObjCPropertyDecl *PD,
964 const Decl *Container);
969 llvm::Constant *GetClassName(StringRef RuntimeName);
971 llvm::Function *GetMethodDefinition(
const ObjCMethodDecl *MD);
980 llvm::Constant *BuildIvarLayout(
const ObjCImplementationDecl *OI,
981 CharUnits beginOffset, CharUnits endOffset,
984 llvm::Constant *BuildStrongIvarLayout(
const ObjCImplementationDecl *OI,
985 CharUnits beginOffset,
986 CharUnits endOffset) {
987 return BuildIvarLayout(OI, beginOffset, endOffset,
true,
false);
990 llvm::Constant *BuildWeakIvarLayout(
const ObjCImplementationDecl *OI,
991 CharUnits beginOffset,
994 return BuildIvarLayout(OI, beginOffset, endOffset,
false,
hasMRCWeakIvars);
1001 CharUnits FieldOffset, CharUnits FieldSize);
1003 void BuildRCBlockVarRecordLayout(
const RecordType *RT, CharUnits BytePos,
1004 bool &HasUnion,
bool ByrefLayout =
false);
1006 void BuildRCRecordLayout(
const llvm::StructLayout *RecLayout,
1007 const RecordDecl *RD,
1008 ArrayRef<const FieldDecl *> RecFields,
1009 CharUnits BytePos,
bool &HasUnion,
bool ByrefLayout);
1011 uint64_t InlineLayoutInstruction(SmallVectorImpl<unsigned char> &Layout);
1013 llvm::Constant *getBitmapBlockLayout(
bool ComputeByrefLayout);
1017 llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident,
1018 const ObjCCommonTypesHelper &ObjCTypes);
1022 llvm::Constant *EmitPropertyList(Twine Name,
const Decl *Container,
1023 const ObjCContainerDecl *OCD,
1024 const ObjCCommonTypesHelper &ObjCTypes,
1025 bool IsClassProperty);
1030 EmitProtocolMethodTypes(Twine Name, ArrayRef<llvm::Constant *> MethodTypes,
1031 const ObjCCommonTypesHelper &ObjCTypes);
1036 llvm::Constant *GetProtocolRef(
const ObjCProtocolDecl *PD);
1040 llvm::Value *EmitClassRefViaRuntime(CodeGenFunction &CGF,
1041 const ObjCInterfaceDecl *ID,
1042 ObjCCommonTypesHelper &ObjCTypes);
1044 std::string GetSectionName(StringRef Section, StringRef MachOAttributes);
1047 static constexpr llvm::StringLiteral GetNSConstantIntegerNumberSectionName() {
1048 return "__DATA,__objc_intobj,regular,no_dead_strip";
1052 static constexpr llvm::StringLiteral GetNSConstantFloatNumberSectionName() {
1053 return "__DATA,__objc_floatobj,regular,no_dead_strip";
1057 static constexpr llvm::StringLiteral GetNSConstantDoubleNumberSectionName() {
1058 return "__DATA,__objc_doubleobj,regular,no_dead_strip";
1063 static constexpr llvm::StringLiteral
1064 GetNSConstantCollectionStorageSectionName() {
1065 return "__DATA,__objc_arraydata,regular,no_dead_strip";
1069 static constexpr llvm::StringLiteral GetNSConstantArraySectionName() {
1070 return "__DATA,__objc_arrayobj,regular,no_dead_strip";
1074 static constexpr llvm::StringLiteral GetNSConstantDictionarySectionName() {
1075 return "__DATA,__objc_dictobj,regular,no_dead_strip";
1093 llvm::GlobalVariable *CreateMetadataVar(Twine Name,
1094 ConstantStructBuilder &
Init,
1095 StringRef Section, CharUnits Align,
1097 llvm::GlobalVariable *CreateMetadataVar(Twine Name, llvm::Constant *
Init,
1098 StringRef Section, CharUnits Align,
1101 llvm::GlobalVariable *CreateCStringLiteral(StringRef Name,
1102 ObjCLabelType LabelType,
1103 bool ForceNonFragileABI =
false,
1104 bool NullTerminate =
true);
1107 CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
1108 ReturnValueSlot Return, QualType ResultType,
1109 Selector Sel, llvm::Value *Arg0,
1110 QualType Arg0Ty,
bool IsSuper,
1111 const CallArgList &CallArgs,
1112 const ObjCMethodDecl *OMD,
1113 const ObjCInterfaceDecl *ClassReceiver,
1114 const ObjCCommonTypesHelper &ObjCTypes);
1118 void EmitImageInfo();
1121 CGObjCCommonMac(CodeGen::CodeGenModule &cgm)
1122 : CGObjCRuntime(cgm), VMContext(cgm.getLLVMContext()) {}
1124 bool isNonFragileABI()
const {
return ObjCABI == 2; }
1127 llvm::GlobalVariable *EmitConstantCFBooleanTrue() {
1128 if (DefinedCFBooleanTrue)
1129 return DefinedCFBooleanTrue;
1132 "The current ABI doesn't support the constant CFBooleanTrue "
1137 DefinedCFBooleanTrue->addAttribute(
"objc_arc_inert");
1138 return DefinedCFBooleanTrue;
1142 llvm::GlobalVariable *EmitConstantCFBooleanFalse() {
1143 if (DefinedCFBooleanFalse)
1144 return DefinedCFBooleanFalse;
1147 "The current ABI doesn't support the constant CFBooleanFalse "
1152 DefinedCFBooleanFalse->addAttribute(
"objc_arc_inert");
1153 return DefinedCFBooleanFalse;
1157 llvm::GlobalVariable *EmitEmptyConstantNSDictionary() {
1158 if (DefinedEmptyNSDictionary)
1159 return DefinedEmptyNSDictionary;
1162 "The current ABI doesn't support an empty constant NSDictionary "
1167 DefinedEmptyNSDictionary->addAttribute(
"objc_arc_inert");
1168 return DefinedEmptyNSDictionary;
1172 llvm::GlobalVariable *EmitEmptyConstantNSArray() {
1173 if (DefinedEmptyNSArray)
1174 return DefinedEmptyNSArray;
1178 "The current ABI doesn't support an empty constant NSArray singleton!");
1182 DefinedEmptyNSArray->addAttribute(
"objc_arc_inert");
1183 return DefinedEmptyNSArray;
1186 ConstantAddress GenerateConstantString(
const StringLiteral *SL)
override;
1188 ConstantAddress GenerateConstantNumber(
const bool Value,
1189 const QualType &Ty)
override;
1190 ConstantAddress GenerateConstantNumber(
const llvm::APSInt &
Value,
1191 const QualType &Ty)
override;
1192 ConstantAddress GenerateConstantNumber(
const llvm::APFloat &
Value,
1193 const QualType &Ty)
override;
1195 GenerateConstantArray(
const ArrayRef<llvm::Constant *> &Objects)
override;
1196 ConstantAddress GenerateConstantDictionary(
1197 const ObjCDictionaryLiteral *E,
1198 ArrayRef<std::pair<llvm::Constant *, llvm::Constant *>> KeysAndObjects)
1201 ConstantAddress GenerateConstantNSString(
const StringLiteral *SL);
1202 ConstantAddress GenerateConstantNSNumber(
const bool Value,
1203 const QualType &Ty);
1204 ConstantAddress GenerateConstantNSNumber(
const llvm::APSInt &
Value,
1205 const QualType &Ty);
1206 ConstantAddress GenerateConstantNSNumber(
const llvm::APFloat &
Value,
1207 const QualType &Ty);
1209 GenerateConstantNSArray(
const ArrayRef<llvm::Constant *> &Objects);
1210 ConstantAddress GenerateConstantNSDictionary(
1211 const ObjCDictionaryLiteral *E,
1212 ArrayRef<std::pair<llvm::Constant *, llvm::Constant *>> KeysAndObjects);
1215 GenerateMethod(
const ObjCMethodDecl *OMD,
1216 const ObjCContainerDecl *CD =
nullptr)
override;
1218 DirectMethodInfo &GenerateDirectMethod(
const ObjCMethodDecl *OMD,
1219 const ObjCContainerDecl *CD);
1221 llvm::Function *GenerateObjCDirectThunk(
const ObjCMethodDecl *OMD,
1222 const ObjCContainerDecl *CD,
1223 llvm::Function *Implementation);
1225 llvm::Function *GetDirectMethodCallee(
const ObjCMethodDecl *OMD,
1226 const ObjCContainerDecl *CD,
1227 bool ReceiverCanBeNull,
1228 bool ClassObjectCanBeUnrealized);
1233 llvm::Value *GenerateClassRealization(CodeGenFunction &CGF,
1234 llvm::Value *classObject,
1235 const ObjCInterfaceDecl *OID);
1237 void GenerateDirectMethodsPreconditionCheck(
1238 CodeGenFunction &CGF, llvm::Function *Fn,
const ObjCMethodDecl *OMD,
1239 const ObjCContainerDecl *CD)
override;
1241 void GenerateDirectMethodPrologue(CodeGenFunction &CGF, llvm::Function *Fn,
1242 const ObjCMethodDecl *OMD,
1243 const ObjCContainerDecl *CD)
override;
1246 GenerateMethodSelectorStub(Selector Sel, StringRef ClassName,
1247 const ObjCCommonTypesHelper &ObjCTypes);
1249 void GenerateProtocol(
const ObjCProtocolDecl *PD)
override;
1255 virtual llvm::Constant *GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD) = 0;
1257 virtual llvm::Constant *getNSConstantStringClassRef() = 0;
1258 virtual llvm::Constant *getNSConstantArrayClassRef() = 0;
1259 virtual llvm::Constant *getNSConstantDictionaryClassRef() = 0;
1261 virtual llvm::Constant *getNSConstantIntegerNumberClassRef() = 0;
1262 virtual llvm::Constant *getNSConstantFloatNumberClassRef() = 0;
1263 virtual llvm::Constant *getNSConstantDoubleNumberClassRef() = 0;
1265 llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM,
1266 const CGBlockInfo &blockInfo)
override;
1267 llvm::Constant *BuildRCBlockLayout(CodeGen::CodeGenModule &CGM,
1268 const CGBlockInfo &blockInfo)
override;
1269 std::string getRCBlockLayoutStr(CodeGen::CodeGenModule &CGM,
1270 const CGBlockInfo &blockInfo)
override;
1272 llvm::Constant *BuildByrefLayout(CodeGen::CodeGenModule &CGM,
1273 QualType
T)
override;
1276 void fillRunSkipBlockVars(CodeGenModule &CGM,
const CGBlockInfo &blockInfo);
1277 llvm::GlobalVariable *EmitNSConstantCollectionLiteralArrayStorage(
1278 const ArrayRef<llvm::Constant *> &Elements);
1283enum class MethodListType {
1284 CategoryInstanceMethods,
1285 CategoryClassMethods,
1288 ProtocolInstanceMethods,
1289 ProtocolClassMethods,
1290 OptionalProtocolInstanceMethods,
1291 OptionalProtocolClassMethods,
1296class ProtocolMethodLists {
1299 RequiredInstanceMethods,
1300 RequiredClassMethods,
1301 OptionalInstanceMethods,
1302 OptionalClassMethods
1304 enum { NumProtocolMethodLists = 4 };
1306 static MethodListType getMethodListKind(Kind
kind) {
1308 case RequiredInstanceMethods:
1309 return MethodListType::ProtocolInstanceMethods;
1310 case RequiredClassMethods:
1311 return MethodListType::ProtocolClassMethods;
1312 case OptionalInstanceMethods:
1313 return MethodListType::OptionalProtocolInstanceMethods;
1314 case OptionalClassMethods:
1315 return MethodListType::OptionalProtocolClassMethods;
1317 llvm_unreachable(
"bad kind");
1320 SmallVector<const ObjCMethodDecl *, 4> Methods[NumProtocolMethodLists];
1322 static ProtocolMethodLists get(
const ObjCProtocolDecl *PD) {
1323 ProtocolMethodLists result;
1325 for (
auto *MD : PD->
methods()) {
1327 (2 *
size_t(MD->isOptional())) + (
size_t(MD->isClassMethod()));
1328 result.Methods[index].push_back(MD);
1334 template <
class Self>
1335 SmallVector<llvm::Constant *, 8> emitExtendedTypesArray(
Self *self)
const {
1342 SmallVector<llvm::Constant *, 8> result;
1345 for (
auto &list : Methods) {
1346 for (
auto MD : list) {
1347 result.push_back(self->GetMethodVarType(MD,
true));
1354 template <
class Self>
1355 llvm::Constant *emitMethodList(
Self *self,
const ObjCProtocolDecl *PD,
1358 getMethodListKind(
kind), Methods[
kind]);
1364class CGObjCMac :
public CGObjCCommonMac {
1366 friend ProtocolMethodLists;
1368 ObjCTypesHelper ObjCTypes;
1372 void EmitModuleInfo();
1376 llvm::Constant *EmitModuleSymbols();
1380 void FinishModule();
1385 llvm::Constant *EmitClassExtension(
const ObjCImplementationDecl *ID,
1386 CharUnits instanceSize,
1391 llvm::Value *EmitClassRef(CodeGenFunction &CGF,
const ObjCInterfaceDecl *ID);
1393 llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF, IdentifierInfo *II);
1395 llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF)
override;
1398 llvm::Value *EmitSuperClassRef(
const ObjCInterfaceDecl *ID);
1405 llvm::Constant *EmitIvarList(
const ObjCImplementationDecl *ID,
bool ForClass);
1410 llvm::Constant *EmitMetaClassRef(
const ObjCInterfaceDecl *ID);
1414 llvm::Constant *EmitMetaClass(
const ObjCImplementationDecl *ID,
1415 llvm::Constant *Protocols,
1416 ArrayRef<const ObjCMethodDecl *> Methods);
1418 void emitMethodConstant(ConstantArrayBuilder &builder,
1419 const ObjCMethodDecl *MD);
1421 void emitMethodDescriptionConstant(ConstantArrayBuilder &builder,
1422 const ObjCMethodDecl *MD);
1426 llvm::Constant *emitMethodList(Twine Name, MethodListType MLT,
1427 ArrayRef<const ObjCMethodDecl *> Methods);
1432 llvm::Constant *GetOrEmitProtocol(
const ObjCProtocolDecl *PD)
override;
1438 llvm::Constant *GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD)
override;
1444 llvm::Constant *EmitProtocolExtension(
const ObjCProtocolDecl *PD,
1445 const ProtocolMethodLists &methodLists);
1449 llvm::Constant *EmitProtocolList(Twine Name,
1455 llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel);
1456 ConstantAddress EmitSelectorAddr(Selector Sel);
1459 CGObjCMac(CodeGen::CodeGenModule &cgm);
1461 llvm::Constant *getNSConstantStringClassRef()
override;
1462 llvm::Constant *getNSConstantArrayClassRef()
override;
1463 llvm::Constant *getNSConstantDictionaryClassRef()
override;
1465 llvm::Constant *getNSConstantIntegerNumberClassRef()
override;
1466 llvm::Constant *getNSConstantFloatNumberClassRef()
override;
1467 llvm::Constant *getNSConstantDoubleNumberClassRef()
override;
1469 llvm::Function *ModuleInitFunction()
override;
1471 CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1472 ReturnValueSlot Return,
1473 QualType ResultType, Selector Sel,
1474 llvm::Value *Receiver,
1475 const CallArgList &CallArgs,
1476 const ObjCInterfaceDecl *
Class,
1477 const ObjCMethodDecl *
Method)
override;
1479 CodeGen::RValue GenerateMessageSendSuper(
1480 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return,
1481 QualType ResultType, Selector Sel,
const ObjCInterfaceDecl *
Class,
1482 bool isCategoryImpl, llvm::Value *Receiver,
bool IsClassMessage,
1483 const CallArgList &CallArgs,
const ObjCMethodDecl *
Method)
override;
1485 llvm::Value *GetClass(CodeGenFunction &CGF,
1486 const ObjCInterfaceDecl *ID)
override;
1488 llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel)
override;
1489 Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel)
override;
1493 llvm::Value *GetSelector(CodeGenFunction &CGF,
1494 const ObjCMethodDecl *
Method)
override;
1496 llvm::Constant *GetEHType(QualType
T)
override;
1498 void GenerateCategory(
const ObjCCategoryImplDecl *CMD)
override;
1500 void GenerateClass(
const ObjCImplementationDecl *ClassDecl)
override;
1502 void RegisterAlias(
const ObjCCompatibleAliasDecl *OAD)
override {}
1504 llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
1505 const ObjCProtocolDecl *PD)
override;
1507 llvm::FunctionCallee GetPropertyGetFunction()
override;
1508 llvm::FunctionCallee GetPropertySetFunction()
override;
1509 llvm::FunctionCallee GetOptimizedPropertySetFunction(
bool atomic,
1510 bool copy)
override;
1511 llvm::FunctionCallee GetGetStructFunction()
override;
1512 llvm::FunctionCallee GetSetStructFunction()
override;
1513 llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override;
1514 llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override;
1515 llvm::FunctionCallee EnumerationMutationFunction()
override;
1517 void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1518 const ObjCAtTryStmt &S)
override;
1519 void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1520 const ObjCAtSynchronizedStmt &S)
override;
1521 void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
const Stmt &S);
1522 void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
const ObjCAtThrowStmt &S,
1523 bool ClearInsertionPoint =
true)
override;
1524 llvm::Value *EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1525 Address AddrWeakObj)
override;
1526 void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1527 Address dst)
override;
1528 void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1529 Address dest,
bool threadlocal =
false)
override;
1530 void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1531 Address dest, llvm::Value *ivarOffset)
override;
1532 void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1533 Address dest)
override;
1534 void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, Address dest,
1535 Address src, llvm::Value *size)
override;
1537 LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy,
1538 llvm::Value *BaseValue,
const ObjCIvarDecl *Ivar,
1539 unsigned CVRQualifiers)
override;
1540 llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1542 const ObjCIvarDecl *Ivar)
override;
1545class CGObjCNonFragileABIMac :
public CGObjCCommonMac {
1547 friend ProtocolMethodLists;
1548 ObjCNonFragileABITypesHelper ObjCTypes;
1549 llvm::GlobalVariable *ObjCEmptyCacheVar;
1550 llvm::Constant *ObjCEmptyVtableVar;
1553 llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> SuperClassReferences;
1556 llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> MetaClassReferences;
1559 llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> EHTypeReferences;
1563 llvm::DenseSet<Selector> VTableDispatchMethods;
1566 std::vector<llvm::GlobalValue *> DefinedMetaClasses;
1570 bool isVTableDispatchedSelector(Selector Sel);
1574 void FinishNonFragileABIModule();
1578 void AddModuleClassList(ArrayRef<llvm::GlobalValue *> Container,
1579 StringRef SymbolName, StringRef SectionName);
1581 llvm::GlobalVariable *
1582 BuildClassRoTInitializer(
unsigned flags,
unsigned InstanceStart,
1583 unsigned InstanceSize,
1584 const ObjCImplementationDecl *ID);
1585 llvm::GlobalVariable *
1586 BuildClassObject(
const ObjCInterfaceDecl *CI,
bool isMetaclass,
1587 llvm::Constant *IsAGV, llvm::Constant *SuperClassGV,
1590 void emitMethodConstant(ConstantArrayBuilder &builder,
1591 const ObjCMethodDecl *MD,
bool forProtocol);
1595 llvm::Constant *emitMethodList(Twine Name, MethodListType MLT,
1596 ArrayRef<const ObjCMethodDecl *> Methods);
1603 llvm::Constant *EmitIvarList(
const ObjCImplementationDecl *ID);
1605 llvm::Constant *EmitIvarOffsetVar(
const ObjCInterfaceDecl *ID,
1606 const ObjCIvarDecl *Ivar,
1607 unsigned long int offset);
1612 llvm::Constant *GetOrEmitProtocol(
const ObjCProtocolDecl *PD)
override;
1618 llvm::Constant *GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD)
override;
1622 llvm::Constant *EmitProtocolList(Twine Name,
1626 CodeGen::RValue EmitVTableMessageSend(
1627 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return,
1628 QualType ResultType, Selector Sel, llvm::Value *Receiver, QualType Arg0Ty,
1629 bool IsSuper,
const CallArgList &CallArgs,
const ObjCMethodDecl *
Method);
1633 llvm::Constant *GetClassGlobal(StringRef Name,
1635 bool Weak =
false,
bool DLLImport =
false);
1636 llvm::Constant *GetClassGlobal(
const ObjCInterfaceDecl *ID,
bool isMetaclass,
1639 llvm::Constant *GetClassGlobalForClassRef(
const ObjCInterfaceDecl *ID);
1641 llvm::Value *EmitLoadOfClassRef(CodeGenFunction &CGF,
1642 const ObjCInterfaceDecl *ID,
1643 llvm::GlobalVariable *Entry);
1647 llvm::Value *EmitClassRef(CodeGenFunction &CGF,
const ObjCInterfaceDecl *ID);
1649 llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF, IdentifierInfo *II,
1650 const ObjCInterfaceDecl *ID);
1652 llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF)
override;
1656 llvm::Value *EmitSuperClassRef(CodeGenFunction &CGF,
1657 const ObjCInterfaceDecl *ID);
1661 llvm::Value *EmitMetaClassRef(CodeGenFunction &CGF,
1662 const ObjCInterfaceDecl *ID,
bool Weak);
1667 llvm::GlobalVariable *ObjCIvarOffsetVariable(
const ObjCInterfaceDecl *ID,
1668 const ObjCIvarDecl *Ivar);
1672 llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel);
1673 ConstantAddress EmitSelectorAddr(Selector Sel);
1677 llvm::Constant *GetInterfaceEHType(
const ObjCInterfaceDecl *ID,
1680 StringRef getMetaclassSymbolPrefix()
const {
return "OBJC_METACLASS_$_"; }
1682 StringRef getClassSymbolPrefix()
const {
return "OBJC_CLASS_$_"; }
1684 void GetClassSizeInfo(
const ObjCImplementationDecl *OID,
1700 bool ImplementationIsNonLazy(
const ObjCImplDecl *OD)
const;
1702 bool IsIvarOffsetKnownIdempotent(
const CodeGen::CodeGenFunction &CGF,
1703 const ObjCIvarDecl *IV) {
1718 if (
const ObjCMethodDecl *MD =
1719 dyn_cast_or_null<ObjCMethodDecl>(CGF.
CurFuncDecl))
1720 if (MD->isInstanceMethod() && !MD->isDirectMethod())
1721 if (
const ObjCInterfaceDecl *ID = MD->getClassInterface())
1726 bool isClassLayoutKnownStatically(
const ObjCInterfaceDecl *ID) {
1729 assert(ID !=
nullptr &&
"Passed a null class to check layout");
1730 for (;
ID !=
nullptr;
ID =
ID->getSuperClass()) {
1733 if (
ID->getIdentifier()->getName() ==
"NSObject")
1738 if (!
ID->getImplementation())
1747 CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm);
1749 llvm::Constant *getNSConstantStringClassRef()
override;
1750 llvm::Constant *getNSConstantArrayClassRef()
override;
1751 llvm::Constant *getNSConstantDictionaryClassRef()
override;
1753 llvm::Constant *getNSConstantIntegerNumberClassRef()
override;
1754 llvm::Constant *getNSConstantFloatNumberClassRef()
override;
1755 llvm::Constant *getNSConstantDoubleNumberClassRef()
override;
1757 llvm::Function *ModuleInitFunction()
override;
1759 CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1760 ReturnValueSlot Return,
1761 QualType ResultType, Selector Sel,
1762 llvm::Value *Receiver,
1763 const CallArgList &CallArgs,
1764 const ObjCInterfaceDecl *
Class,
1765 const ObjCMethodDecl *
Method)
override;
1767 CodeGen::RValue GenerateMessageSendSuper(
1768 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return,
1769 QualType ResultType, Selector Sel,
const ObjCInterfaceDecl *
Class,
1770 bool isCategoryImpl, llvm::Value *Receiver,
bool IsClassMessage,
1771 const CallArgList &CallArgs,
const ObjCMethodDecl *
Method)
override;
1773 llvm::Value *GetClass(CodeGenFunction &CGF,
1774 const ObjCInterfaceDecl *ID)
override;
1776 llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel)
override {
1777 return EmitSelector(CGF, Sel);
1779 Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel)
override {
1780 return EmitSelectorAddr(Sel);
1785 llvm::Value *GetSelector(CodeGenFunction &CGF,
1786 const ObjCMethodDecl *
Method)
override {
1787 return EmitSelector(CGF,
Method->getSelector());
1790 void GenerateCategory(
const ObjCCategoryImplDecl *CMD)
override;
1792 void GenerateClass(
const ObjCImplementationDecl *ClassDecl)
override;
1794 void RegisterAlias(
const ObjCCompatibleAliasDecl *OAD)
override {}
1796 llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
1797 const ObjCProtocolDecl *PD)
override;
1799 llvm::Constant *GetEHType(QualType
T)
override;
1801 llvm::FunctionCallee GetPropertyGetFunction()
override {
1802 return ObjCTypes.getGetPropertyFn();
1804 llvm::FunctionCallee GetPropertySetFunction()
override {
1805 return ObjCTypes.getSetPropertyFn();
1808 llvm::FunctionCallee GetOptimizedPropertySetFunction(
bool atomic,
1809 bool copy)
override {
1810 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
1813 llvm::FunctionCallee GetSetStructFunction()
override {
1814 return ObjCTypes.getCopyStructFn();
1817 llvm::FunctionCallee GetGetStructFunction()
override {
1818 return ObjCTypes.getCopyStructFn();
1821 llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override {
1822 return ObjCTypes.getCppAtomicObjectFunction();
1825 llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override {
1826 return ObjCTypes.getCppAtomicObjectFunction();
1829 llvm::FunctionCallee EnumerationMutationFunction()
override {
1830 return ObjCTypes.getEnumerationMutationFn();
1833 void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1834 const ObjCAtTryStmt &S)
override;
1835 void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1836 const ObjCAtSynchronizedStmt &S)
override;
1837 void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
const ObjCAtThrowStmt &S,
1838 bool ClearInsertionPoint =
true)
override;
1839 llvm::Value *EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1840 Address AddrWeakObj)
override;
1841 void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1842 Address edst)
override;
1843 void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1844 Address dest,
bool threadlocal =
false)
override;
1845 void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1846 Address dest, llvm::Value *ivarOffset)
override;
1847 void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1848 Address dest)
override;
1849 void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, Address dest,
1850 Address src, llvm::Value *size)
override;
1851 LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy,
1852 llvm::Value *BaseValue,
const ObjCIvarDecl *Ivar,
1853 unsigned CVRQualifiers)
override;
1854 llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1856 const ObjCIvarDecl *Ivar)
override;
1861struct NullReturnState {
1862 llvm::BasicBlock *NullBB =
nullptr;
1863 NullReturnState() =
default;
1866 void init(CodeGenFunction &CGF, llvm::Value *receiver) {
1876 CGF.
Builder.CreateCondBr(isNull, NullBB, callBB);
1884 RValue complete(CodeGenFunction &CGF, ReturnValueSlot returnSlot,
1885 RValue result, QualType resultType,
1886 const CallArgList &CallArgs,
const ObjCMethodDecl *
Method) {
1893 llvm::BasicBlock *contBB =
nullptr;
1896 llvm::BasicBlock *callBB = CGF.
Builder.GetInsertBlock();
1911 assert(CGF.
Builder.GetInsertBlock() == NullBB);
1933 llvm::PHINode *phi = CGF.
Builder.CreatePHI(null->getType(), 2);
1935 phi->addIncoming(null, NullBB);
1944 assert(result.
isAggregate() &&
"null init of non-aggregate result?");
1957 llvm::Type *scalarTy = callResult.first->getType();
1958 llvm::Constant *scalarZero = llvm::Constant::getNullValue(scalarTy);
1961 llvm::PHINode *real = CGF.
Builder.CreatePHI(scalarTy, 2);
1962 real->addIncoming(callResult.first, callBB);
1963 real->addIncoming(scalarZero, NullBB);
1964 llvm::PHINode *imag = CGF.
Builder.CreatePHI(scalarTy, 2);
1965 imag->addIncoming(callResult.second, callBB);
1966 imag->addIncoming(scalarZero, NullBB);
1979 if (OID->
hasAttr<ObjCExceptionAttr>())
1986static llvm::GlobalValue::LinkageTypes
1988 if (CGM.
getTriple().isOSBinFormatMachO() &&
1989 (Section.empty() || Section.starts_with(
"__DATA")))
1990 return llvm::GlobalValue::InternalLinkage;
1991 return llvm::GlobalValue::PrivateLinkage;
1995static llvm::GlobalVariable *
1998 std::string SectionName;
1999 if (CGM.
getTriple().isOSBinFormatMachO())
2000 SectionName =
"__DATA, __objc_const";
2001 auto *GV = Builder.finishAndCreateGlobal(
2004 GV->setSection(SectionName);
2011 : CGObjCCommonMac(cgm), ObjCTypes(cgm) {
2020 return EmitClassRef(CGF, ID);
2024llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF, Selector Sel) {
2025 return EmitSelector(CGF, Sel);
2027Address CGObjCMac::GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) {
2028 return EmitSelectorAddr(Sel);
2030llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF,
2031 const ObjCMethodDecl *
Method) {
2032 return EmitSelector(CGF,
Method->getSelector());
2035llvm::Constant *CGObjCMac::GetEHType(QualType
T) {
2047 llvm_unreachable(
"asking for catch type for ObjC type in fragile runtime");
2070CGObjCCommonMac::GenerateConstantString(
const StringLiteral *SL) {
2073 : GenerateConstantNSString(SL));
2076ConstantAddress CGObjCCommonMac::GenerateConstantNumber(
const bool Value,
2077 const QualType &Ty) {
2078 return GenerateConstantNSNumber(
Value, Ty);
2082CGObjCCommonMac::GenerateConstantNumber(
const llvm::APSInt &
Value,
2083 const QualType &Ty) {
2084 return GenerateConstantNSNumber(
Value, Ty);
2088CGObjCCommonMac::GenerateConstantNumber(
const llvm::APFloat &
Value,
2089 const QualType &Ty) {
2090 return GenerateConstantNSNumber(
Value, Ty);
2093ConstantAddress CGObjCCommonMac::GenerateConstantArray(
2094 const ArrayRef<llvm::Constant *> &Objects) {
2095 return GenerateConstantNSArray(Objects);
2098ConstantAddress CGObjCCommonMac::GenerateConstantDictionary(
2099 const ObjCDictionaryLiteral *E,
2100 ArrayRef<std::pair<llvm::Constant *, llvm::Constant *>> KeysAndObjects) {
2101 return GenerateConstantNSDictionary(E, KeysAndObjects);
2104static llvm::StringMapEntry<llvm::GlobalVariable *> &
2107 StringRef String = Literal->getString();
2108 StringLength = String.size();
2109 return *Map.insert(std::make_pair(String,
nullptr)).first;
2112llvm::Constant *CGObjCMac::getNSConstantStringClassRef() {
2113 if (llvm::Value *
V = ConstantStringClassRef)
2117 std::string str = StringClass.empty() ?
"_NSConstantStringClassReference"
2118 :
"_" + StringClass +
"ClassReference";
2120 llvm::Type *PTy = llvm::ArrayType::get(CGM.
IntTy, 0);
2122 ConstantStringClassRef = GV;
2126llvm::Constant *CGObjCMac::getNSConstantArrayClassRef() {
2127 llvm_unreachable(
"constant array literals not supported for fragile ABI");
2130llvm::Constant *CGObjCMac::getNSConstantDictionaryClassRef() {
2131 llvm_unreachable(
"constant dictionary literals not supported for fragile "
2135llvm::Constant *CGObjCMac::getNSConstantIntegerNumberClassRef() {
2136 llvm_unreachable(
"constant number literals not supported for fragile ABI");
2139llvm::Constant *CGObjCMac::getNSConstantFloatNumberClassRef() {
2140 llvm_unreachable(
"constant number literals not supported for fragile ABI");
2143llvm::Constant *CGObjCMac::getNSConstantDoubleNumberClassRef() {
2144 llvm_unreachable(
"constant number literals not supported for fragile ABI");
2147llvm::Constant *CGObjCNonFragileABIMac::getNSConstantStringClassRef() {
2148 if (llvm::Value *
V = ConstantStringClassRef)
2152 std::string str = StringClass.empty() ?
"OBJC_CLASS_$_NSConstantString"
2153 :
"OBJC_CLASS_$_" + StringClass;
2155 ConstantStringClassRef = GV;
2159llvm::Constant *CGObjCNonFragileABIMac::getNSConstantArrayClassRef() {
2160 if (llvm::Value *
V = ConstantArrayClassRef)
2164 std::string Str = ArrayClass.empty() ?
"OBJC_CLASS_$_NSConstantArray"
2165 :
"OBJC_CLASS_$_" + ArrayClass;
2168 ConstantArrayClassRef = GV;
2172llvm::Constant *CGObjCNonFragileABIMac::getNSConstantDictionaryClassRef() {
2173 if (llvm::Value *
V = ConstantDictionaryClassRef)
2176 const std::string &DictionaryClass =
2178 std::string Str = DictionaryClass.empty()
2179 ?
"OBJC_CLASS_$_NSConstantDictionary"
2180 :
"OBJC_CLASS_$_" + DictionaryClass;
2183 ConstantDictionaryClassRef = GV;
2187llvm::Constant *CGObjCNonFragileABIMac::getNSConstantIntegerNumberClassRef() {
2188 if (llvm::Value *
V = ConstantIntegerNumberClassRef)
2191 const std::string &NumberClass =
2193 std::string Str = NumberClass.empty() ?
"OBJC_CLASS_$_NSConstantIntegerNumber"
2194 :
"OBJC_CLASS_$_" + NumberClass;
2197 ConstantIntegerNumberClassRef = GV;
2201llvm::Constant *CGObjCNonFragileABIMac::getNSConstantFloatNumberClassRef() {
2202 if (llvm::Value *
V = ConstantFloatNumberClassRef)
2205 const std::string &NumberClass =
2207 std::string Str = NumberClass.empty() ?
"OBJC_CLASS_$_NSConstantFloatNumber"
2208 :
"OBJC_CLASS_$_" + NumberClass;
2211 ConstantFloatNumberClassRef = GV;
2215llvm::Constant *CGObjCNonFragileABIMac::getNSConstantDoubleNumberClassRef() {
2216 if (llvm::Value *
V = ConstantDoubleNumberClassRef)
2219 const std::string &NumberClass =
2221 std::string Str = NumberClass.empty() ?
"OBJC_CLASS_$_NSConstantDoubleNumber"
2222 :
"OBJC_CLASS_$_" + NumberClass;
2225 ConstantDoubleNumberClassRef = GV;
2230CGObjCCommonMac::GenerateConstantNSString(
const StringLiteral *Literal) {
2231 unsigned StringLength = 0;
2232 llvm::StringMapEntry<llvm::GlobalVariable *> &Entry =
2235 if (
auto *
C = Entry.second)
2236 return ConstantAddress(
C,
C->getValueType(),
2240 llvm::Constant *
Class = getNSConstantStringClassRef();
2243 if (!NSConstantStringType) {
2247 NSConstantStringType =
2249 "struct.__builtin_NSString");
2252 ConstantInitBuilder Builder(CGM);
2253 auto Fields = Builder.beginStruct(NSConstantStringType);
2256 Fields.addSignedPointer(
Class,
2258 GlobalDecl(), QualType());
2262 llvm::ConstantDataArray::getString(VMContext, Entry.first());
2264 llvm::GlobalValue::LinkageTypes
Linkage = llvm::GlobalValue::PrivateLinkage;
2265 bool isConstant = !CGM.
getLangOpts().WritableStrings;
2267 auto *GV =
new llvm::GlobalVariable(CGM.
getModule(),
C->getType(), isConstant,
2269 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2272 GV->setAlignment(llvm::Align(1));
2276 Fields.addInt(CGM.
IntTy, StringLength);
2280 GV = Fields.finishAndCreateGlobal(
"_unnamed_nsstring_", Alignment,
2282 llvm::GlobalVariable::PrivateLinkage);
2283 const char *NSStringSection =
"__OBJC,__cstring_object,regular,no_dead_strip";
2284 const char *NSStringNonFragileABISection =
2285 "__DATA,__objc_stringobj,regular,no_dead_strip";
2288 ? NSStringNonFragileABISection
2292 return ConstantAddress(GV, GV->getValueType(), Alignment);
2296ConstantAddress CGObjCCommonMac::GenerateConstantNSNumber(
const bool Value,
2297 const QualType &Ty) {
2298 llvm::GlobalVariable *Val =
2299 Value ? EmitConstantCFBooleanTrue() : EmitConstantCFBooleanFalse();
2300 return ConstantAddress(Val, Val->getValueType(), CGM.
getPointerAlign());
2313CGObjCCommonMac::GenerateConstantNSNumber(
const llvm::APSInt &
Value,
2314 const QualType &Ty) {
2318 llvm::GlobalVariable *&Entry =
2321 return ConstantAddress(Entry, Entry->getValueType(), Alignment);
2325 std::string ObjCEncodingType;
2326 CodeGenFunction(CGM).getContext().getObjCEncodingForType(Ty,
2329 llvm::Constant *
const Class = getNSConstantIntegerNumberClassRef();
2331 if (!NSConstantIntegerNumberType) {
2332 NSConstantIntegerNumberType = llvm::StructType::create(
2338 "struct.__builtin_NSConstantIntegerNumber");
2341 ConstantInitBuilder Builder(CGM);
2342 auto Fields = Builder.beginStruct(NSConstantIntegerNumberType);
2345 Fields.addSignedPointer(
Class,
2347 GlobalDecl(), QualType());
2353 llvm::Constant *IntegerValue =
2354 llvm::ConstantInt::get(CGM.
Int64Ty,
Value.extOrTrunc(64));
2356 Fields.add(IntegerValue);
2359 llvm::GlobalVariable *
const GV = Fields.finishAndCreateGlobal(
2360 "_unnamed_nsconstantintegernumber_", Alignment,
2361 true, llvm::GlobalVariable::PrivateLinkage);
2363 GV->setSection(GetNSConstantIntegerNumberSectionName());
2364 GV->addAttribute(
"objc_arc_inert");
2368 return ConstantAddress(GV, GV->getValueType(), Alignment);
2386CGObjCCommonMac::GenerateConstantNSNumber(
const llvm::APFloat &
Value,
2387 const QualType &Ty) {
2391 llvm::GlobalVariable *&Entry =
2394 return ConstantAddress(Entry, Entry->getValueType(), Alignment);
2398 std::string ObjCEncodingType;
2399 CodeGenFunction(CGM).getContext().getObjCEncodingForType(Ty,
2402 assert((ObjCEncodingType ==
"d" || ObjCEncodingType ==
"f") &&
2403 "Unexpected or unknown ObjCEncodingType used in constant NSNumber");
2405 llvm::GlobalValue::LinkageTypes
Linkage =
2406 llvm::GlobalVariable::PrivateLinkage;
2409 if (ObjCEncodingType ==
"f") {
2410 llvm::Constant *
const Class = getNSConstantFloatNumberClassRef();
2412 if (!NSConstantFloatNumberType) {
2413 NSConstantFloatNumberType = llvm::StructType::create(
2418 "struct.__builtin_NSConstantFloatNumber");
2421 ConstantInitBuilder Builder(CGM);
2422 auto Fields = Builder.beginStruct(NSConstantFloatNumberType);
2425 Fields.addSignedPointer(
Class,
2427 GlobalDecl(), QualType());
2430 llvm::Constant *FV = llvm::ConstantFP::get(CGM.
FloatTy,
Value);
2434 llvm::GlobalVariable *
const GV = Fields.finishAndCreateGlobal(
2435 "_unnamed_nsconstantfloatnumber_", Alignment,
2438 GV->setSection(GetNSConstantFloatNumberSectionName());
2439 GV->addAttribute(
"objc_arc_inert");
2443 return ConstantAddress(GV, GV->getValueType(), Alignment);
2446 llvm::Constant *
const Class = getNSConstantDoubleNumberClassRef();
2447 if (!NSConstantDoubleNumberType) {
2449 NSConstantDoubleNumberType = llvm::StructType::create(
2454 "struct.__builtin_NSConstantDoubleNumber");
2457 ConstantInitBuilder Builder(CGM);
2458 auto Fields = Builder.beginStruct(NSConstantDoubleNumberType);
2461 Fields.addSignedPointer(
Class,
2463 GlobalDecl(), QualType());
2466 llvm::Constant *DV = llvm::ConstantFP::get(CGM.
DoubleTy,
Value);
2470 llvm::GlobalVariable *
const GV = Fields.finishAndCreateGlobal(
2471 "_unnamed_nsconstantdoublenumber_", Alignment,
2474 GV->setSection(GetNSConstantDoubleNumberSectionName());
2475 GV->addAttribute(
"objc_arc_inert");
2479 return ConstantAddress(GV, GV->getValueType(), Alignment);
2484llvm::GlobalVariable *
2485CGObjCCommonMac::EmitNSConstantCollectionLiteralArrayStorage(
2486 const ArrayRef<llvm::Constant *> &Elements) {
2487 llvm::Type *ElementsTy = Elements[0]->getType();
2488 llvm::ArrayType *ArrayTy = llvm::ArrayType::get(ElementsTy, Elements.size());
2490 llvm::Constant *
const ArrayData = llvm::ConstantArray::get(ArrayTy, Elements);
2492 llvm::GlobalVariable *ObjectsGV =
new llvm::GlobalVariable(
2493 CGM.
getModule(), ArrayTy,
true, llvm::GlobalValue::InternalLinkage,
2494 ArrayData,
"_unnamed_array_storage");
2497 ObjectsGV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2498 ObjectsGV->setSection(GetNSConstantCollectionStorageSectionName());
2511ConstantAddress CGObjCCommonMac::GenerateConstantNSArray(
2512 const ArrayRef<llvm::Constant *> &Objects) {
2515 if (Objects.size() == 0) {
2516 llvm::GlobalVariable *GV = EmitEmptyConstantNSArray();
2517 return ConstantAddress(GV, GV->getValueType(), Alignment);
2521 CodeGenTypes &Types = CGM.
getTypes();
2522 llvm::Constant *
const Class = getNSConstantArrayClassRef();
2523 llvm::Type *
const NSUIntegerTy =
2526 if (!NSConstantArrayType) {
2527 NSConstantArrayType = llvm::StructType::create(
2533 "struct.__builtin_NSArray");
2536 ConstantInitBuilder Builder(CGM);
2537 auto Fields = Builder.beginStruct(NSConstantArrayType);
2540 Fields.addSignedPointer(
Class,
2542 GlobalDecl(), QualType());
2545 uint64_t ObjectCount = Objects.size();
2546 llvm::Constant *Count = llvm::ConstantInt::get(NSUIntegerTy, ObjectCount);
2550 llvm::GlobalVariable *ObjectsGV =
2551 EmitNSConstantCollectionLiteralArrayStorage(Objects);
2552 Fields.add(ObjectsGV);
2555 llvm::GlobalVariable *GV = Fields.finishAndCreateGlobal(
2556 "_unnamed_nsarray_", Alignment,
2557 true, llvm::GlobalValue::PrivateLinkage);
2559 GV->setSection(GetNSConstantArraySectionName());
2560 GV->addAttribute(
"objc_arc_inert");
2562 return ConstantAddress(GV, GV->getValueType(), Alignment);
2577ConstantAddress CGObjCCommonMac::GenerateConstantNSDictionary(
2578 const ObjCDictionaryLiteral *E,
2579 ArrayRef<std::pair<llvm::Constant *, llvm::Constant *>> KeysAndObjects) {
2582 if (KeysAndObjects.size() == 0) {
2583 llvm::GlobalVariable *GV = EmitEmptyConstantNSDictionary();
2584 return ConstantAddress(GV, GV->getValueType(), Alignment);
2588 CodeGenTypes &Types = CGM.
getTypes();
2589 llvm::Constant *
const Class = getNSConstantDictionaryClassRef();
2591 llvm::Type *
const NSUIntegerTy =
2594 if (!NSConstantDictionaryType) {
2595 NSConstantDictionaryType = llvm::StructType::create(
2603 "struct.__builtin_NSDictionary");
2606 ConstantInitBuilder Builder(CGM);
2607 auto Fields = Builder.beginStruct(NSConstantDictionaryType);
2610 Fields.addSignedPointer(
Class,
2612 GlobalDecl(), QualType());
2619 auto HashOpts(NSDictionaryBuilder::Options::Sorted);
2620 NSDictionaryBuilder DictBuilder(E, KeysAndObjects, HashOpts,
2624 uint64_t const NumElements = DictBuilder.getNumElements();
2626 llvm::Constant *OptionsConstant = llvm::ConstantInt::get(
2627 NSUIntegerTy,
static_cast<uint64_t>(DictBuilder.getOptions()));
2628 Fields.add(OptionsConstant);
2631 llvm::Constant *Count = llvm::ConstantInt::get(NSUIntegerTy, NumElements);
2635 SmallVector<llvm::Constant *, 16> SortedKeys, SortedObjects;
2636 SortedKeys.reserve(NumElements);
2637 SortedObjects.reserve(NumElements);
2638 for (
auto &[Key, Obj] : DictBuilder.getElements()) {
2639 SortedKeys.push_back(Key);
2640 SortedObjects.push_back(Obj);
2644 llvm::GlobalVariable *KeysGV =
2645 EmitNSConstantCollectionLiteralArrayStorage(SortedKeys);
2649 llvm::GlobalVariable *ObjectsGV =
2650 EmitNSConstantCollectionLiteralArrayStorage(SortedObjects);
2651 Fields.add(ObjectsGV);
2654 llvm::GlobalVariable *GV = Fields.finishAndCreateGlobal(
2655 "_unnamed_nsdictionary_", Alignment,
2656 true, llvm::GlobalValue::PrivateLinkage);
2658 GV->setSection(GetNSConstantDictionarySectionName());
2659 GV->addAttribute(
"objc_arc_inert");
2661 return ConstantAddress(GV, GV->getValueType(), Alignment);
2669CodeGen::RValue CGObjCMac::GenerateMessageSendSuper(
2670 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
2671 Selector Sel,
const ObjCInterfaceDecl *
Class,
bool isCategoryImpl,
2672 llvm::Value *Receiver,
bool IsClassMessage,
2673 const CodeGen::CallArgList &CallArgs,
const ObjCMethodDecl *
Method) {
2678 llvm::Value *ReceiverAsObject =
2679 CGF.
Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
2684 llvm::Type *ClassTyPtr = llvm::PointerType::getUnqual(VMContext);
2686 if (IsClassMessage) {
2687 if (isCategoryImpl) {
2694 Target = EmitClassRef(CGF,
Class->getSuperClass());
2699 llvm::Constant *MetaClassPtr = EmitMetaClassRef(
Class);
2700 llvm::Value *SuperPtr =
2706 }
else if (isCategoryImpl)
2707 Target = EmitClassRef(CGF,
Class->getSuperClass());
2709 llvm::Value *ClassPtr = EmitSuperClassRef(
Class);
2716 llvm::Type *ClassTy =
2720 return EmitMessageSend(CGF, Return, ResultType, Sel, ObjCSuper.
getPointer(),
2721 ObjCTypes.SuperPtrCTy,
true, CallArgs,
Method,
Class,
2726CodeGen::RValue CGObjCMac::GenerateMessageSend(
2727 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
2728 Selector Sel, llvm::Value *Receiver,
const CallArgList &CallArgs,
2729 const ObjCInterfaceDecl *
Class,
const ObjCMethodDecl *
Method) {
2730 return EmitMessageSend(CGF, Return, ResultType, Sel, Receiver,
2735CodeGen::RValue CGObjCCommonMac::EmitMessageSend(
2736 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
2737 Selector Sel, llvm::Value *Arg0, QualType Arg0Ty,
bool IsSuper,
2738 const CallArgList &CallArgs,
const ObjCMethodDecl *
Method,
2739 const ObjCInterfaceDecl *ClassReceiver,
2740 const ObjCCommonTypesHelper &ObjCTypes) {
2741 CodeGenTypes &Types = CGM.
getTypes();
2743 llvm::Value *ReceiverValue =
2744 llvm::PoisonValue::get(Types.
ConvertType(Arg0Ty));
2745 llvm::Value *SelValue = llvm::UndefValue::get(Types.
ConvertType(selTy));
2747 CallArgList ActualArgs;
2749 Arg0 = CGF.
Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy);
2756 MessageSendInfo MSI = getMessageSendInfo(
Method, ResultType, ActualArgs);
2761 "Result type mismatch!");
2763 bool ReceiverCanBeNull =
2764 canMessageReceiverBeNull(CGF,
Method, IsSuper, ClassReceiver, Arg0);
2765 bool ClassObjectCanBeUnrealized =
2767 canClassObjectBeUnrealized(ClassReceiver, CGF);
2769 bool RequiresNullCheck =
false;
2770 bool RequiresReceiverValue =
true;
2771 bool RequiresSelValue =
true;
2773 llvm::FunctionCallee
Fn =
nullptr;
2777 ReceiverCanBeNull, ClassObjectCanBeUnrealized);
2780 RequiresSelValue =
false;
2782 if (ReceiverCanBeNull)
2783 RequiresNullCheck =
true;
2784 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
2785 : ObjCTypes.getSendStretFn(IsSuper);
2787 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
2788 : ObjCTypes.getSendFpretFn(IsSuper);
2790 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)
2791 : ObjCTypes.getSendFp2retFn(IsSuper);
2796 RequiresNullCheck =
true;
2798 StringRef ClassName;
2804 if (CGM.
getCodeGenOpts().ObjCMsgSendClassSelectorStubs && ClassReceiver &&
2806 !ClassReceiver->
hasAttr<ObjCClassStubAttr>() &&
2807 !ClassReceiver->
hasAttr<ObjCRuntimeVisibleAttr>() &&
2811 bool UseClassStub = ClassName.data();
2814 (CGM.
getCodeGenOpts().ObjCMsgSendSelectorStubs || UseClassStub)) {
2815 Fn = GenerateMethodSelectorStub(Sel, ClassName, ObjCTypes);
2817 RequiresReceiverValue = !UseClassStub;
2818 RequiresSelValue =
false;
2820 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
2821 : ObjCTypes.getSendFn(IsSuper);
2827 CGF.
Builder.CreateBitCast(
Fn.getCallee(), MSI.MessengerType));
2832 RequiresNullCheck =
false;
2835 if (!RequiresNullCheck &&
Method &&
Method->hasParamDestroyedInCallee())
2836 RequiresNullCheck =
true;
2843 if (ClassReceiver && ClassObjectCanBeUnrealized) {
2845 Arg0 = GenerateClassRealization(CGF, Arg0, ClassReceiver);
2846 ActualArgs[0] = CallArg(
RValue::get(Arg0), ActualArgs[0].Ty);
2852 RequiresNullCheck |= ReceiverCanBeNull;
2855 NullReturnState nullReturn;
2856 if (RequiresNullCheck) {
2857 nullReturn.init(CGF, Arg0);
2861 if (RequiresReceiverValue)
2862 ActualArgs[0] = CallArg(
RValue::get(Arg0), Arg0Ty);
2865 if (RequiresSelValue) {
2866 SelValue = GetSelector(CGF, Sel);
2867 ActualArgs[1] = CallArg(
RValue::get(SelValue), selTy);
2870 llvm::CallBase *CallSite;
2873 CGF.
EmitCall(MSI.CallInfo, Callee, Return, ActualArgs, &CallSite);
2877 if (
Method &&
Method->hasAttr<NoReturnAttr>() && !ReceiverCanBeNull) {
2878 CallSite->setDoesNotReturn();
2881 return nullReturn.complete(CGF, Return, rvalue, ResultType, CallArgs,
2882 RequiresNullCheck ?
Method :
nullptr);
2886 bool pointee =
false) {
2900 switch (ownership) {
2908 llvm_unreachable(
"autoreleasing ivar?");
2910 llvm_unreachable(
"known nonzero");
2912 llvm_unreachable(
"bad objc ownership");
2932 IvarInfo(CharUnits offset, uint64_t sizeInWords)
2933 : Offset(offset), SizeInWords(sizeInWords) {}
2936 bool operator<(
const IvarInfo &other)
const {
return Offset < other.Offset; }
2940class IvarLayoutBuilder {
2945 CharUnits InstanceBegin;
2948 CharUnits InstanceEnd;
2951 bool ForStrongLayout;
2954 bool IsDisordered =
false;
2956 llvm::SmallVector<IvarInfo, 8> IvarsInfo;
2959 IvarLayoutBuilder(CodeGenModule &CGM, CharUnits instanceBegin,
2960 CharUnits instanceEnd,
bool forStrongLayout)
2961 : CGM(CGM), InstanceBegin(instanceBegin), InstanceEnd(instanceEnd),
2962 ForStrongLayout(forStrongLayout) {}
2964 void visitRecord(
const RecordType *RT, CharUnits offset);
2966 template <
class Iterator,
class GetOffsetFn>
2967 void visitAggregate(Iterator begin, Iterator end, CharUnits aggrOffset,
2968 const GetOffsetFn &getOffset);
2970 void visitField(
const FieldDecl *field, CharUnits offset);
2973 void visitBlock(
const CGBlockInfo &blockInfo);
2976 bool hasBitmapData()
const {
return !IvarsInfo.empty(); }
2978 llvm::Constant *buildBitmap(CGObjCCommonMac &CGObjC,
2979 llvm::SmallVectorImpl<unsigned char> &buffer);
2981 static void dump(ArrayRef<unsigned char> buffer) {
2982 const unsigned char *s = buffer.data();
2983 for (
unsigned i = 0, e = buffer.size(); i < e; i++)
2985 printf(
"0x0%x%s", s[i], s[i] != 0 ?
", " :
"");
2987 printf(
"0x%x%s", s[i], s[i] != 0 ?
", " :
"");
2994CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,
2995 const CGBlockInfo &blockInfo) {
2997 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2998 if (CGM.
getLangOpts().getGC() == LangOptions::NonGC)
3004 builder.visitBlock(blockInfo);
3006 if (!builder.hasBitmapData())
3009 llvm::SmallVector<unsigned char, 32> buffer;
3010 llvm::Constant *
C = builder.buildBitmap(*
this, buffer);
3011 if (CGM.
getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
3012 printf(
"\n block variable layout for block: ");
3013 builder.dump(buffer);
3019void IvarLayoutBuilder::visitBlock(
const CGBlockInfo &blockInfo) {
3029 CharUnits lastFieldOffset;
3032 for (
const auto &CI :
blockDecl->captures()) {
3033 const VarDecl *variable = CI.getVariable();
3036 const CGBlockInfo::Capture &capture = blockInfo.
getCapture(variable);
3042 CharUnits fieldOffset = capture.
getOffset();
3046 if (fieldOffset < lastFieldOffset)
3047 IsDisordered =
true;
3048 lastFieldOffset = fieldOffset;
3052 IvarsInfo.push_back(IvarInfo(fieldOffset, 1));
3056 assert(!
type->isArrayType() &&
"array variable should not be caught");
3057 if (
const RecordType *record =
type->getAsCanonical<RecordType>()) {
3058 visitRecord(record, fieldOffset);
3067 IvarsInfo.push_back(IvarInfo(fieldOffset, 1));
3076CGObjCCommonMac::getBlockCaptureLifetime(QualType FQT,
bool ByrefLayout) {
3092void CGObjCCommonMac::UpdateRunSkipBlockVars(
bool IsByref,
3094 CharUnits FieldOffset,
3095 CharUnits FieldSize) {
3098 RunSkipBlockVars.push_back(
3099 RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset, FieldSize));
3101 RunSkipBlockVars.push_back(
3102 RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset, FieldSize));
3104 RunSkipBlockVars.push_back(
3105 RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset, FieldSize));
3107 RunSkipBlockVars.push_back(
3108 RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset, FieldSize));
3110 RunSkipBlockVars.push_back(
3111 RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES, FieldOffset, FieldSize));
3114void CGObjCCommonMac::BuildRCRecordLayout(
const llvm::StructLayout *RecLayout,
3115 const RecordDecl *RD,
3116 ArrayRef<const FieldDecl *> RecFields,
3117 CharUnits BytePos,
bool &HasUnion,
3119 bool IsUnion = (RD && RD->
isUnion());
3121 const FieldDecl *MaxField =
nullptr;
3122 const FieldDecl *LastFieldBitfieldOrUnnamed =
nullptr;
3126 if (RecFields.empty())
3130 for (
unsigned i = 0, e = RecFields.size(); i != e; ++i) {
3131 const FieldDecl *
Field = RecFields[i];
3135 CharUnits FieldOffset =
3139 if (!
Field->getIdentifier() ||
Field->isBitField()) {
3140 LastFieldBitfieldOrUnnamed =
Field;
3141 LastBitfieldOrUnnamedOffset = FieldOffset;
3145 LastFieldBitfieldOrUnnamed =
nullptr;
3146 QualType FQT =
Field->getType();
3152 BytePos + FieldOffset, HasUnion);
3158 uint64_t ElCount = CArray->getZExtSize();
3159 assert(CArray &&
"only array with known element size is supported");
3160 FQT = CArray->getElementType();
3163 ElCount *= CArray->getZExtSize();
3164 FQT = CArray->getElementType();
3167 int OldIndex = RunSkipBlockVars.size() - 1;
3169 BuildRCBlockVarRecordLayout(RT, BytePos + FieldOffset, HasUnion);
3174 for (
int FirstIndex = RunSkipBlockVars.size() - 1; ElIx < ElCount;
3177 for (
int i = OldIndex + 1; i <= FirstIndex; ++i)
3178 RunSkipBlockVars.push_back(
3179 RUN_SKIP(RunSkipBlockVars[i].opcode,
3180 RunSkipBlockVars[i].block_var_bytepos + Size * ElIx,
3181 RunSkipBlockVars[i].block_var_size));
3188 CharUnits UnionIvarSize = FieldSize;
3189 if (UnionIvarSize > MaxUnionSize) {
3190 MaxUnionSize = UnionIvarSize;
3192 MaxFieldOffset = FieldOffset;
3195 UpdateRunSkipBlockVars(
false, getBlockCaptureLifetime(FQT, ByrefLayout),
3196 BytePos + FieldOffset, FieldSize);
3200 if (LastFieldBitfieldOrUnnamed) {
3201 if (LastFieldBitfieldOrUnnamed->
isBitField()) {
3204 unsigned UnsSize = (BitFieldSize / ByteSizeInBits) +
3205 ((BitFieldSize % ByteSizeInBits) != 0);
3207 Size += LastBitfieldOrUnnamedOffset;
3208 UpdateRunSkipBlockVars(
3210 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
3212 BytePos + LastBitfieldOrUnnamedOffset, Size);
3215 "Expected unnamed");
3218 LastFieldBitfieldOrUnnamed->
getType());
3219 UpdateRunSkipBlockVars(
3221 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
3223 BytePos + LastBitfieldOrUnnamedOffset, FieldSize);
3228 UpdateRunSkipBlockVars(
3229 false, getBlockCaptureLifetime(MaxField->
getType(), ByrefLayout),
3230 BytePos + MaxFieldOffset, MaxUnionSize);
3233void CGObjCCommonMac::BuildRCBlockVarRecordLayout(
const RecordType *RT,
3238 SmallVector<const FieldDecl *, 16> Fields(RD->
fields());
3240 const llvm::StructLayout *RecLayout =
3243 BuildRCRecordLayout(RecLayout, RD, Fields, BytePos, HasUnion, ByrefLayout);
3255uint64_t CGObjCCommonMac::InlineLayoutInstruction(
3256 SmallVectorImpl<unsigned char> &Layout) {
3258 if (Layout.size() <= 3) {
3259 unsigned size = Layout.size();
3260 unsigned strong_word_count = 0, byref_word_count = 0, weak_word_count = 0;
3262 enum BLOCK_LAYOUT_OPCODE opcode;
3266 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3267 if (opcode == BLOCK_LAYOUT_STRONG)
3268 strong_word_count = (inst & 0xF) + 1;
3272 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3273 if (opcode == BLOCK_LAYOUT_BYREF)
3274 byref_word_count = (inst & 0xF) + 1;
3278 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3279 if (opcode == BLOCK_LAYOUT_WEAK)
3280 weak_word_count = (inst & 0xF) + 1;
3287 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3288 if (opcode == BLOCK_LAYOUT_STRONG) {
3289 strong_word_count = (inst & 0xF) + 1;
3291 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3292 if (opcode == BLOCK_LAYOUT_BYREF)
3293 byref_word_count = (inst & 0xF) + 1;
3294 else if (opcode == BLOCK_LAYOUT_WEAK)
3295 weak_word_count = (inst & 0xF) + 1;
3298 }
else if (opcode == BLOCK_LAYOUT_BYREF) {
3299 byref_word_count = (inst & 0xF) + 1;
3301 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3302 if (opcode == BLOCK_LAYOUT_WEAK)
3303 weak_word_count = (inst & 0xF) + 1;
3312 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3313 if (opcode == BLOCK_LAYOUT_STRONG)
3314 strong_word_count = (inst & 0xF) + 1;
3315 else if (opcode == BLOCK_LAYOUT_BYREF)
3316 byref_word_count = (inst & 0xF) + 1;
3317 else if (opcode == BLOCK_LAYOUT_WEAK)
3318 weak_word_count = (inst & 0xF) + 1;
3330 if (strong_word_count == 16 || byref_word_count == 16 ||
3331 weak_word_count == 16)
3334 unsigned count = (strong_word_count != 0) + (byref_word_count != 0) +
3335 (weak_word_count != 0);
3337 if (size == count) {
3338 if (strong_word_count)
3339 Result = strong_word_count;
3341 if (byref_word_count)
3342 Result += byref_word_count;
3344 if (weak_word_count)
3345 Result += weak_word_count;
3351llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(
bool ComputeByrefLayout) {
3352 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
3353 if (RunSkipBlockVars.empty())
3357 unsigned WordSizeInBytes = WordSizeInBits / ByteSizeInBits;
3361 llvm::array_pod_sort(RunSkipBlockVars.begin(), RunSkipBlockVars.end());
3362 SmallVector<unsigned char, 16> Layout;
3364 unsigned size = RunSkipBlockVars.size();
3365 for (
unsigned i = 0; i < size; i++) {
3366 enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode;
3367 CharUnits start_byte_pos = RunSkipBlockVars[i].block_var_bytepos;
3368 CharUnits end_byte_pos = start_byte_pos;
3371 if (opcode == RunSkipBlockVars[j].opcode) {
3372 end_byte_pos = RunSkipBlockVars[j++].block_var_bytepos;
3377 CharUnits size_in_bytes =
3378 end_byte_pos - start_byte_pos + RunSkipBlockVars[j - 1].block_var_size;
3380 CharUnits gap = RunSkipBlockVars[j].block_var_bytepos -
3381 RunSkipBlockVars[j - 1].block_var_bytepos -
3382 RunSkipBlockVars[j - 1].block_var_size;
3383 size_in_bytes += gap;
3386 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) {
3387 residue_in_bytes = size_in_bytes % WordSizeInBytes;
3388 size_in_bytes -= residue_in_bytes;
3389 opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS;
3392 unsigned size_in_words = size_in_bytes.
getQuantity() / WordSizeInBytes;
3393 while (size_in_words >= 16) {
3396 unsigned char inst = (opcode << 4) | 0xf;
3397 Layout.push_back(inst);
3398 size_in_words -= 16;
3400 if (size_in_words > 0) {
3403 unsigned char inst = (opcode << 4) | (size_in_words - 1);
3404 Layout.push_back(inst);
3407 unsigned char inst = (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) |
3409 Layout.push_back(inst);
3413 while (!Layout.empty()) {
3414 unsigned char inst = Layout.back();
3415 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3416 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES ||
3417 opcode == BLOCK_LAYOUT_NON_OBJECT_WORDS)
3427 if (ComputeByrefLayout)
3428 printf(
"\n Inline BYREF variable layout: ");
3430 printf(
"\n Inline block variable layout: ");
3432 if (
auto numStrong = (
Result & 0xF00) >> 8)
3433 printf(
", BL_STRONG:%d", (
int)numStrong);
3434 if (
auto numByref = (
Result & 0x0F0) >> 4)
3435 printf(
", BL_BYREF:%d", (
int)numByref);
3436 if (
auto numWeak = (
Result & 0x00F) >> 0)
3437 printf(
", BL_WEAK:%d", (
int)numWeak);
3438 printf(
", BL_OPERATOR:0\n");
3443 unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0;
3444 Layout.push_back(inst);
3446 for (
unsigned char C : Layout)
3450 if (ComputeByrefLayout)
3451 printf(
"\n Byref variable layout: ");
3453 printf(
"\n Block variable layout: ");
3454 for (
unsigned i = 0, e = BitMap.size(); i != e; i++) {
3455 unsigned char inst = BitMap[i];
3456 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3459 case BLOCK_LAYOUT_OPERATOR:
3463 case BLOCK_LAYOUT_NON_OBJECT_BYTES:
3464 printf(
"BL_NON_OBJECT_BYTES:");
3466 case BLOCK_LAYOUT_NON_OBJECT_WORDS:
3467 printf(
"BL_NON_OBJECT_WORD:");
3469 case BLOCK_LAYOUT_STRONG:
3472 case BLOCK_LAYOUT_BYREF:
3475 case BLOCK_LAYOUT_WEAK:
3478 case BLOCK_LAYOUT_UNRETAINED:
3479 printf(
"BL_UNRETAINED:");
3484 printf(
"%d", (inst & 0xf) + delta);
3492 return CreateCStringLiteral(BitMap, ObjCLabelType::LayoutBitMap,
3499 bool HasCopyDisposeHelpers) {
3501 for (
const CGObjCCommonMac::RUN_SKIP &R : RunSkipBlockVars) {
3502 if (R.opcode == CGObjCCommonMac::BLOCK_LAYOUT_UNRETAINED) {
3506 }
else if (HasCopyDisposeHelpers) {
3514 case CGObjCCommonMac::BLOCK_LAYOUT_STRONG:
3517 case CGObjCCommonMac::BLOCK_LAYOUT_BYREF:
3520 case CGObjCCommonMac::BLOCK_LAYOUT_WEAK:
3527 Str += llvm::to_string(R.block_var_bytepos.getQuantity());
3528 Str +=
"l" + llvm::to_string(R.block_var_size.getQuantity());
3533void CGObjCCommonMac::fillRunSkipBlockVars(CodeGenModule &CGM,
3534 const CGBlockInfo &blockInfo) {
3535 assert(CGM.
getLangOpts().getGC() == LangOptions::NonGC);
3537 RunSkipBlockVars.clear();
3538 bool hasUnion =
false;
3542 unsigned WordSizeInBytes = WordSizeInBits / ByteSizeInBits;
3547 const llvm::StructLayout *layout =
3557 for (
const auto &CI :
blockDecl->captures()) {
3558 const VarDecl *variable = CI.getVariable();
3561 const CGBlockInfo::Capture &capture = blockInfo.
getCapture(variable);
3567 CharUnits fieldOffset =
3570 assert(!
type->isArrayType() &&
"array variable should not be caught");
3572 if (
const auto *record =
type->getAsCanonical<RecordType>()) {
3573 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion);
3576 CharUnits fieldSize;
3581 UpdateRunSkipBlockVars(CI.isByRef(), getBlockCaptureLifetime(
type,
false),
3582 fieldOffset, fieldSize);
3587CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM,
3588 const CGBlockInfo &blockInfo) {
3589 fillRunSkipBlockVars(CGM, blockInfo);
3590 return getBitmapBlockLayout(
false);
3593std::string CGObjCCommonMac::getRCBlockLayoutStr(CodeGenModule &CGM,
3594 const CGBlockInfo &blockInfo) {
3595 fillRunSkipBlockVars(CGM, blockInfo);
3599llvm::Constant *CGObjCCommonMac::BuildByrefLayout(CodeGen::CodeGenModule &CGM,
3601 assert(CGM.
getLangOpts().getGC() == LangOptions::NonGC);
3602 assert(!
T->
isArrayType() &&
"__block array variable should not be caught");
3603 CharUnits fieldOffset;
3604 RunSkipBlockVars.clear();
3605 bool hasUnion =
false;
3607 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion,
3609 llvm::Constant *
Result = getBitmapBlockLayout(
true);
3614 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
3618llvm::Value *CGObjCMac::GenerateProtocolRef(CodeGenFunction &CGF,
3619 const ObjCProtocolDecl *PD) {
3624 return GetProtocolRef(PD);
3627void CGObjCCommonMac::GenerateProtocol(
const ObjCProtocolDecl *PD) {
3636 GetOrEmitProtocol(PD);
3639llvm::Constant *CGObjCCommonMac::GetProtocolRef(
const ObjCProtocolDecl *PD) {
3641 return GetOrEmitProtocol(PD);
3643 return GetOrEmitProtocolRef(PD);
3647CGObjCCommonMac::EmitClassRefViaRuntime(CodeGenFunction &CGF,
3648 const ObjCInterfaceDecl *ID,
3649 ObjCCommonTypesHelper &ObjCTypes) {
3650 llvm::FunctionCallee lookUpClassFn = ObjCTypes.getLookUpClassFn();
3652 llvm::Value *className = CGF.
CGM
3654 ID->getObjCRuntimeNameAsString()))
3657 className = CGF.
Builder.CreateBitCast(
3659 llvm::CallInst *call = CGF.
Builder.CreateCall(lookUpClassFn, className);
3660 call->setDoesNotThrow();
3676llvm::Constant *CGObjCMac::GetOrEmitProtocol(
const ObjCProtocolDecl *PD) {
3677 llvm::GlobalVariable *Entry = Protocols[PD->
getIdentifier()];
3680 if (Entry && Entry->hasInitializer())
3692 auto methodLists = ProtocolMethodLists::get(PD);
3694 ConstantInitBuilder builder(CGM);
3695 auto values = builder.beginStruct(ObjCTypes.ProtocolTy);
3696 values.add(EmitProtocolExtension(PD, methodLists));
3698 values.add(EmitProtocolList(
"OBJC_PROTOCOL_REFS_" + PD->
getName(),
3700 values.add(methodLists.emitMethodList(
3701 this, PD, ProtocolMethodLists::RequiredInstanceMethods));
3702 values.add(methodLists.emitMethodList(
3703 this, PD, ProtocolMethodLists::RequiredClassMethods));
3707 assert(Entry->hasPrivateLinkage());
3708 values.finishAndSetAsInitializer(Entry);
3710 Entry = values.finishAndCreateGlobal(
3712 false, llvm::GlobalValue::PrivateLinkage);
3713 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
3722llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD) {
3723 llvm::GlobalVariable *&Entry = Protocols[PD->
getIdentifier()];
3729 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolTy,
3730 false, llvm::GlobalValue::PrivateLinkage,
3731 nullptr,
"OBJC_PROTOCOL_" + PD->
getName());
3732 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
3734 Entry->setAlignment(llvm::Align(4));
3751CGObjCMac::EmitProtocolExtension(
const ObjCProtocolDecl *PD,
3752 const ProtocolMethodLists &methodLists) {
3753 auto optInstanceMethods = methodLists.emitMethodList(
3754 this, PD, ProtocolMethodLists::OptionalInstanceMethods);
3755 auto optClassMethods = methodLists.emitMethodList(
3756 this, PD, ProtocolMethodLists::OptionalClassMethods);
3758 auto extendedMethodTypes = EmitProtocolMethodTypes(
3759 "OBJC_PROTOCOL_METHOD_TYPES_" + PD->
getName(),
3760 methodLists.emitExtendedTypesArray(
this), ObjCTypes);
3762 auto instanceProperties = EmitPropertyList(
3763 "OBJC_$_PROP_PROTO_LIST_" + PD->
getName(),
nullptr, PD, ObjCTypes,
false);
3764 auto classProperties =
3765 EmitPropertyList(
"OBJC_$_CLASS_PROP_PROTO_LIST_" + PD->
getName(),
nullptr,
3766 PD, ObjCTypes,
true);
3769 if (optInstanceMethods->isNullValue() && optClassMethods->isNullValue() &&
3770 extendedMethodTypes->isNullValue() && instanceProperties->isNullValue() &&
3771 classProperties->isNullValue()) {
3772 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
3776 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
3778 ConstantInitBuilder builder(CGM);
3779 auto values = builder.beginStruct(ObjCTypes.ProtocolExtensionTy);
3780 values.addInt(ObjCTypes.IntTy, size);
3781 values.add(optInstanceMethods);
3782 values.add(optClassMethods);
3783 values.add(instanceProperties);
3784 values.add(extendedMethodTypes);
3785 values.add(classProperties);
3788 return CreateMetadataVar(
"_OBJC_PROTOCOLEXT_" + PD->
getName(), values,
3800CGObjCMac::EmitProtocolList(Twine name,
3804 auto PDs = GetRuntimeProtocolList(begin, end);
3806 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
3808 ConstantInitBuilder builder(CGM);
3809 auto values = builder.beginStruct();
3812 values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
3815 auto countSlot = values.addPlaceholder();
3817 auto refsArray = values.beginArray(ObjCTypes.ProtocolPtrTy);
3818 for (
const auto *Proto : PDs)
3819 refsArray.add(GetProtocolRef(Proto));
3821 auto count = refsArray.size();
3824 refsArray.addNullPointer(ObjCTypes.ProtocolPtrTy);
3826 refsArray.finishAndAddTo(values);
3827 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
3830 if (CGM.
getTriple().isOSBinFormatMachO())
3831 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3833 llvm::GlobalVariable *GV =
3834 CreateMetadataVar(name, values, section, CGM.
getPointerAlign(),
false);
3843 if (IsClassProperty != PD->isClassProperty())
3847 Properties.push_back(PD);
3850 for (
const auto *P : Proto->
protocols())
3866llvm::Constant *CGObjCCommonMac::EmitPropertyList(
3867 Twine Name,
const Decl *Container,
const ObjCContainerDecl *OCD,
3868 const ObjCCommonTypesHelper &ObjCTypes,
bool IsClassProperty) {
3869 if (IsClassProperty) {
3873 if ((Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 11)) ||
3874 (Triple.isiOS() && Triple.isOSVersionLT(9)))
3875 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3878 SmallVector<const ObjCPropertyDecl *, 16> Properties;
3879 llvm::SmallPtrSet<const IdentifierInfo *, 16> PropertySet;
3881 if (
const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD))
3882 for (
const ObjCCategoryDecl *ClassExt : OID->known_extensions())
3883 for (
auto *PD : ClassExt->properties()) {
3884 if (IsClassProperty != PD->isClassProperty())
3886 if (PD->isDirectProperty())
3889 Properties.push_back(PD);
3893 if (IsClassProperty != PD->isClassProperty())
3899 if (PD->isDirectProperty())
3901 Properties.push_back(PD);
3904 if (
const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) {
3905 for (
const auto *P : OID->all_referenced_protocols())
3907 }
else if (
const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD)) {
3908 for (
const auto *P : CD->protocols())
3913 if (Properties.empty())
3914 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3916 unsigned propertySize =
3919 ConstantInitBuilder builder(CGM);
3920 auto values = builder.beginStruct();
3921 values.addInt(ObjCTypes.IntTy, propertySize);
3922 values.addInt(ObjCTypes.IntTy, Properties.size());
3923 auto propertiesArray = values.beginArray(ObjCTypes.PropertyTy);
3924 for (
auto PD : Properties) {
3925 auto property = propertiesArray.beginStruct(ObjCTypes.PropertyTy);
3927 property.add(GetPropertyTypeString(PD, Container));
3928 property.finishAndAddTo(propertiesArray);
3930 propertiesArray.finishAndAddTo(values);
3933 if (CGM.
getTriple().isOSBinFormatMachO())
3934 Section = (ObjCABI == 2) ?
"__DATA, __objc_const"
3935 :
"__OBJC,__property,regular,no_dead_strip";
3937 llvm::GlobalVariable *GV =
3938 CreateMetadataVar(Name, values, Section, CGM.
getPointerAlign(),
true);
3942llvm::Constant *CGObjCCommonMac::EmitProtocolMethodTypes(
3943 Twine Name, ArrayRef<llvm::Constant *> MethodTypes,
3944 const ObjCCommonTypesHelper &ObjCTypes) {
3946 if (MethodTypes.empty())
3947 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy);
3949 llvm::ArrayType *AT =
3950 llvm::ArrayType::get(ObjCTypes.Int8PtrTy, MethodTypes.size());
3951 llvm::Constant *
Init = llvm::ConstantArray::get(AT, MethodTypes);
3954 if (CGM.
getTriple().isOSBinFormatMachO() && ObjCABI == 2)
3955 Section =
"__DATA, __objc_const";
3957 llvm::GlobalVariable *GV =
3974void CGObjCMac::GenerateCategory(
const ObjCCategoryImplDecl *OCD) {
3982 const ObjCCategoryDecl *Category =
3985 SmallString<256> ExtName;
3986 llvm::raw_svector_ostream(ExtName)
3989 ConstantInitBuilder Builder(CGM);
3990 auto Values = Builder.beginStruct(ObjCTypes.CategoryTy);
3992 enum { InstanceMethods, ClassMethods, NumMethodLists };
3993 SmallVector<const ObjCMethodDecl *, 16> Methods[NumMethodLists];
3994 for (
const auto *MD : OCD->
methods()) {
3995 if (!MD->isDirectMethod())
3996 Methods[unsigned(MD->isClassMethod())].push_back(MD);
3999 Values.add(GetClassName(OCD->
getName()));
4000 Values.add(GetClassName(
Interface->getObjCRuntimeNameAsString()));
4001 LazySymbols.insert(
Interface->getIdentifier());
4003 Values.add(emitMethodList(ExtName, MethodListType::CategoryInstanceMethods,
4004 Methods[InstanceMethods]));
4005 Values.add(emitMethodList(ExtName, MethodListType::CategoryClassMethods,
4006 Methods[ClassMethods]));
4008 Values.add(EmitProtocolList(
"OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
4009 Category->protocol_begin(),
4010 Category->protocol_end()));
4012 Values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
4014 Values.addInt(ObjCTypes.IntTy, Size);
4018 Values.add(EmitPropertyList(
"_OBJC_$_PROP_LIST_" + ExtName.str(), OCD,
4019 Category, ObjCTypes,
false));
4020 Values.add(EmitPropertyList(
"_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(), OCD,
4021 Category, ObjCTypes,
true));
4023 Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
4024 Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
4027 llvm::GlobalVariable *GV = CreateMetadataVar(
4028 "OBJC_CATEGORY_" + ExtName.str(), Values,
4029 "__OBJC,__category,regular,no_dead_strip", CGM.
getPointerAlign(),
true);
4030 DefinedCategories.push_back(GV);
4031 DefinedCategoryNames.insert(llvm::CachedHashString(ExtName));
4033 MethodDefinitions.clear();
4094 if (
auto *RD =
type->getAsRecordDecl()) {
4095 for (
auto *field : RD->
fields()) {
4114 ID->getClassInterface()->all_declared_ivar_begin();
4142void CGObjCMac::GenerateClass(
const ObjCImplementationDecl *ID) {
4143 IdentifierInfo *RuntimeName =
4145 DefinedSymbols.insert(RuntimeName);
4147 std::string ClassName =
ID->getNameAsString();
4150 const_cast<ObjCInterfaceDecl *
>(
ID->getClassInterface());
4151 llvm::Constant *Protocols =
4152 EmitProtocolList(
"OBJC_CLASS_PROTOCOLS_" +
ID->getName(),
4153 Interface->all_referenced_protocol_begin(),
4154 Interface->all_referenced_protocol_end());
4156 if (
ID->hasNonZeroConstructors() ||
ID->hasDestructors())
4159 bool hasMRCWeak =
false;
4174 enum { InstanceMethods, ClassMethods, NumMethodLists };
4175 SmallVector<const ObjCMethodDecl *, 16> Methods[NumMethodLists];
4176 for (
const auto *MD :
ID->methods()) {
4177 if (!MD->isDirectMethod())
4178 Methods[unsigned(MD->isClassMethod())].push_back(MD);
4181 for (
const auto *PID :
ID->property_impls()) {
4183 if (PID->getPropertyDecl()->isDirectProperty())
4185 if (ObjCMethodDecl *MD = PID->getGetterMethodDecl())
4186 if (GetMethodDefinition(MD))
4187 Methods[InstanceMethods].push_back(MD);
4188 if (ObjCMethodDecl *MD = PID->getSetterMethodDecl())
4189 if (GetMethodDefinition(MD))
4190 Methods[InstanceMethods].push_back(MD);
4194 ConstantInitBuilder builder(CGM);
4195 auto values = builder.beginStruct(ObjCTypes.ClassTy);
4196 values.add(EmitMetaClass(ID, Protocols, Methods[ClassMethods]));
4197 if (ObjCInterfaceDecl *Super =
Interface->getSuperClass()) {
4199 LazySymbols.insert(Super->getIdentifier());
4201 values.add(GetClassName(Super->getObjCRuntimeNameAsString()));
4203 values.addNullPointer(ObjCTypes.ClassPtrTy);
4205 values.add(GetClassName(
ID->getObjCRuntimeNameAsString()));
4207 values.addInt(ObjCTypes.LongTy, 0);
4208 values.addInt(ObjCTypes.LongTy, Flags);
4209 values.addInt(ObjCTypes.LongTy,
Size.getQuantity());
4210 values.add(EmitIvarList(ID,
false));
4211 values.add(emitMethodList(
ID->getName(), MethodListType::InstanceMethods,
4212 Methods[InstanceMethods]));
4214 values.addNullPointer(ObjCTypes.CachePtrTy);
4215 values.add(Protocols);
4217 values.add(EmitClassExtension(ID, Size, hasMRCWeak,
4220 std::string Name(
"OBJC_CLASS_");
4222 const char *Section =
"__OBJC,__class,regular,no_dead_strip";
4224 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
4226 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4227 "Forward metaclass reference has incorrect type.");
4228 values.finishAndSetAsInitializer(GV);
4229 GV->setSection(Section);
4233 GV = CreateMetadataVar(Name, values, Section, CGM.
getPointerAlign(),
true);
4234 DefinedClasses.push_back(GV);
4235 ImplementedClasses.push_back(
Interface);
4237 MethodDefinitions.clear();
4241CGObjCMac::EmitMetaClass(
const ObjCImplementationDecl *ID,
4242 llvm::Constant *Protocols,
4243 ArrayRef<const ObjCMethodDecl *> Methods) {
4250 ConstantInitBuilder builder(CGM);
4251 auto values = builder.beginStruct(ObjCTypes.ClassTy);
4253 const ObjCInterfaceDecl *Root =
ID->getClassInterface();
4254 while (
const ObjCInterfaceDecl *Super = Root->
getSuperClass())
4260 if (ObjCInterfaceDecl *Super =
ID->getClassInterface()->getSuperClass()) {
4261 values.add(GetClassName(Super->getObjCRuntimeNameAsString()));
4263 values.addNullPointer(ObjCTypes.ClassPtrTy);
4265 values.add(GetClassName(
ID->getObjCRuntimeNameAsString()));
4267 values.addInt(ObjCTypes.LongTy, 0);
4268 values.addInt(ObjCTypes.LongTy, Flags);
4269 values.addInt(ObjCTypes.LongTy, Size);
4270 values.add(EmitIvarList(ID,
true));
4272 emitMethodList(
ID->getName(), MethodListType::ClassMethods, Methods));
4274 values.addNullPointer(ObjCTypes.CachePtrTy);
4275 values.add(Protocols);
4277 values.addNullPointer(ObjCTypes.Int8PtrTy);
4282 std::string Name(
"OBJC_METACLASS_");
4283 Name +=
ID->getName();
4286 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
4288 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4289 "Forward metaclass reference has incorrect type.");
4290 values.finishAndSetAsInitializer(GV);
4294 llvm::GlobalValue::PrivateLinkage);
4296 GV->setSection(
"__OBJC,__meta_class,regular,no_dead_strip");
4302llvm::Constant *CGObjCMac::EmitMetaClassRef(
const ObjCInterfaceDecl *ID) {
4303 std::string Name =
"OBJC_METACLASS_" +
ID->getNameAsString();
4313 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
4315 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
4316 llvm::GlobalValue::PrivateLinkage,
nullptr,
4319 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4320 "Forward metaclass reference has incorrect type.");
4324llvm::Value *CGObjCMac::EmitSuperClassRef(
const ObjCInterfaceDecl *ID) {
4325 std::string Name =
"OBJC_CLASS_" +
ID->getNameAsString();
4326 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
4329 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
4330 llvm::GlobalValue::PrivateLinkage,
nullptr,
4333 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4334 "Forward class metadata reference has incorrect type.");
4349llvm::Constant *CGObjCMac::EmitClassExtension(
const ObjCImplementationDecl *ID,
4350 CharUnits InstanceSize,
4354 llvm::Constant *layout;
4356 layout = llvm::ConstantPointerNull::get(CGM.
Int8PtrTy);
4363 llvm::Constant *propertyList =
4364 EmitPropertyList((isMetaclass ? Twine(
"_OBJC_$_CLASS_PROP_LIST_")
4365 : Twine(
"_OBJC_$_PROP_LIST_")) +
4367 ID,
ID->getClassInterface(), ObjCTypes, isMetaclass);
4370 if (layout->isNullValue() && propertyList->isNullValue()) {
4371 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
4375 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
4377 ConstantInitBuilder builder(CGM);
4378 auto values = builder.beginStruct(ObjCTypes.ClassExtensionTy);
4379 values.addInt(ObjCTypes.IntTy, size);
4381 values.add(propertyList);
4383 return CreateMetadataVar(
"OBJC_CLASSEXT_" +
ID->getName(), values,
4384 "__OBJC,__class_ext,regular,no_dead_strip",
4400llvm::Constant *CGObjCMac::EmitIvarList(
const ObjCImplementationDecl *ID,
4408 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
4410 const ObjCInterfaceDecl *OID =
ID->getClassInterface();
4412 ConstantInitBuilder builder(CGM);
4413 auto ivarList = builder.beginStruct();
4414 auto countSlot = ivarList.addPlaceholder();
4415 auto ivars = ivarList.beginArray(ObjCTypes.IvarTy);
4420 if (!IVD->getDeclName())
4423 auto ivar = ivars.beginStruct(ObjCTypes.IvarTy);
4424 ivar.add(GetMethodVarName(IVD->getIdentifier()));
4425 ivar.add(GetMethodVarType(IVD));
4426 ivar.addInt(ObjCTypes.IntTy, ComputeIvarBaseOffset(CGM, OID, IVD));
4427 ivar.finishAndAddTo(ivars);
4431 auto count = ivars.size();
4435 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
4438 ivars.finishAndAddTo(ivarList);
4439 ivarList.fillPlaceholderWithInt(countSlot, ObjCTypes.IntTy, count);
4441 llvm::GlobalVariable *GV;
4442 GV = CreateMetadataVar(
"OBJC_INSTANCE_VARIABLES_" +
ID->getName(), ivarList,
4443 "__OBJC,__instance_vars,regular,no_dead_strip",
4454void CGObjCMac::emitMethodDescriptionConstant(ConstantArrayBuilder &builder,
4455 const ObjCMethodDecl *MD) {
4456 auto description = builder.
beginStruct(ObjCTypes.MethodDescriptionTy);
4457 description.add(GetMethodVarName(MD->
getSelector()));
4458 description.add(GetMethodVarType(MD));
4459 description.finishAndAddTo(builder);
4469void CGObjCMac::emitMethodConstant(ConstantArrayBuilder &builder,
4470 const ObjCMethodDecl *MD) {
4471 llvm::Function *fn = GetMethodDefinition(MD);
4472 assert(fn &&
"no definition registered for method");
4474 auto method = builder.
beginStruct(ObjCTypes.MethodTy);
4476 method.add(GetMethodVarType(MD));
4478 method.finishAndAddTo(builder);
4495CGObjCMac::emitMethodList(Twine name, MethodListType MLT,
4496 ArrayRef<const ObjCMethodDecl *> methods) {
4499 bool forProtocol =
false;
4501 case MethodListType::CategoryInstanceMethods:
4502 prefix =
"OBJC_CATEGORY_INSTANCE_METHODS_";
4503 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
4504 forProtocol =
false;
4506 case MethodListType::CategoryClassMethods:
4507 prefix =
"OBJC_CATEGORY_CLASS_METHODS_";
4508 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
4509 forProtocol =
false;
4511 case MethodListType::InstanceMethods:
4512 prefix =
"OBJC_INSTANCE_METHODS_";
4513 section =
"__OBJC,__inst_meth,regular,no_dead_strip";
4514 forProtocol =
false;
4516 case MethodListType::ClassMethods:
4517 prefix =
"OBJC_CLASS_METHODS_";
4518 section =
"__OBJC,__cls_meth,regular,no_dead_strip";
4519 forProtocol =
false;
4521 case MethodListType::ProtocolInstanceMethods:
4522 prefix =
"OBJC_PROTOCOL_INSTANCE_METHODS_";
4523 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
4526 case MethodListType::ProtocolClassMethods:
4527 prefix =
"OBJC_PROTOCOL_CLASS_METHODS_";
4528 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
4531 case MethodListType::OptionalProtocolInstanceMethods:
4532 prefix =
"OBJC_PROTOCOL_INSTANCE_METHODS_OPT_";
4533 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
4536 case MethodListType::OptionalProtocolClassMethods:
4537 prefix =
"OBJC_PROTOCOL_CLASS_METHODS_OPT_";
4538 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
4544 if (methods.empty())
4545 return llvm::Constant::getNullValue(
4546 forProtocol ? ObjCTypes.MethodDescriptionListPtrTy
4547 : ObjCTypes.MethodListPtrTy);
4552 ConstantInitBuilder builder(CGM);
4554 values.addInt(ObjCTypes.IntTy, methods.size());
4555 auto methodArray = values.beginArray(ObjCTypes.MethodDescriptionTy);
4556 for (
auto MD : methods) {
4557 emitMethodDescriptionConstant(methodArray, MD);
4559 methodArray.finishAndAddTo(values);
4561 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
4567 ConstantInitBuilder builder(CGM);
4569 values.addNullPointer(ObjCTypes.Int8PtrTy);
4570 values.addInt(ObjCTypes.IntTy, methods.size());
4571 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
4572 for (
auto MD : methods) {
4574 emitMethodConstant(methodArray, MD);
4576 methodArray.finishAndAddTo(values);
4578 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
4583llvm::Function *CGObjCCommonMac::GenerateMethod(
const ObjCMethodDecl *OMD,
4584 const ObjCContainerDecl *CD) {
4589 DirectMethodInfo &Info = GenerateDirectMethod(OMD, CD);
4590 Method = Info.Implementation;
4592 auto Name = getSymbolNameForMethod(OMD);
4594 CodeGenTypes &Types = CGM.
getTypes();
4595 llvm::FunctionType *MethodTy =
4597 Method = llvm::Function::Create(
4598 MethodTy, llvm::GlobalValue::InternalLinkage, Name, &CGM.
getModule());
4601 MethodDefinitions.insert(std::make_pair(OMD,
Method));
4607CGObjCCommonMac::DirectMethodInfo &
4608CGObjCCommonMac::GenerateDirectMethod(
const ObjCMethodDecl *OMD,
4609 const ObjCContainerDecl *CD) {
4614 auto Cached = DirectMethodDefinitions.find(COMD);
4615 if (Cached != DirectMethodDefinitions.end()) {
4617 return Cached->second;
4620 CodeGenTypes &Types = CGM.
getTypes();
4621 llvm::FunctionType *MethodTy =
4624 getSymbolNameForMethod(OMD,
false,
4626 std::string ThunkName = Name +
"_thunk";
4629 auto ReplaceFunction = [](llvm::Function *OldFn, llvm::Function *NewFn) {
4630 NewFn->takeName(OldFn);
4631 OldFn->replaceAllUsesWith(NewFn);
4632 OldFn->eraseFromParent();
4637 llvm::Function *
Fn = CGM.
getModule().getFunction(Name);
4641 Fn = llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,
4643 return DirectMethodDefinitions.insert({COMD, DirectMethodInfo(Fn)})
4649 if (
Fn->getFunctionType() == MethodTy) {
4651 Fn->setLinkage(llvm::GlobalValue::ExternalLinkage);
4654 DirectMethodInfo Info(Fn);
4655 if (llvm::Function *Thunk = CGM.
getModule().getFunction(ThunkName))
4658 return DirectMethodDefinitions.insert({COMD, Info}).first->second;
4664 llvm::Function *NewFn = llvm::Function::Create(
4665 MethodTy, llvm::GlobalValue::ExternalLinkage,
"", &CGM.
getModule());
4666 ReplaceFunction(Fn, NewFn);
4669 DirectMethodInfo Info(NewFn);
4670 if (llvm::Function *OldThunk = CGM.
getModule().getFunction(ThunkName)) {
4671 llvm::Function *NewThunk = GenerateObjCDirectThunk(OMD, CD, NewFn);
4672 ReplaceFunction(OldThunk, NewThunk);
4673 Info.Thunk = NewThunk;
4676 if (Cached != DirectMethodDefinitions.end()) {
4677 Cached->second = Info;
4678 return Cached->second;
4680 return DirectMethodDefinitions.insert({COMD, Info}).first->second;
4746CGObjCCommonMac::GenerateObjCDirectThunk(
const ObjCMethodDecl *OMD,
4748 llvm::Function *Implementation) {
4751 "Should only generate thunk when optimization enabled");
4752 assert(Implementation &&
"Implementation must exist");
4754 llvm::FunctionType *ThunkTy = Implementation->getFunctionType();
4755 std::string ThunkName = Implementation->getName().str() +
"_thunk";
4758 llvm::Function *Thunk =
4759 llvm::Function::Create(ThunkTy, llvm::GlobalValue::LinkOnceODRLinkage,
4766 Thunk->setVisibility(llvm::GlobalValue::HiddenVisibility);
4767 Thunk->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4786 GenerateDirectMethodsPreconditionCheck(CGF, Thunk, OMD, CD);
4791 for (
auto &Arg : Thunk->args())
4792 Args.push_back(&Arg);
4795 llvm::CallInst *
Call = CGF.
Builder.CreateCall(Implementation, Args);
4796 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
4803 llvm::AttributeList Attrs;
4807 Call->setAttributes(Attrs);
4808 Call->setCallingConv(
static_cast<llvm::CallingConv::ID
>(
CallingConv));
4813 if (ThunkTy->getReturnType()->isVoidTy())
4823llvm::Function *CGObjCCommonMac::GetDirectMethodCallee(
4825 bool ReceiverCanBeNull,
bool ClassObjectCanBeUnrealized) {
4830 DirectMethodInfo Info = GenerateDirectMethod(OMD, CD);
4836 return Info.Implementation;
4840 auto getOrCreateThunk = [&]() {
4842 Info.Thunk = GenerateObjCDirectThunk(OMD, CD, Info.Implementation);
4852 return ReceiverCanBeNull ? getOrCreateThunk() : Info.Implementation;
4855 "OMD should either be a class method or instance method");
4859 return (ReceiverCanBeNull || ClassObjectCanBeUnrealized)
4860 ? getOrCreateThunk()
4861 : Info.Implementation;
4865CGObjCCommonMac::GenerateClassRealization(CodeGenFunction &CGF,
4866 llvm::Value *classObject,
4867 const ObjCInterfaceDecl *OID) {
4874 RValue result = GeneratePossiblySpecializedMessageSend(
4875 CGF, ReturnValueSlot(), ResultType, SelfSel, classObject, Args, OID,
4881void CGObjCCommonMac::GenerateDirectMethodsPreconditionCheck(
4882 CodeGenFunction &CGF, llvm::Function *Fn,
const ObjCMethodDecl *OMD,
4883 const ObjCContainerDecl *CD) {
4885 bool ReceiverCanBeNull =
true;
4887 auto selfValue = Builder.CreateLoad(selfAddr);
4902 "GenerateDirectMethod() should be called with the Class Interface");
4913 llvm::Value *realizedClass = GenerateClassRealization(CGF, selfValue, OID);
4914 Builder.CreateStore(realizedClass, selfAddr);
4919 ReceiverCanBeNull = isWeakLinkedClass(OID);
4923 if (ReceiverCanBeNull) {
4924 llvm::BasicBlock *SelfIsNilBlock =
4926 llvm::BasicBlock *ContBlock =
4931 auto Zero = llvm::ConstantPointerNull::get(selfTy);
4934 Builder.CreateCondBr(Builder.CreateICmpEQ(selfValue,
Zero), SelfIsNilBlock,
4935 ContBlock, MDHelper.createUnlikelyBranchWeights());
4941 Builder.SetInsertPoint(SelfIsNilBlock);
4942 if (!retTy->isVoidType()) {
4950 Builder.SetInsertPoint(ContBlock);
4954void CGObjCCommonMac::GenerateDirectMethodPrologue(
4955 CodeGenFunction &CGF, llvm::Function *Fn,
const ObjCMethodDecl *OMD,
4956 const ObjCContainerDecl *CD) {
4959 GenerateDirectMethodsPreconditionCheck(CGF, Fn, OMD, CD);
4968 Builder.CreateStore(GetSelector(CGF, OMD),
4973llvm::Function *CGObjCCommonMac::GenerateMethodSelectorStub(
4974 Selector Sel, StringRef ClassName,
const ObjCCommonTypesHelper &ObjCTypes) {
4975 assert((!ClassName.data() || !ClassName.empty()) &&
4976 "class name cannot be an empty string");
4977 auto Key = std::make_pair(Sel, ClassName);
4978 auto I = MethodSelectorStubs.find(Key);
4980 if (I != MethodSelectorStubs.end())
4983 auto *FnTy = llvm::FunctionType::get(
4984 ObjCTypes.ObjectPtrTy, {ObjCTypes.ObjectPtrTy, ObjCTypes.SelectorPtrTy},
4988 if (ClassName.data())
4989 FnName = (
"objc_msgSendClass$" + Sel.
getAsString() +
"$_OBJC_CLASS_$_" +
4990 llvm::Twine(ClassName))
4998 MethodSelectorStubs.insert(std::make_pair(Key, Fn));
5002llvm::GlobalVariable *
5003CGObjCCommonMac::CreateMetadataVar(Twine Name, ConstantStructBuilder &
Init,
5004 StringRef Section, CharUnits Align,
5006 llvm::GlobalValue::LinkageTypes
LT =
5008 llvm::GlobalVariable *GV =
5009 Init.finishAndCreateGlobal(Name, Align,
false, LT);
5010 if (!Section.empty())
5011 GV->setSection(Section);
5017llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
5018 llvm::Constant *
Init,
5022 llvm::Type *Ty =
Init->getType();
5023 llvm::GlobalValue::LinkageTypes
LT =
5025 llvm::GlobalVariable *GV =
5026 new llvm::GlobalVariable(CGM.
getModule(), Ty,
false, LT,
Init, Name);
5027 if (!Section.empty())
5028 GV->setSection(Section);
5035llvm::GlobalVariable *
5036CGObjCCommonMac::CreateCStringLiteral(StringRef Name, ObjCLabelType
Type,
5037 bool ForceNonFragileABI,
5038 bool NullTerminate) {
5041 case ObjCLabelType::ClassName:
5042 Label =
"OBJC_CLASS_NAME_";
5044 case ObjCLabelType::MethodVarName:
5045 Label =
"OBJC_METH_VAR_NAME_";
5047 case ObjCLabelType::MethodVarType:
5048 Label =
"OBJC_METH_VAR_TYPE_";
5050 case ObjCLabelType::PropertyName:
5051 Label =
"OBJC_PROP_NAME_ATTR_";
5053 case ObjCLabelType::LayoutBitMap:
5054 Label =
"OBJC_LAYOUT_BITMAP_";
5058 bool NonFragile = ForceNonFragileABI || isNonFragileABI();
5062 case ObjCLabelType::ClassName:
5063 Section = NonFragile ?
"__TEXT,__objc_classname,cstring_literals"
5064 :
"__TEXT,__cstring,cstring_literals";
5066 case ObjCLabelType::MethodVarName:
5067 Section = NonFragile ?
"__TEXT,__objc_methname,cstring_literals"
5068 :
"__TEXT,__cstring,cstring_literals";
5070 case ObjCLabelType::MethodVarType:
5071 Section = NonFragile ?
"__TEXT,__objc_methtype,cstring_literals"
5072 :
"__TEXT,__cstring,cstring_literals";
5074 case ObjCLabelType::PropertyName:
5075 Section = NonFragile ?
"__TEXT,__objc_methname,cstring_literals"
5076 :
"__TEXT,__cstring,cstring_literals";
5078 case ObjCLabelType::LayoutBitMap:
5079 Section =
"__TEXT,__cstring,cstring_literals";
5083 llvm::Constant *
Value =
5084 llvm::ConstantDataArray::getString(VMContext, Name, NullTerminate);
5085 llvm::GlobalVariable *GV =
new llvm::GlobalVariable(
5087 true, llvm::GlobalValue::PrivateLinkage,
Value, Label);
5088 if (CGM.
getTriple().isOSBinFormatMachO())
5089 GV->setSection(Section);
5090 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
5097llvm::Function *CGObjCMac::ModuleInitFunction() {
5103llvm::FunctionCallee CGObjCMac::GetPropertyGetFunction() {
5104 return ObjCTypes.getGetPropertyFn();
5107llvm::FunctionCallee CGObjCMac::GetPropertySetFunction() {
5108 return ObjCTypes.getSetPropertyFn();
5111llvm::FunctionCallee CGObjCMac::GetOptimizedPropertySetFunction(
bool atomic,
5113 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
5116llvm::FunctionCallee CGObjCMac::GetGetStructFunction() {
5117 return ObjCTypes.getCopyStructFn();
5120llvm::FunctionCallee CGObjCMac::GetSetStructFunction() {
5121 return ObjCTypes.getCopyStructFn();
5124llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectGetFunction() {
5125 return ObjCTypes.getCppAtomicObjectFunction();
5128llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectSetFunction() {
5129 return ObjCTypes.getCppAtomicObjectFunction();
5132llvm::FunctionCallee CGObjCMac::EnumerationMutationFunction() {
5133 return ObjCTypes.getEnumerationMutationFn();
5136void CGObjCMac::EmitTryStmt(CodeGenFunction &CGF,
const ObjCAtTryStmt &S) {
5137 return EmitTryOrSynchronizedStmt(CGF, S);
5140void CGObjCMac::EmitSynchronizedStmt(CodeGenFunction &CGF,
5141 const ObjCAtSynchronizedStmt &S) {
5142 return EmitTryOrSynchronizedStmt(CGF, S);
5146struct PerformFragileFinally final : EHScopeStack::Cleanup {
5151 ObjCTypesHelper &ObjCTypes;
5152 PerformFragileFinally(
const Stmt *S, Address SyncArgSlot,
5153 Address CallTryExitVar, Address ExceptionData,
5154 ObjCTypesHelper *ObjCTypes)
5155 : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
5156 ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
5158 void Emit(CodeGenFunction &CGF, Flags flags)
override {
5161 llvm::BasicBlock *FinallyCallExit =
5163 llvm::BasicBlock *FinallyNoCallExit =
5166 FinallyCallExit, FinallyNoCallExit);
5175 if (
const ObjCAtFinallyStmt *FinallyStmt =
5178 if (flags.isForEHCleanup())
5183 llvm::Value *CurCleanupDest =
5186 CGF.
EmitStmt(FinallyStmt->getFinallyBody());
5205class FragileHazards {
5206 CodeGenFunction &CGF;
5207 SmallVector<llvm::Value *, 20> Locals;
5208 llvm::DenseSet<llvm::BasicBlock *> BlocksBeforeTry;
5210 llvm::InlineAsm *ReadHazard;
5211 llvm::InlineAsm *WriteHazard;
5213 llvm::FunctionType *GetAsmFnType();
5215 void collectLocals();
5216 void emitReadHazard(CGBuilderTy &Builder);
5219 FragileHazards(CodeGenFunction &CGF);
5221 void emitWriteHazard();
5222 void emitHazardsInNewBlocks();
5231FragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) {
5238 for (llvm::BasicBlock &BB : *CGF.
CurFn)
5239 BlocksBeforeTry.insert(&BB);
5241 llvm::FunctionType *AsmFnTy = GetAsmFnType();
5249 std::string Constraint;
5250 for (
unsigned I = 0, E = Locals.size(); I != E; ++I) {
5256 ReadHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
5264 std::string Constraint;
5265 for (
unsigned I = 0, E = Locals.size(); I != E; ++I) {
5268 Constraint +=
"=*m";
5271 WriteHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
5276void FragileHazards::emitWriteHazard() {
5281 for (
auto Pair : llvm::enumerate(Locals))
5284 llvm::Attribute::get(
5289void FragileHazards::emitReadHazard(
CGBuilderTy &Builder) {
5290 assert(!Locals.empty());
5291 llvm::CallInst *call = Builder.CreateCall(ReadHazard, Locals);
5292 call->setDoesNotThrow();
5294 for (
auto Pair : llvm::enumerate(Locals))
5297 llvm::Attribute::get(
5298 Builder.getContext(), llvm::Attribute::ElementType,
5304void FragileHazards::emitHazardsInNewBlocks() {
5311 for (llvm::BasicBlock &BB : *CGF.
CurFn) {
5312 if (BlocksBeforeTry.count(&BB))
5316 for (llvm::BasicBlock::iterator BI = BB.begin(), BE = BB.end(); BI != BE;
5318 llvm::Instruction &I = *BI;
5337 Builder.SetInsertPoint(BI);
5338 emitReadHazard(Builder);
5345 if (llvm::Value *Ptr =
V.getBasePointer())
5349void FragileHazards::collectLocals() {
5351 llvm::DenseSet<llvm::Value *> AllocasToIgnore;
5357 llvm::BasicBlock &Entry = CGF.
CurFn->getEntryBlock();
5358 for (llvm::Instruction &I : Entry)
5360 Locals.push_back(&I);
5363llvm::FunctionType *FragileHazards::GetAsmFnType() {
5364 SmallVector<llvm::Type *, 16> tys(Locals.size());
5365 for (
unsigned i = 0, e = Locals.size(); i != e; ++i)
5366 tys[i] = Locals[i]->getType();
5367 return llvm::FunctionType::get(CGF.
VoidTy, tys,
false);
5478void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
5499 llvm::Value *SyncArg =
5501 SyncArg = CGF.
Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
5512 ObjCTypes.ExceptionDataTy, CGF.
getPointerAlign(),
"exceptiondata.ptr");
5518 FragileHazards Hazards(CGF);
5537 SyncArgSlot, CallTryExitVar,
5538 ExceptionData, &ObjCTypes);
5544 ExceptionData.emitRawPointer(CGF));
5547 llvm::Constant *
Zero = llvm::ConstantInt::get(CGF.
Builder.getInt32Ty(), 0);
5550 ObjCTypes.ExceptionDataTy, ExceptionData.emitRawPointer(CGF), GEPIndexes,
5553 ObjCTypes.getSetJmpFn(), SetJmpBuffer,
"setjmp_result");
5554 SetJmpResult->setCanReturnTwice();
5560 llvm::Value *DidCatch =
5561 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
5562 CGF.
Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
5570 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.
Builder.saveAndClearIP();
5576 Hazards.emitWriteHazard();
5590 ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF),
5601 llvm::BasicBlock *CatchBlock =
nullptr;
5602 llvm::BasicBlock *CatchHandler =
nullptr;
5613 ExceptionData.emitRawPointer(CGF));
5616 ObjCTypes.getSetJmpFn(), SetJmpBuffer,
"setjmp.result");
5617 SetJmpResult->setCanReturnTwice();
5619 llvm::Value *Threw =
5620 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
5624 CGF.
Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
5634 bool AllMatched =
false;
5635 for (
const ObjCAtCatchStmt *CatchStmt : AtTryStmt->
catch_stmts()) {
5636 const VarDecl *CatchParam = CatchStmt->getCatchParamDecl();
5637 const ObjCObjectPointerType *OPT =
nullptr;
5643 OPT = CatchParam->
getType()->
getAs<ObjCObjectPointerType>();
5662 EmitInitOfCatchParam(CGF, Caught, CatchParam);
5665 CGF.
EmitStmt(CatchStmt->getCatchBody());
5668 CatchVarCleanups.ForceCleanup();
5674 assert(OPT &&
"Unexpected non-object pointer type in @catch");
5678 ObjCInterfaceDecl *IDecl = ObjTy->getInterface();
5679 assert(IDecl &&
"Catch parameter must have Objective-C type!");
5682 llvm::Value *
Class = EmitClassRef(CGF, IDecl);
5684 llvm::Value *matchArgs[] = {
Class, Caught};
5686 ObjCTypes.getExceptionMatchFn(), matchArgs,
"match");
5692 MatchedBlock, NextCatchBlock);
5705 llvm::Value *Tmp = CGF.
Builder.CreateBitCast(
5707 EmitInitOfCatchParam(CGF, Tmp, CatchParam);
5709 CGF.
EmitStmt(CatchStmt->getCatchBody());
5712 CatchVarCleanups.ForceCleanup();
5723 if (Caught->use_empty())
5724 Caught->eraseFromParent();
5740 assert(PropagatingExnVar.
isValid());
5742 ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF),
5753 Hazards.emitHazardsInNewBlocks();
5756 CGF.
Builder.restoreIP(TryFallthroughIP);
5763 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
5767 llvm::Value *PropagatingExn;
5768 if (PropagatingExnVar.
isValid()) {
5774 ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF));
5775 PropagatingExn = Caught;
5780 CGF.
Builder.CreateUnreachable();
5783 CGF.
Builder.restoreIP(SavedIP);
5786void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
5787 const ObjCAtThrowStmt &S,
5788 bool ClearInsertionPoint) {
5789 llvm::Value *ExceptionAsObject;
5794 CGF.
Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
5797 "Unexpected rethrow outside @catch block.");
5801 CGF.
EmitRuntimeCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
5802 ->setDoesNotReturn();
5803 CGF.
Builder.CreateUnreachable();
5806 if (ClearInsertionPoint)
5807 CGF.
Builder.ClearInsertionPoint();
5813llvm::Value *CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
5816 llvm::Value *AddrWeakObjVal = CGF.
Builder.CreateBitCast(
5819 ObjCTypes.getGcReadWeakFn(), AddrWeakObjVal,
"weakread");
5820 read_weak = CGF.
Builder.CreateBitCast(read_weak, DestTy);
5827void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
5828 llvm::Value *src,
Address dst) {
5829 llvm::Type *SrcTy = src->getType();
5832 assert(Size <= 8 && "does not support size > 8
");
5833 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
5834 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
5835 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5837 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5838 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
5839 ObjCTypes.PtrObjectPtrTy);
5840 llvm::Value *args[] = {src, dstVal};
5841 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), args,
5848void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
5849 llvm::Value *src, Address dst,
5851 llvm::Type *SrcTy = src->getType();
5852 if (!isa<llvm::PointerType>(SrcTy)) {
5853 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
5854 assert(Size <= 8 && "does
not support size > 8
");
5855 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
5856 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
5857 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5859 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5860 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
5861 ObjCTypes.PtrObjectPtrTy);
5862 llvm::Value *args[] = {src, dstVal};
5864 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), args,
5867 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(), args,
5868 "threadlocalassign
");
5874void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
5875 llvm::Value *src, Address dst,
5876 llvm::Value *ivarOffset) {
5877 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset
is NULL");
5878 llvm::Type *SrcTy = src->getType();
5879 if (!isa<llvm::PointerType>(SrcTy)) {
5880 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
5881 assert(Size <= 8 && "does
not support size > 8
");
5882 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
5883 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
5884 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5886 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5887 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
5888 ObjCTypes.PtrObjectPtrTy);
5889 llvm::Value *args[] = {src, dstVal, ivarOffset};
5890 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
5896void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
5897 llvm::Value *src, Address dst) {
5898 llvm::Type *SrcTy = src->getType();
5899 if (!isa<llvm::PointerType>(SrcTy)) {
5900 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
5901 assert(Size <= 8 && "does
not support size > 8
");
5902 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
5903 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
5904 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5906 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5907 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
5908 ObjCTypes.PtrObjectPtrTy);
5909 llvm::Value *args[] = {src, dstVal};
5910 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), args,
5914void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
5915 Address DestPtr, Address SrcPtr,
5916 llvm::Value *size) {
5917 llvm::Value *args[] = {DestPtr.emitRawPointer(CGF),
5918 SrcPtr.emitRawPointer(CGF), size};
5919 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
5924LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
5926 llvm::Value *BaseValue,
5927 const ObjCIvarDecl *Ivar,
5928 unsigned CVRQualifiers) {
5929 const ObjCInterfaceDecl *ID =
5930 ObjectTy->castAs<ObjCObjectType>()->getInterface();
5931 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
5932 EmitIvarOffset(CGF, ID, Ivar));
5935llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
5936 const ObjCInterfaceDecl *Interface,
5937 const ObjCIvarDecl *Ivar) {
5938 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
5939 return llvm::ConstantInt::get(
5940 CGM.getTypes().ConvertType(CGM.getContext().LongTy), Offset);
5943/* *** Private Interface *** */
5945std::string CGObjCCommonMac::GetSectionName(StringRef Section,
5946 StringRef MachOAttributes) {
5947 switch (CGM.getTriple().getObjectFormat()) {
5948 case llvm::Triple::UnknownObjectFormat:
5949 llvm_unreachable("unexpected
object file format
");
5950 case llvm::Triple::MachO: {
5951 if (MachOAttributes.empty())
5952 return ("__DATA,
" + Section).str();
5953 return ("__DATA,
" + Section + ",
" + MachOAttributes).str();
5955 case llvm::Triple::ELF:
5956 assert(Section.starts_with("__
") && "expected the name to begin with __
");
5957 return Section.substr(2).str();
5958 case llvm::Triple::COFF:
5959 assert(Section.starts_with("__
") && "expected the name to begin with __
");
5960 return (".
" + Section.substr(2) + "$B
").str();
5961 case llvm::Triple::Wasm:
5962 case llvm::Triple::GOFF:
5963 case llvm::Triple::SPIRV:
5964 case llvm::Triple::XCOFF:
5965 case llvm::Triple::DXContainer:
5966 llvm::report_fatal_error(
5967 "Objective-
C support
is unimplemented
for object file format
");
5970 llvm_unreachable("Unhandled llvm::Triple::ObjectFormatType
enum");
5982enum ImageInfoFlags {
5983 eImageInfo_FixAndContinue = (1 << 0), // This flag is no longer set by clang.
5984 eImageInfo_GarbageCollected = (1 << 1),
5985 eImageInfo_GCOnly = (1 << 2),
5986 eImageInfo_OptimizedByDyld = (1 << 3), // This flag is set by the dyld shared cache.
5988 eImageInfo_SignedClassRO = (1 << 4), // Reused (was _CorrectedSynthesize)
5989 eImageInfo_ImageIsSimulated = (1 << 5),
5990 eImageInfo_ClassProperties = (1 << 6)
5994void CGObjCCommonMac::EmitImageInfo() {
5995 unsigned version = 0; // Version is unused?
5996 std::string Section =
5998 ? "__OBJC,__image_info,regular
"
5999 : GetSectionName("__objc_imageinfo
", "regular,no_dead_strip
");
6001 // Generate module-level named metadata to convey this information to the
6002 // linker and code-gen.
6003 llvm::Module &Mod = CGM.getModule();
6005 // Add the ObjC ABI version to the module flags.
6006 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Version
", ObjCABI);
6007 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Image Info Version
",
6009 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Image Info Section
",
6010 llvm::MDString::get(VMContext, Section));
6012 auto Int8Ty = llvm::Type::getInt8Ty(VMContext);
6013 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
6014 // Non-GC overrides those files which specify GC.
6015 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Garbage Collection
",
6016 llvm::ConstantInt::get(Int8Ty, 0));
6018 // Add the ObjC garbage collection value.
6020 llvm::Module::Error, "Objective-
C Garbage Collection
",
6021 llvm::ConstantInt::get(Int8Ty, (uint8_t)eImageInfo_GarbageCollected));
6023 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
6024 // Add the ObjC GC Only value.
6025 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C GC Only
",
6028 // Require that GC be specified and set to eImageInfo_GarbageCollected.
6029 llvm::Metadata *Ops[2] = {
6030 llvm::MDString::get(VMContext, "Objective-
C Garbage Collection
"),
6031 llvm::ConstantAsMetadata::get(
6032 llvm::ConstantInt::get(Int8Ty, eImageInfo_GarbageCollected))};
6033 Mod.addModuleFlag(llvm::Module::Require, "Objective-
C GC Only
",
6034 llvm::MDNode::get(VMContext, Ops));
6038 // Indicate whether we're compiling this to run on a simulator.
6039 if (CGM.getTarget().getTriple().isSimulatorEnvironment())
6040 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Is Simulated
",
6041 eImageInfo_ImageIsSimulated);
6043 // Indicate whether we are generating class properties.
6044 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Class Properties
",
6045 eImageInfo_ClassProperties);
6047 // Indicate whether we want enforcement of pointer signing for class_ro_t
6049 if (CGM.getLangOpts().PointerAuthObjcClassROPointers)
6050 Mod.addModuleFlag(llvm::Module::Error,
6051 "Objective-
C Enforce ClassRO
Pointer Signing
",
6052 eImageInfo_SignedClassRO);
6054 Mod.addModuleFlag(llvm::Module::Error,
6055 "Objective-
C Enforce ClassRO
Pointer Signing
",
6056 llvm::ConstantInt::get(Int8Ty, 0));
6059// struct objc_module {
6060// unsigned long version;
6061// unsigned long size;
6066// FIXME: Get from somewhere
6067static const int ModuleVersion = 7;
6069void CGObjCMac::EmitModuleInfo() {
6070 uint64_t Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ModuleTy);
6072 ConstantInitBuilder builder(CGM);
6073 auto values = builder.beginStruct(ObjCTypes.ModuleTy);
6074 values.addInt(ObjCTypes.LongTy, ModuleVersion);
6075 values.addInt(ObjCTypes.LongTy, Size);
6076 // This used to be the filename, now it is unused. <rdr://4327263>
6077 values.add(GetClassName(StringRef("")));
6078 values.add(EmitModuleSymbols());
6079 CreateMetadataVar("OBJC_MODULES
", values,
6080 "__OBJC,__module_info,regular,no_dead_strip
",
6081 CGM.getPointerAlign(), true);
6084llvm::Constant *CGObjCMac::EmitModuleSymbols() {
6085 unsigned NumClasses = DefinedClasses.size();
6086 unsigned NumCategories = DefinedCategories.size();
6088 // Return null if no symbols were defined.
6089 if (!NumClasses && !NumCategories)
6090 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
6092 ConstantInitBuilder builder(CGM);
6093 auto values = builder.beginStruct();
6094 values.addInt(ObjCTypes.LongTy, 0);
6095 values.addNullPointer(ObjCTypes.SelectorPtrTy);
6096 values.addInt(ObjCTypes.ShortTy, NumClasses);
6097 values.addInt(ObjCTypes.ShortTy, NumCategories);
6099 // The runtime expects exactly the list of defined classes followed
6100 // by the list of defined categories, in a single array.
6101 auto array = values.beginArray(ObjCTypes.Int8PtrTy);
6102 for (unsigned i = 0; i < NumClasses; i++) {
6103 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
6105 if (ObjCImplementationDecl *IMP = ID->getImplementation())
6106 // We are implementing a weak imported interface. Give it external linkage
6107 if (ID->isWeakImported() && !IMP->isWeakImported())
6108 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
6110 array.add(DefinedClasses[i]);
6112 for (unsigned i = 0; i < NumCategories; i++)
6113 array.add(DefinedCategories[i]);
6115 array.finishAndAddTo(values);
6117 llvm::GlobalVariable *GV = CreateMetadataVar(
6118 "OBJC_SYMBOLS
", values, "__OBJC,__symbols,regular,no_dead_strip
",
6119 CGM.getPointerAlign(), true);
6123llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF,
6124 IdentifierInfo *II) {
6125 LazySymbols.insert(II);
6127 llvm::GlobalVariable *&Entry = ClassReferences[II];
6131 CreateMetadataVar("OBJC_CLASS_REFERENCES_
", GetClassName(II->getName()),
6132 "__OBJC,__cls_refs,literal_pointers,no_dead_strip
",
6133 CGM.getPointerAlign(), true);
6136 return CGF.Builder.CreateAlignedLoad(Entry->getValueType(), Entry,
6137 CGF.getPointerAlign());
6140llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF,
6141 const ObjCInterfaceDecl *ID) {
6142 // If the class has the objc_runtime_visible attribute, we need to
6143 // use the Objective-C runtime to get the class.
6144 if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
6145 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
6147 IdentifierInfo *RuntimeName =
6148 &CGM.getContext().Idents.get(ID->getObjCRuntimeNameAsString());
6149 return EmitClassRefFromId(CGF, RuntimeName);
6152llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
6153 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool
");
6154 return EmitClassRefFromId(CGF, II);
6157llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel) {
6158 return CGF.Builder.CreateLoad(EmitSelectorAddr(Sel));
6161ConstantAddress CGObjCMac::EmitSelectorAddr(Selector Sel) {
6162 CharUnits Align = CGM.getPointerAlign();
6164 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
6166 Entry = CreateMetadataVar(
6167 "OBJC_SELECTOR_REFERENCES_
", GetMethodVarName(Sel),
6168 "__OBJC,__message_refs,literal_pointers,no_dead_strip
", Align, true);
6169 Entry->setExternallyInitialized(true);
6172 return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align);
6175llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) {
6176 llvm::GlobalVariable *&Entry = ClassNames[RuntimeName];
6178 Entry = CreateCStringLiteral(RuntimeName, ObjCLabelType::ClassName);
6182llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
6183 return MethodDefinitions.lookup(MD);
6189CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
6190 const ObjCCommonTypesHelper &ObjCTypes) {
6191 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
6194void IvarLayoutBuilder::visitRecord(const RecordType *RT, CharUnits offset) {
6195 const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
6197 // If this is a union, remember that we had one, because it might mess
6198 // up the ordering of layout entries.
6200 IsDisordered = true;
6202 const ASTRecordLayout *recLayout = nullptr;
6203 visitAggregate(RD->field_begin(), RD->field_end(), offset,
6204 [&](const FieldDecl *field) -> CharUnits {
6206 recLayout = &CGM.getContext().getASTRecordLayout(RD);
6208 recLayout->getFieldOffset(field->getFieldIndex());
6209 return CGM.getContext().toCharUnitsFromBits(offsetInBits);
6213template <class Iterator, class GetOffsetFn>
6214void IvarLayoutBuilder::visitAggregate(Iterator begin, Iterator end,
6215 CharUnits aggregateOffset,
6216 const GetOffsetFn &getOffset) {
6217 for (; begin != end; ++begin) {
6218 auto field = *begin;
6220 // Skip over bitfields.
6221 if (field->isBitField()) {
6225 // Compute the offset of the field within the aggregate.
6226 CharUnits fieldOffset = aggregateOffset + getOffset(field);
6228 visitField(field, fieldOffset);
6233void IvarLayoutBuilder::visitField(const FieldDecl *field,
6234 CharUnits fieldOffset) {
6235 QualType fieldType = field->getType();
6237 // Drill down into arrays.
6238 uint64_t numElts = 1;
6239 if (auto arrayType = CGM.getContext().getAsIncompleteArrayType(fieldType)) {
6241 fieldType = arrayType->getElementType();
6243 // Unlike incomplete arrays, constant arrays can be nested.
6244 while (auto arrayType = CGM.getContext().getAsConstantArrayType(fieldType)) {
6245 numElts *= arrayType->getZExtSize();
6246 fieldType = arrayType->getElementType();
6249 assert(!fieldType->isArrayType() && "ivar of non-constant array
type?
");
6251 // If we ended up with a zero-sized array, we've done what we can do within
6252 // the limits of this layout encoding.
6256 // Recurse if the base element type is a record type.
6257 if (const auto *recType = fieldType->getAsCanonical<RecordType>()) {
6258 size_t oldEnd = IvarsInfo.size();
6260 visitRecord(recType, fieldOffset);
6262 // If we have an array, replicate the first entry's layout information.
6263 auto numEltEntries = IvarsInfo.size() - oldEnd;
6264 if (numElts != 1 && numEltEntries != 0) {
6265 CharUnits eltSize = CGM.getContext().getTypeSizeInChars(recType);
6266 for (uint64_t eltIndex = 1; eltIndex != numElts; ++eltIndex) {
6267 // Copy the last numEltEntries onto the end of the array, adjusting
6268 // each for the element size.
6269 for (size_t i = 0; i != numEltEntries; ++i) {
6270 auto firstEntry = IvarsInfo[oldEnd + i];
6271 IvarsInfo.push_back(IvarInfo(firstEntry.Offset + eltIndex * eltSize,
6272 firstEntry.SizeInWords));
6280 // Classify the element type.
6281 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), fieldType);
6283 // If it matches what we're looking for, add an entry.
6284 if ((ForStrongLayout && GCAttr == Qualifiers::Strong) ||
6285 (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
6286 assert(CGM.getContext().getTypeSizeInChars(fieldType) ==
6287 CGM.getPointerSize());
6288 IvarsInfo.push_back(IvarInfo(fieldOffset, numElts));
6296IvarLayoutBuilder::buildBitmap(CGObjCCommonMac &CGObjC,
6297 llvm::SmallVectorImpl<unsigned char> &buffer) {
6298 // The bitmap is a series of skip/scan instructions, aligned to word
6299 // boundaries. The skip is performed first.
6300 const unsigned char MaxNibble = 0xF;
6301 const unsigned char SkipMask = 0xF0, SkipShift = 4;
6302 const unsigned char ScanMask = 0x0F, ScanShift = 0;
6304 assert(!IvarsInfo.empty() && "generating bitmap
for no data
");
6306 // Sort the ivar info on byte position in case we encounterred a
6307 // union nested in the ivar list.
6309 // This isn't a stable sort, but our algorithm should handle it fine.
6310 llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end());
6312 assert(llvm::is_sorted(IvarsInfo));
6314 assert(IvarsInfo.back().Offset < InstanceEnd);
6316 assert(buffer.empty());
6318 // Skip the next N words.
6319 auto skip = [&](unsigned numWords) {
6320 assert(numWords > 0);
6322 // Try to merge into the previous byte. Since scans happen second, we
6323 // can't do this if it includes a scan.
6324 if (!buffer.empty() && !(buffer.back() & ScanMask)) {
6325 unsigned lastSkip = buffer.back() >> SkipShift;
6326 if (lastSkip < MaxNibble) {
6327 unsigned claimed = std::min(MaxNibble - lastSkip, numWords);
6328 numWords -= claimed;
6329 lastSkip += claimed;
6330 buffer.back() = (lastSkip << SkipShift);
6334 while (numWords >= MaxNibble) {
6335 buffer.push_back(MaxNibble << SkipShift);
6336 numWords -= MaxNibble;
6339 buffer.push_back(numWords << SkipShift);
6343 // Scan the next N words.
6344 auto scan = [&](unsigned numWords) {
6345 assert(numWords > 0);
6347 // Try to merge into the previous byte. Since scans happen second, we can
6348 // do this even if it includes a skip.
6349 if (!buffer.empty()) {
6350 unsigned lastScan = (buffer.back() & ScanMask) >> ScanShift;
6351 if (lastScan < MaxNibble) {
6352 unsigned claimed = std::min(MaxNibble - lastScan, numWords);
6353 numWords -= claimed;
6354 lastScan += claimed;
6355 buffer.back() = (buffer.back() & SkipMask) | (lastScan << ScanShift);
6359 while (numWords >= MaxNibble) {
6360 buffer.push_back(MaxNibble << ScanShift);
6361 numWords -= MaxNibble;
6364 buffer.push_back(numWords << ScanShift);
6368 // One past the end of the last scan.
6369 unsigned endOfLastScanInWords = 0;
6370 const CharUnits WordSize = CGM.getPointerSize();
6372 // Consider all the scan requests.
6373 for (auto &request : IvarsInfo) {
6374 CharUnits beginOfScan = request.Offset - InstanceBegin;
6376 // Ignore scan requests that don't start at an even multiple of the
6377 // word size. We can't encode them.
6378 if (!beginOfScan.isMultipleOf(WordSize))
6381 // Ignore scan requests that start before the instance start.
6382 // This assumes that scans never span that boundary. The boundary
6383 // isn't the true start of the ivars, because in the fragile-ARC case
6384 // it's rounded up to word alignment, but the test above should leave
6385 // us ignoring that possibility.
6386 if (beginOfScan.isNegative()) {
6387 assert(request.Offset + request.SizeInWords * WordSize <= InstanceBegin);
6391 unsigned beginOfScanInWords = beginOfScan / WordSize;
6392 unsigned endOfScanInWords = beginOfScanInWords + request.SizeInWords;
6394 // If the scan starts some number of words after the last one ended,
6396 if (beginOfScanInWords > endOfLastScanInWords) {
6397 skip(beginOfScanInWords - endOfLastScanInWords);
6399 // Otherwise, start scanning where the last left off.
6401 beginOfScanInWords = endOfLastScanInWords;
6403 // If that leaves us with nothing to scan, ignore this request.
6404 if (beginOfScanInWords >= endOfScanInWords)
6408 // Scan to the end of the request.
6409 assert(beginOfScanInWords < endOfScanInWords);
6410 scan(endOfScanInWords - beginOfScanInWords);
6411 endOfLastScanInWords = endOfScanInWords;
6415 return llvm::ConstantPointerNull::get(CGM.Int8PtrTy);
6417 // For GC layouts, emit a skip to the end of the allocation so that we
6418 // have precise information about the entire thing. This isn't useful
6419 // or necessary for the ARC-style layout strings.
6420 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
6421 unsigned lastOffsetInWords =
6422 (InstanceEnd - InstanceBegin + WordSize - CharUnits::One()) / WordSize;
6423 if (lastOffsetInWords > endOfLastScanInWords) {
6424 skip(lastOffsetInWords - endOfLastScanInWords);
6428 // Null terminate the string.
6429 buffer.push_back(0);
6431 return CGObjC.CreateCStringLiteral(reinterpret_cast<char *>(buffer.data()),
6432 ObjCLabelType::LayoutBitMap);
6452CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD,
6453 CharUnits beginOffset, CharUnits endOffset,
6454 bool ForStrongLayout, bool HasMRCWeakIvars) {
6455 // If this is MRC, and we're either building a strong layout or there
6456 // are no weak ivars, bail out early.
6457 llvm::Type *PtrTy = CGM.Int8PtrTy;
6458 if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
6459 !CGM.getLangOpts().ObjCAutoRefCount &&
6460 (ForStrongLayout || !HasMRCWeakIvars))
6461 return llvm::Constant::getNullValue(PtrTy);
6463 const ObjCInterfaceDecl *OI = OMD->getClassInterface();
6464 SmallVector<const ObjCIvarDecl *, 32> ivars;
6466 // GC layout strings include the complete object layout, possibly
6467 // inaccurately in the non-fragile ABI; the runtime knows how to fix this
6470 // ARC layout strings only include the class's ivars. In non-fragile
6471 // runtimes, that means starting at InstanceStart, rounded up to word
6472 // alignment. In fragile runtimes, there's no InstanceStart, so it means
6473 // starting at the offset of the first ivar, rounded up to word alignment.
6475 // MRC weak layout strings follow the ARC style.
6476 CharUnits baseOffset;
6477 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
6478 for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin(); IVD;
6479 IVD = IVD->getNextIvar())
6480 ivars.push_back(IVD);
6482 if (isNonFragileABI()) {
6483 baseOffset = beginOffset; // InstanceStart
6484 } else if (!ivars.empty()) {
6486 CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivars[0]));
6488 baseOffset = CharUnits::Zero();
6491 baseOffset = baseOffset.alignTo(CGM.getPointerAlign());
6493 CGM.getContext().DeepCollectObjCIvars(OI, true, ivars);
6495 baseOffset = CharUnits::Zero();
6499 return llvm::Constant::getNullValue(PtrTy);
6501 IvarLayoutBuilder builder(CGM, baseOffset, endOffset, ForStrongLayout);
6503 builder.visitAggregate(ivars.begin(), ivars.end(), CharUnits::Zero(),
6504 [&](const ObjCIvarDecl *ivar) -> CharUnits {
6505 return CharUnits::fromQuantity(
6506 ComputeIvarBaseOffset(CGM, OMD, ivar));
6509 if (!builder.hasBitmapData())
6510 return llvm::Constant::getNullValue(PtrTy);
6512 llvm::SmallVector<unsigned char, 4> buffer;
6513 llvm::Constant *C = builder.buildBitmap(*this, buffer);
6515 if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
6516 printf("\n%s ivar layout
for class '%s':
",
6517 ForStrongLayout ? "strong
" : "weak
",
6518 OMD->getClassInterface()->getName().str().c_str());
6519 builder.dump(buffer);
6524llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
6525 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
6526 // FIXME: Avoid std::string in "Sel.
getAsString()
"
6529 CreateCStringLiteral(Sel.getAsString(), ObjCLabelType::MethodVarName);
6533// FIXME: Merge into a single cstring creation function.
6534llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
6535 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
6538llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
6539 std::string TypeStr;
6540 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
6542 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
6544 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType);
6548llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D,
6550 std::string TypeStr =
6551 CGM.getContext().getObjCEncodingForMethodDecl(D, Extended);
6553 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
6555 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType);
6559// FIXME: Merge into a single cstring creation function.
6560llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
6561 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
6563 Entry = CreateCStringLiteral(Ident->getName(), ObjCLabelType::PropertyName);
6567// FIXME: Merge into a single cstring creation function.
6568// FIXME: This Decl should be more precise.
6570CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
6571 const Decl *Container) {
6572 std::string TypeStr =
6573 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container);
6574 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
6577void CGObjCMac::FinishModule() {
6580 // Emit the dummy bodies for any protocols which were referenced but
6582 for (auto &entry : Protocols) {
6583 llvm::GlobalVariable *global = entry.second;
6584 if (global->hasInitializer())
6587 ConstantInitBuilder builder(CGM);
6588 auto values = builder.beginStruct(ObjCTypes.ProtocolTy);
6589 values.addNullPointer(ObjCTypes.ProtocolExtensionPtrTy);
6590 values.add(GetClassName(entry.first->getName()));
6591 values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
6592 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy);
6593 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy);
6594 values.finishAndSetAsInitializer(global);
6595 CGM.addCompilerUsedGlobal(global);
6598 // Add assembler directives to add lazy undefined symbol references
6599 // for classes which are referenced but not defined. This is
6600 // important for correct linker interaction.
6602 // FIXME: It would be nice if we had an LLVM construct for this.
6603 if ((!LazySymbols.empty() || !DefinedSymbols.empty()) &&
6604 CGM.getTriple().isOSBinFormatMachO()) {
6605 SmallString<256> Asm;
6606 llvm::raw_svector_ostream OS(Asm);
6607 for (const auto *Sym : DefinedSymbols)
6608 OS << "\t.objc_class_name_
" << Sym->getName() << "=0\n
"
6609 << "\t.globl .objc_class_name_
" << Sym->getName() << "\n
";
6610 for (const auto *Sym : LazySymbols)
6611 OS << "\t.lazy_reference .objc_class_name_
" << Sym->getName() << "\n
";
6612 for (const auto &Category : DefinedCategoryNames)
6613 OS << "\t.objc_category_name_
" << Category << "=0\n
"
6614 << "\t.globl .objc_category_name_
" << Category << "\n
";
6616 CGM.getModule().appendModuleInlineAsm(OS.str());
6620CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
6621 : CGObjCCommonMac(cgm), ObjCTypes(cgm), ObjCEmptyCacheVar(nullptr),
6622 ObjCEmptyVtableVar(nullptr) {
6628ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
6629 : VMContext(cgm.getLLVMContext()), CGM(cgm) {
6630 CodeGen::CodeGenTypes &Types = CGM.getTypes();
6631 ASTContext &Ctx = CGM.getContext();
6632 unsigned ProgramAS = CGM.getDataLayout().getProgramAddressSpace();
6634 ShortTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.ShortTy));
6636 LongTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.LongTy));
6637 Int8PtrTy = CGM.Int8PtrTy;
6638 Int8PtrProgramASTy = llvm::PointerType::get(CGM.getLLVMContext(), ProgramAS);
6639 Int8PtrPtrTy = CGM.Int8PtrPtrTy;
6641 // arm64 targets use "int" ivar offset variables. All others,
6642 // including OS X x86_64 and Windows x86_64, use "long" ivar offsets.
6643 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::aarch64)
6644 IvarOffsetVarTy = IntTy;
6646 IvarOffsetVarTy = LongTy;
6648 ObjectPtrTy = cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCIdType()));
6649 PtrObjectPtrTy = llvm::PointerType::getUnqual(VMContext);
6651 cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCSelType()));
6653 // I'm not sure I like this. The implicit coordination is a bit
6654 // gross. We should solve this in a reasonable fashion because this
6655 // is a pretty common task (match some runtime data structure with
6656 // an LLVM data structure).
6658 // FIXME: This is leaked.
6659 // FIXME: Merge with rewriter code?
6661 // struct _objc_super {
6665 RecordDecl *RD = RecordDecl::Create(
6666 Ctx, TagTypeKind::Struct, Ctx.getTranslationUnitDecl(), SourceLocation(),
6667 SourceLocation(), &Ctx.Idents.get("_objc_super
"));
6668 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
6669 nullptr, Ctx.getObjCIdType(), nullptr, nullptr,
6670 false, ICIS_NoInit));
6671 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
6672 nullptr, Ctx.getObjCClassType(), nullptr,
6673 nullptr, false, ICIS_NoInit));
6674 RD->completeDefinition();
6676 SuperCTy = Ctx.getCanonicalTagType(RD);
6677 SuperPtrCTy = Ctx.getPointerType(SuperCTy);
6679 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
6680 SuperPtrTy = llvm::PointerType::getUnqual(VMContext);
6684 // char *attributes;
6686 PropertyTy = llvm::StructType::create("struct._prop_t
", Int8PtrTy, Int8PtrTy);
6688 // struct _prop_list_t {
6689 // uint32_t entsize; // sizeof(struct _prop_t)
6690 // uint32_t count_of_properties;
6691 // struct _prop_t prop_list[count_of_properties];
6693 PropertyListTy = llvm::StructType::create(
6694 "struct._prop_list_t
", IntTy, IntTy, llvm::ArrayType::get(PropertyTy, 0));
6695 // struct _prop_list_t *
6696 PropertyListPtrTy = llvm::PointerType::getUnqual(VMContext);
6698 // struct _objc_method {
6700 // char *method_type;
6703 MethodTy = llvm::StructType::create("struct._objc_method
", SelectorPtrTy,
6704 Int8PtrTy, Int8PtrProgramASTy);
6706 // struct _objc_cache *
6707 CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache
");
6708 CachePtrTy = llvm::PointerType::getUnqual(VMContext);
6711ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
6712 : ObjCCommonTypesHelper(cgm) {
6713 // struct _objc_method_description {
6717 MethodDescriptionTy = llvm::StructType::create(
6718 "struct._objc_method_description
", SelectorPtrTy, Int8PtrTy);
6720 // struct _objc_method_description_list {
6722 // struct _objc_method_description[1];
6724 MethodDescriptionListTy =
6725 llvm::StructType::create("struct._objc_method_description_list
", IntTy,
6726 llvm::ArrayType::get(MethodDescriptionTy, 0));
6728 // struct _objc_method_description_list *
6729 MethodDescriptionListPtrTy = llvm::PointerType::getUnqual(VMContext);
6731 // Protocol description structures
6733 // struct _objc_protocol_extension {
6734 // uint32_t size; // sizeof(struct _objc_protocol_extension)
6735 // struct _objc_method_description_list *optional_instance_methods;
6736 // struct _objc_method_description_list *optional_class_methods;
6737 // struct _objc_property_list *instance_properties;
6738 // const char ** extendedMethodTypes;
6739 // struct _objc_property_list *class_properties;
6741 ProtocolExtensionTy = llvm::StructType::create(
6742 "struct._objc_protocol_extension
", IntTy, MethodDescriptionListPtrTy,
6743 MethodDescriptionListPtrTy, PropertyListPtrTy, Int8PtrPtrTy,
6746 // struct _objc_protocol_extension *
6747 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(VMContext);
6749 // Handle construction of Protocol and ProtocolList types
6751 // struct _objc_protocol {
6752 // struct _objc_protocol_extension *isa;
6753 // char *protocol_name;
6754 // struct _objc_protocol **_objc_protocol_list;
6755 // struct _objc_method_description_list *instance_methods;
6756 // struct _objc_method_description_list *class_methods;
6758 ProtocolTy = llvm::StructType::create(
6759 {ProtocolExtensionPtrTy, Int8PtrTy,
6760 llvm::PointerType::getUnqual(VMContext), MethodDescriptionListPtrTy,
6761 MethodDescriptionListPtrTy},
6762 "struct._objc_protocol
");
6765 llvm::StructType::create({llvm::PointerType::getUnqual(VMContext), LongTy,
6766 llvm::ArrayType::get(ProtocolTy, 0)},
6767 "struct._objc_protocol_list
");
6769 // struct _objc_protocol_list *
6770 ProtocolListPtrTy = llvm::PointerType::getUnqual(VMContext);
6772 ProtocolPtrTy = llvm::PointerType::getUnqual(VMContext);
6774 // Class description structures
6776 // struct _objc_ivar {
6781 IvarTy = llvm::StructType::create("struct._objc_ivar
", Int8PtrTy, Int8PtrTy,
6784 // struct _objc_ivar_list *
6785 IvarListTy = llvm::StructType::create(VMContext, "struct._objc_ivar_list
");
6786 IvarListPtrTy = llvm::PointerType::getUnqual(VMContext);
6788 // struct _objc_method_list *
6790 llvm::StructType::create(VMContext, "struct._objc_method_list
");
6791 MethodListPtrTy = llvm::PointerType::getUnqual(VMContext);
6793 // struct _objc_class_extension *
6794 ClassExtensionTy = llvm::StructType::create(
6795 "struct._objc_class_extension
", IntTy, Int8PtrTy, PropertyListPtrTy);
6796 ClassExtensionPtrTy = llvm::PointerType::getUnqual(VMContext);
6798 // struct _objc_class {
6800 // Class super_class;
6804 // long instance_size;
6805 // struct _objc_ivar_list *ivars;
6806 // struct _objc_method_list *methods;
6807 // struct _objc_cache *cache;
6808 // struct _objc_protocol_list *protocols;
6809 // char *ivar_layout;
6810 // struct _objc_class_ext *ext;
6812 ClassTy = llvm::StructType::create(
6813 {llvm::PointerType::getUnqual(VMContext),
6814 llvm::PointerType::getUnqual(VMContext), Int8PtrTy, LongTy, LongTy,
6815 LongTy, IvarListPtrTy, MethodListPtrTy, CachePtrTy, ProtocolListPtrTy,
6816 Int8PtrTy, ClassExtensionPtrTy},
6817 "struct._objc_class
");
6819 ClassPtrTy = llvm::PointerType::getUnqual(VMContext);
6821 // struct _objc_category {
6822 // char *category_name;
6823 // char *class_name;
6824 // struct _objc_method_list *instance_method;
6825 // struct _objc_method_list *class_method;
6826 // struct _objc_protocol_list *protocols;
6827 // uint32_t size; // sizeof(struct _objc_category)
6828 // struct _objc_property_list *instance_properties;// category's @property
6829 // struct _objc_property_list *class_properties;
6831 CategoryTy = llvm::StructType::create(
6832 "struct._objc_category
", Int8PtrTy, Int8PtrTy, MethodListPtrTy,
6833 MethodListPtrTy, ProtocolListPtrTy, IntTy, PropertyListPtrTy,
6836 // Global metadata structures
6838 // struct _objc_symtab {
6839 // long sel_ref_cnt;
6841 // short cls_def_cnt;
6842 // short cat_def_cnt;
6843 // char *defs[cls_def_cnt + cat_def_cnt];
6845 SymtabTy = llvm::StructType::create("struct._objc_symtab
", LongTy,
6846 SelectorPtrTy, ShortTy, ShortTy,
6847 llvm::ArrayType::get(Int8PtrTy, 0));
6848 SymtabPtrTy = llvm::PointerType::getUnqual(VMContext);
6850 // struct _objc_module {
6852 // long size; // sizeof(struct _objc_module)
6854 // struct _objc_symtab* symtab;
6856 ModuleTy = llvm::StructType::create("struct._objc_module
", LongTy, LongTy,
6857 Int8PtrTy, SymtabPtrTy);
6859 // FIXME: This is the size of the setjmp buffer and should be target
6860 // specific. 18 is what's used on 32-bit X86.
6861 uint64_t SetJmpBufferSize = 18;
6864 llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4);
6866 ExceptionDataTy = llvm::StructType::create(
6867 "struct._objc_exception_data
",
6868 llvm::ArrayType::get(CGM.Int32Ty, SetJmpBufferSize), StackPtrTy);
6871ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(
6872 CodeGen::CodeGenModule &cgm)
6873 : ObjCCommonTypesHelper(cgm) {
6874 // struct _method_list_t {
6875 // uint32_t entsize; // sizeof(struct _objc_method)
6876 // uint32_t method_count;
6877 // struct _objc_method method_list[method_count];
6880 llvm::StructType::create("struct.__method_list_t
", IntTy, IntTy,
6881 llvm::ArrayType::get(MethodTy, 0));
6882 // struct method_list_t *
6883 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6885 // struct _protocol_t {
6887 // const char * const protocol_name;
6888 // const struct _protocol_list_t * protocol_list; // super protocols
6889 // const struct method_list_t * const instance_methods;
6890 // const struct method_list_t * const class_methods;
6891 // const struct method_list_t *optionalInstanceMethods;
6892 // const struct method_list_t *optionalClassMethods;
6893 // const struct _prop_list_t * properties;
6894 // const uint32_t size; // sizeof(struct _protocol_t)
6895 // const uint32_t flags; // = 0
6896 // const char ** extendedMethodTypes;
6897 // const char *demangledName;
6898 // const struct _prop_list_t * class_properties;
6901 ProtocolnfABITy = llvm::StructType::create(
6902 "struct._protocol_t
", ObjectPtrTy, Int8PtrTy,
6903 llvm::PointerType::getUnqual(VMContext), MethodListnfABIPtrTy,
6904 MethodListnfABIPtrTy, MethodListnfABIPtrTy, MethodListnfABIPtrTy,
6905 PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy, Int8PtrTy,
6908 // struct _protocol_t*
6909 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6911 // struct _protocol_list_t {
6912 // long protocol_count; // Note, this is 32/64 bit
6913 // struct _protocol_t *[protocol_count];
6915 ProtocolListnfABITy = llvm::StructType::create(
6916 {LongTy, llvm::ArrayType::get(ProtocolnfABIPtrTy, 0)},
6917 "struct._objc_protocol_list
");
6919 // struct _objc_protocol_list*
6920 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6923 // unsigned [long] int *offset; // pointer to ivar offset location
6926 // uint32_t alignment;
6929 IvarnfABITy = llvm::StructType::create(
6930 "struct._ivar_t
", llvm::PointerType::getUnqual(VMContext), Int8PtrTy,
6931 Int8PtrTy, IntTy, IntTy);
6933 // struct _ivar_list_t {
6934 // uint32 entsize; // sizeof(struct _ivar_t)
6936 // struct _iver_t list[count];
6939 llvm::StructType::create("struct._ivar_list_t
", IntTy, IntTy,
6940 llvm::ArrayType::get(IvarnfABITy, 0));
6942 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6944 // struct _class_ro_t {
6945 // uint32_t const flags;
6946 // uint32_t const instanceStart;
6947 // uint32_t const instanceSize;
6948 // uint32_t const reserved; // only when building for 64bit targets
6949 // const uint8_t * const ivarLayout;
6950 // const char *const name;
6951 // const struct _method_list_t * const baseMethods;
6952 // const struct _objc_protocol_list *const baseProtocols;
6953 // const struct _ivar_list_t *const ivars;
6954 // const uint8_t * const weakIvarLayout;
6955 // const struct _prop_list_t * const properties;
6958 // FIXME. Add 'reserved' field in 64bit abi mode!
6959 ClassRonfABITy = llvm::StructType::create(
6960 "struct._class_ro_t
", IntTy, IntTy, IntTy, Int8PtrTy, Int8PtrTy,
6961 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, IvarListnfABIPtrTy,
6962 Int8PtrTy, PropertyListPtrTy);
6964 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
6965 ImpnfABITy = CGM.DefaultPtrTy;
6967 // struct _class_t {
6968 // struct _class_t *isa;
6969 // struct _class_t * const superclass;
6972 // struct class_ro_t *ro;
6975 ClassnfABITy = llvm::StructType::create(
6976 {llvm::PointerType::getUnqual(VMContext),
6977 llvm::PointerType::getUnqual(VMContext), CachePtrTy,
6978 llvm::PointerType::getUnqual(VMContext),
6979 llvm::PointerType::getUnqual(VMContext)},
6982 // LLVM for struct _class_t *
6983 ClassnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6985 // struct _category_t {
6986 // const char * const name;
6987 // struct _class_t *const cls;
6988 // const struct _method_list_t * const instance_methods;
6989 // const struct _method_list_t * const class_methods;
6990 // const struct _protocol_list_t * const protocols;
6991 // const struct _prop_list_t * const properties;
6992 // const struct _prop_list_t * const class_properties;
6993 // const uint32_t size;
6995 CategorynfABITy = llvm::StructType::create(
6996 "struct._category_t
", Int8PtrTy, ClassnfABIPtrTy, MethodListnfABIPtrTy,
6997 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, PropertyListPtrTy,
6998 PropertyListPtrTy, IntTy);
7000 // New types for nonfragile abi messaging.
7001 CodeGen::CodeGenTypes &Types = CGM.getTypes();
7002 ASTContext &Ctx = CGM.getContext();
7004 // MessageRefTy - LLVM for:
7005 // struct _message_ref_t {
7010 // First the clang type for struct _message_ref_t
7011 RecordDecl *RD = RecordDecl::Create(
7012 Ctx, TagTypeKind::Struct, Ctx.getTranslationUnitDecl(), SourceLocation(),
7013 SourceLocation(), &Ctx.Idents.get("_message_ref_t
"));
7014 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
7015 nullptr, Ctx.VoidPtrTy, nullptr, nullptr, false,
7017 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
7018 nullptr, Ctx.getObjCSelType(), nullptr, nullptr,
7019 false, ICIS_NoInit));
7020 RD->completeDefinition();
7022 MessageRefCTy = Ctx.getCanonicalTagType(RD);
7023 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy);
7024 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy));
7026 // MessageRefPtrTy - LLVM for struct _message_ref_t*
7027 MessageRefPtrTy = llvm::PointerType::getUnqual(VMContext);
7029 // SuperMessageRefTy - LLVM for:
7030 // struct _super_message_ref_t {
7031 // SUPER_IMP messenger;
7034 SuperMessageRefTy = llvm::StructType::create("struct._super_message_ref_t
",
7035 ImpnfABITy, SelectorPtrTy);
7037 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
7038 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(VMContext);
7040 // struct objc_typeinfo {
7041 // const void** vtable; // objc_ehtype_vtable + 2
7042 // const char* name; // c++ typeinfo string
7045 EHTypeTy = llvm::StructType::create("struct._objc_typeinfo
",
7046 llvm::PointerType::getUnqual(VMContext),
7047 Int8PtrTy, ClassnfABIPtrTy);
7048 EHTypePtrTy = llvm::PointerType::getUnqual(VMContext);
7051llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
7052 FinishNonFragileABIModule();
7057void CGObjCNonFragileABIMac::AddModuleClassList(
7058 ArrayRef<llvm::GlobalValue *> Container, StringRef SymbolName,
7059 StringRef SectionName) {
7060 unsigned NumClasses = Container.size();
7065 SmallVector<llvm::Constant *, 8> Symbols(NumClasses);
7066 for (unsigned i = 0; i < NumClasses; i++)
7067 Symbols[i] = Container[i];
7069 llvm::Constant *Init = llvm::ConstantArray::get(
7070 llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Symbols.size()), Symbols);
7072 // Section name is obtained by calling GetSectionName, which returns
7073 // sections in the __DATA segment on MachO.
7074 assert((!CGM.getTriple().isOSBinFormatMachO() ||
7075 SectionName.starts_with("__DATA
")) &&
7076 "SectionName expected to start with __DATA on
MachO");
7077 llvm::GlobalVariable *GV = new llvm::GlobalVariable(
7078 CGM.getModule(), Init->getType(), false,
7079 llvm::GlobalValue::PrivateLinkage, Init, SymbolName);
7080 GV->setAlignment(CGM.getDataLayout().getABITypeAlign(Init->getType()));
7081 GV->setSection(SectionName);
7082 CGM.addCompilerUsedGlobal(GV);
7085void CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
7086 // nonfragile abi has no module definition.
7088 // Build list of all implemented class addresses in array
7089 // L_OBJC_LABEL_CLASS_$.
7091 for (unsigned i = 0, NumClasses = ImplementedClasses.size(); i < NumClasses;
7093 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
7095 if (ObjCImplementationDecl *IMP = ID->getImplementation())
7096 // We are implementing a weak imported interface. Give it external linkage
7097 if (ID->isWeakImported() && !IMP->isWeakImported()) {
7098 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
7099 DefinedMetaClasses[i]->setLinkage(
7100 llvm::GlobalVariable::ExternalLinkage);
7105 DefinedClasses, "OBJC_LABEL_CLASS_$
",
7106 GetSectionName("__objc_classlist
", "regular,no_dead_strip
"));
7109 DefinedNonLazyClasses, "OBJC_LABEL_NONLAZY_CLASS_$
",
7110 GetSectionName("__objc_nlclslist
", "regular,no_dead_strip
"));
7112 // Build list of all implemented category addresses in array
7113 // L_OBJC_LABEL_CATEGORY_$.
7114 AddModuleClassList(DefinedCategories, "OBJC_LABEL_CATEGORY_$
",
7115 GetSectionName("__objc_catlist
", "regular,no_dead_strip
"));
7117 DefinedStubCategories, "OBJC_LABEL_STUB_CATEGORY_$
",
7118 GetSectionName("__objc_catlist2
", "regular,no_dead_strip
"));
7120 DefinedNonLazyCategories, "OBJC_LABEL_NONLAZY_CATEGORY_$
",
7121 GetSectionName("__objc_nlcatlist
", "regular,no_dead_strip
"));
7130bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
7131 // At various points we've experimented with using vtable-based
7132 // dispatch for all methods.
7133 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
7134 case CodeGenOptions::Legacy:
7136 case CodeGenOptions::NonLegacy:
7138 case CodeGenOptions::Mixed:
7142 // If so, see whether this selector is in the white-list of things which must
7143 // use the new dispatch convention. We lazily build a dense set for this.
7144 if (VTableDispatchMethods.empty()) {
7145 VTableDispatchMethods.insert(GetNullarySelector("alloc
"));
7146 VTableDispatchMethods.insert(GetNullarySelector("class"));
7147 VTableDispatchMethods.insert(GetNullarySelector("self
"));
7148 VTableDispatchMethods.insert(GetNullarySelector("isFlipped
"));
7149 VTableDispatchMethods.insert(GetNullarySelector("length"));
7150 VTableDispatchMethods.insert(GetNullarySelector("count
"));
7152 // These are vtable-based if GC is disabled.
7153 // Optimistically use vtable dispatch for hybrid compiles.
7154 if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) {
7155 VTableDispatchMethods.insert(GetNullarySelector("retain
"));
7156 VTableDispatchMethods.insert(GetNullarySelector("release
"));
7157 VTableDispatchMethods.insert(GetNullarySelector("autorelease
"));
7160 VTableDispatchMethods.insert(GetUnarySelector("allocWithZone
"));
7161 VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass
"));
7162 VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector
"));
7163 VTableDispatchMethods.insert(GetUnarySelector("objectForKey
"));
7164 VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex
"));
7165 VTableDispatchMethods.insert(GetUnarySelector("isEqualToString
"));
7166 VTableDispatchMethods.insert(GetUnarySelector("isEqual
"));
7168 // These are vtable-based if GC is enabled.
7169 // Optimistically use vtable dispatch for hybrid compiles.
7170 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
7171 VTableDispatchMethods.insert(GetNullarySelector("hash
"));
7172 VTableDispatchMethods.insert(GetUnarySelector("addObject
"));
7174 // "countByEnumeratingWithState:objects:count
"
7175 const IdentifierInfo *KeyIdents[] = {
7176 &CGM.getContext().Idents.get("countByEnumeratingWithState
"),
7177 &CGM.getContext().Idents.get("objects
"),
7178 &CGM.getContext().Idents.get("count
")};
7179 VTableDispatchMethods.insert(
7180 CGM.getContext().Selectors.getSelector(3, KeyIdents));
7184 return VTableDispatchMethods.count(Sel);
7202llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassRoTInitializer(
7203 unsigned flags, unsigned InstanceStart, unsigned InstanceSize,
7204 const ObjCImplementationDecl *ID) {
7205 std::string ClassName = std::string(ID->getObjCRuntimeNameAsString());
7207 CharUnits beginInstance = CharUnits::fromQuantity(InstanceStart);
7208 CharUnits endInstance = CharUnits::fromQuantity(InstanceSize);
7210 bool hasMRCWeak = false;
7211 if (CGM.getLangOpts().ObjCAutoRefCount)
7212 flags |= NonFragileABI_Class_CompiledByARC;
7213 else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))
7214 flags |= NonFragileABI_Class_HasMRCWeakIvars;
7216 ConstantInitBuilder builder(CGM);
7217 auto values = builder.beginStruct(ObjCTypes.ClassRonfABITy);
7219 values.addInt(ObjCTypes.IntTy, flags);
7220 values.addInt(ObjCTypes.IntTy, InstanceStart);
7221 values.addInt(ObjCTypes.IntTy, InstanceSize);
7222 values.add((flags & NonFragileABI_Class_Meta)
7223 ? GetIvarLayoutName(nullptr, ObjCTypes)
7224 : BuildStrongIvarLayout(ID, beginInstance, endInstance));
7225 values.add(GetClassName(ID->getObjCRuntimeNameAsString()));
7227 // const struct _method_list_t * const baseMethods;
7228 SmallVector<const ObjCMethodDecl *, 16> methods;
7229 if (flags & NonFragileABI_Class_Meta) {
7230 for (const auto *MD : ID->class_methods())
7231 if (!MD->isDirectMethod())
7232 methods.push_back(MD);
7234 for (const auto *MD : ID->instance_methods())
7235 if (!MD->isDirectMethod())
7236 methods.push_back(MD);
7239 llvm::Constant *MethListPtr = emitMethodList(
7240 ID->getObjCRuntimeNameAsString(),
7241 (flags & NonFragileABI_Class_Meta) ? MethodListType::ClassMethods
7242 : MethodListType::InstanceMethods,
7245 const PointerAuthSchema &MethListSchema =
7246 CGM.getCodeGenOpts().PointerAuth.ObjCMethodListPointer;
7247 if (!MethListPtr->isNullValue())
7248 values.addSignedPointer(MethListPtr, MethListSchema, GlobalDecl(),
7251 values.add(MethListPtr);
7253 const ObjCInterfaceDecl *OID = ID->getClassInterface();
7254 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer
");
7255 values.add(EmitProtocolList("_OBJC_CLASS_PROTOCOLS_$_
" +
7256 OID->getObjCRuntimeNameAsString(),
7257 OID->all_referenced_protocol_begin(),
7258 OID->all_referenced_protocol_end()));
7260 if (flags & NonFragileABI_Class_Meta) {
7261 values.addNullPointer(ObjCTypes.IvarListnfABIPtrTy);
7262 values.add(GetIvarLayoutName(nullptr, ObjCTypes));
7263 values.add(EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_
" +
7264 ID->getObjCRuntimeNameAsString(),
7265 ID, ID->getClassInterface(), ObjCTypes, true));
7267 values.add(EmitIvarList(ID));
7268 values.add(BuildWeakIvarLayout(ID, beginInstance, endInstance, hasMRCWeak));
7269 values.add(EmitPropertyList("_OBJC_$_PROP_LIST_
" +
7270 ID->getObjCRuntimeNameAsString(),
7271 ID, ID->getClassInterface(), ObjCTypes, false));
7274 llvm::SmallString<64> roLabel;
7275 llvm::raw_svector_ostream(roLabel)
7276 << ((flags & NonFragileABI_Class_Meta) ? "_OBJC_METACLASS_RO_$_
"
7277 : "_OBJC_CLASS_RO_$_
")
7280 return finishAndCreateGlobal(values, roLabel, CGM);
7293llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassObject(
7294 const ObjCInterfaceDecl *CI, bool isMetaclass, llvm::Constant *IsAGV,
7295 llvm::Constant *SuperClassGV, llvm::Constant *ClassRoGV,
7296 bool HiddenVisibility) {
7297 ConstantInitBuilder builder(CGM);
7298 auto values = builder.beginStruct(ObjCTypes.ClassnfABITy);
7299 const PointerAuthOptions &PointerAuthOpts = CGM.getCodeGenOpts().PointerAuth;
7300 values.addSignedPointer(IsAGV, PointerAuthOpts.ObjCIsaPointers, GlobalDecl(),
7303 values.addSignedPointer(SuperClassGV, PointerAuthOpts.ObjCSuperPointers,
7304 GlobalDecl(), QualType());
7306 values.addNullPointer(ObjCTypes.ClassnfABIPtrTy);
7308 values.add(ObjCEmptyCacheVar);
7309 values.add(ObjCEmptyVtableVar);
7311 values.addSignedPointer(ClassRoGV, PointerAuthOpts.ObjCClassROPointers,
7312 GlobalDecl(), QualType());
7314 llvm::GlobalVariable *GV = cast<llvm::GlobalVariable>(
7315 GetClassGlobal(CI, isMetaclass, ForDefinition));
7316 values.finishAndSetAsInitializer(GV);
7318 if (CGM.getTriple().isOSBinFormatMachO())
7319 GV->setSection("__DATA, __objc_data
");
7320 GV->setAlignment(CGM.getDataLayout().getABITypeAlign(ObjCTypes.ClassnfABITy));
7321 if (!CGM.getTriple().isOSBinFormatCOFF())
7322 if (HiddenVisibility)
7323 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
7324 if (CGM.getCodeGenOpts().ObjCMsgSendClassSelectorStubs && !isMetaclass)
7325 CGM.addUsedGlobal(GV);
7329bool CGObjCNonFragileABIMac::ImplementationIsNonLazy(
7330 const ObjCImplDecl *OD) const {
7331 return OD->getClassMethod(GetNullarySelector("load
")) != nullptr ||
7332 OD->getClassInterface()->hasAttr<ObjCNonLazyClassAttr>() ||
7333 OD->hasAttr<ObjCNonLazyClassAttr>();
7336void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
7337 uint32_t &InstanceStart,
7338 uint32_t &InstanceSize) {
7339 const ASTRecordLayout &RL =
7340 CGM.getContext().getASTObjCInterfaceLayout(OID->getClassInterface());
7342 // InstanceSize is really instance end.
7343 InstanceSize = RL.getDataSize().getQuantity();
7345 // If there are no fields, the start is the same as the end.
7346 if (!RL.getFieldCount())
7347 InstanceStart = InstanceSize;
7349 InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth();
7352static llvm::GlobalValue::DLLStorageClassTypes getStorage(CodeGenModule &CGM,
7354 IdentifierInfo &II = CGM.getContext().Idents.get(Name);
7355 TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl();
7356 DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl);
7358 const VarDecl *VD = nullptr;
7359 for (const auto *Result : DC->lookup(&II))
7360 if ((VD = dyn_cast<VarDecl>(Result)))
7364 return llvm::GlobalValue::DLLImportStorageClass;
7365 if (VD->hasAttr<DLLExportAttr>())
7366 return llvm::GlobalValue::DLLExportStorageClass;
7367 if (VD->hasAttr<DLLImportAttr>())
7368 return llvm::GlobalValue::DLLImportStorageClass;
7369 return llvm::GlobalValue::DefaultStorageClass;
7372void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
7373 if (!ObjCEmptyCacheVar) {
7374 ObjCEmptyCacheVar = new llvm::GlobalVariable(
7375 CGM.getModule(), ObjCTypes.CacheTy, false,
7376 llvm::GlobalValue::ExternalLinkage, nullptr, "_objc_empty_cache
");
7377 if (CGM.getTriple().isOSBinFormatCOFF())
7378 ObjCEmptyCacheVar->setDLLStorageClass(
7379 getStorage(CGM, "_objc_empty_cache
"));
7381 // Only OS X with deployment version <10.9 use the empty vtable symbol
7382 const llvm::Triple &Triple = CGM.getTarget().getTriple();
7383 if (Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 9))
7384 ObjCEmptyVtableVar = new llvm::GlobalVariable(
7385 CGM.getModule(), ObjCTypes.ImpnfABITy, false,
7386 llvm::GlobalValue::ExternalLinkage, nullptr, "_objc_empty_vtable
");
7388 ObjCEmptyVtableVar = llvm::ConstantPointerNull::get(CGM.DefaultPtrTy);
7391 // FIXME: Is this correct (that meta class size is never computed)?
7392 uint32_t InstanceStart =
7393 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy);
7394 uint32_t InstanceSize = InstanceStart;
7395 uint32_t flags = NonFragileABI_Class_Meta;
7397 llvm::Constant *SuperClassGV, *IsAGV;
7399 const auto *CI = ID->getClassInterface();
7400 assert(CI && "CGObjCNonFragileABIMac::GenerateClass -
class is 0
");
7402 // Build the flags for the metaclass.
7403 bool classIsHidden = (CGM.getTriple().isOSBinFormatCOFF())
7404 ? !CI->hasAttr<DLLExportAttr>()
7405 : CI->getVisibility() == HiddenVisibility;
7407 flags |= NonFragileABI_Class_Hidden;
7409 // FIXME: why is this flag set on the metaclass?
7410 // ObjC metaclasses have no fields and don't really get constructed.
7411 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
7412 flags |= NonFragileABI_Class_HasCXXStructors;
7413 if (!ID->hasNonZeroConstructors())
7414 flags |= NonFragileABI_Class_HasCXXDestructorOnly;
7417 if (!CI->getSuperClass()) {
7419 flags |= NonFragileABI_Class_Root;
7421 SuperClassGV = GetClassGlobal(CI, /*metaclass*/ false, NotForDefinition);
7422 IsAGV = GetClassGlobal(CI, /*metaclass*/ true, NotForDefinition);
7424 // Has a root. Current class is not a root.
7425 const ObjCInterfaceDecl *Root = ID->getClassInterface();
7426 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
7429 const auto *Super = CI->getSuperClass();
7430 IsAGV = GetClassGlobal(Root, /*metaclass*/ true, NotForDefinition);
7431 SuperClassGV = GetClassGlobal(Super, /*metaclass*/ true, NotForDefinition);
7434 llvm::GlobalVariable *CLASS_RO_GV =
7435 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
7437 llvm::GlobalVariable *MetaTClass = BuildClassObject(
7438 CI, /*metaclass*/ true, IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden);
7439 CGM.setGVProperties(MetaTClass, CI);
7440 DefinedMetaClasses.push_back(MetaTClass);
7442 // Metadata for the class
7445 flags |= NonFragileABI_Class_Hidden;
7447 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
7448 flags |= NonFragileABI_Class_HasCXXStructors;
7450 // Set a flag to enable a runtime optimization when a class has
7451 // fields that require destruction but which don't require
7452 // anything except zero-initialization during construction. This
7453 // is most notably true of __strong and __weak types, but you can
7454 // also imagine there being C++ types with non-trivial default
7455 // constructors that merely set all fields to null.
7456 if (!ID->hasNonZeroConstructors())
7457 flags |= NonFragileABI_Class_HasCXXDestructorOnly;
7460 if (hasObjCExceptionAttribute(CGM.getContext(), CI))
7461 flags |= NonFragileABI_Class_Exception;
7463 if (!CI->getSuperClass()) {
7464 flags |= NonFragileABI_Class_Root;
7465 SuperClassGV = nullptr;
7467 // Has a root. Current class is not a root.
7468 const auto *Super = CI->getSuperClass();
7469 SuperClassGV = GetClassGlobal(Super, /*metaclass*/ false, NotForDefinition);
7472 GetClassSizeInfo(ID, InstanceStart, InstanceSize);
7474 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
7476 llvm::GlobalVariable *ClassMD =
7477 BuildClassObject(CI, /*metaclass*/ false, MetaTClass, SuperClassGV,
7478 CLASS_RO_GV, classIsHidden);
7479 CGM.setGVProperties(ClassMD, CI);
7480 DefinedClasses.push_back(ClassMD);
7481 ImplementedClasses.push_back(CI);
7483 // Determine if this class is also "non-lazy
".
7484 if (ImplementationIsNonLazy(ID))
7485 DefinedNonLazyClasses.push_back(ClassMD);
7487 // Force the definition of the EHType if necessary.
7488 if (flags & NonFragileABI_Class_Exception)
7489 (void)GetInterfaceEHType(CI, ForDefinition);
7490 // Make sure method definition entries are all clear for next implementation.
7491 MethodDefinitions.clear();
7503CGObjCNonFragileABIMac::GenerateProtocolRef(CodeGenFunction &CGF,
7504 const ObjCProtocolDecl *PD) {
7506 // This routine is called for @protocol only. So, we must build definition
7507 // of protocol's meta-data (not a reference to it!)
7508 assert(!PD->isNonRuntimeProtocol() &&
7509 "attempting to get a protocol ref to a
static protocol.
");
7510 llvm::Constant *Init = GetOrEmitProtocol(PD);
7512 std::string ProtocolName("_OBJC_PROTOCOL_REFERENCE_$_
");
7513 ProtocolName += PD->getObjCRuntimeNameAsString();
7515 CharUnits Align = CGF.getPointerAlign();
7517 llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);
7519 return CGF.Builder.CreateAlignedLoad(PTGV->getValueType(), PTGV, Align);
7520 PTGV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
7521 llvm::GlobalValue::WeakAnyLinkage, Init,
7524 GetSectionName("__objc_protorefs
", "coalesced,no_dead_strip
"));
7525 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
7526 PTGV->setAlignment(Align.getAsAlign());
7527 if (!CGM.getTriple().isOSBinFormatMachO())
7528 PTGV->setComdat(CGM.getModule().getOrInsertComdat(ProtocolName));
7529 CGM.addUsedGlobal(PTGV);
7530 return CGF.Builder.CreateAlignedLoad(PTGV->getValueType(), PTGV, Align);
7545void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
7546 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
7547 const char *Prefix = "_OBJC_$_CATEGORY_
";
7549 llvm::SmallString<64> ExtCatName(Prefix);
7550 ExtCatName += Interface->getObjCRuntimeNameAsString();
7551 ExtCatName += "_$_
";
7552 ExtCatName += OCD->getNameAsString();
7554 ConstantInitBuilder builder(CGM);
7555 auto values = builder.beginStruct(ObjCTypes.CategorynfABITy);
7556 values.add(GetClassName(OCD->getIdentifier()->getName()));
7557 // meta-class entry symbol
7558 values.add(GetClassGlobal(Interface, /*metaclass*/ false, NotForDefinition));
7559 std::string listName =
7560 (Interface->getObjCRuntimeNameAsString() + "_$_
" + OCD->getName()).str();
7562 SmallVector<const ObjCMethodDecl *, 16> instanceMethods;
7563 SmallVector<const ObjCMethodDecl *, 8> classMethods;
7564 for (const auto *MD : OCD->methods()) {
7565 if (MD->isDirectMethod())
7567 if (MD->isInstanceMethod()) {
7568 instanceMethods.push_back(MD);
7570 classMethods.push_back(MD);
7574 llvm::Constant *InstanceMethodList = emitMethodList(
7575 listName, MethodListType::CategoryInstanceMethods, instanceMethods);
7576 const PointerAuthSchema &MethListSchema =
7577 CGM.getCodeGenOpts().PointerAuth.ObjCMethodListPointer;
7578 if (!InstanceMethodList->isNullValue())
7579 values.addSignedPointer(InstanceMethodList, MethListSchema, GlobalDecl(),
7582 values.add(InstanceMethodList);
7584 llvm::Constant *ClassMethodList = emitMethodList(
7585 listName, MethodListType::CategoryClassMethods, classMethods);
7586 if (!ClassMethodList->isNullValue())
7587 values.addSignedPointer(ClassMethodList, MethListSchema, GlobalDecl(),
7590 values.add(ClassMethodList);
7592 // Keep track of whether we have actual metadata to emit.
7593 bool isEmptyCategory =
7594 InstanceMethodList->isNullValue() && ClassMethodList->isNullValue();
7596 const ObjCCategoryDecl *Category =
7597 Interface->FindCategoryDeclaration(OCD->getIdentifier());
7599 SmallString<256> ExtName;
7600 llvm::raw_svector_ostream(ExtName)
7601 << Interface->getObjCRuntimeNameAsString() << "_$_
" << OCD->getName();
7603 EmitProtocolList("_OBJC_CATEGORY_PROTOCOLS_$_
" +
7604 Interface->getObjCRuntimeNameAsString() + "_$_
" +
7605 Category->getName(),
7606 Category->protocol_begin(), Category->protocol_end());
7607 auto propertyList = EmitPropertyList("_OBJC_$_PROP_LIST_
" + ExtName.str(),
7608 OCD, Category, ObjCTypes, false);
7609 auto classPropertyList =
7610 EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_
" + ExtName.str(), OCD,
7611 Category, ObjCTypes, true);
7612 values.add(protocolList);
7613 values.add(propertyList);
7614 values.add(classPropertyList);
7615 isEmptyCategory &= protocolList->isNullValue() &&
7616 propertyList->isNullValue() &&
7617 classPropertyList->isNullValue();
7619 values.addNullPointer(ObjCTypes.ProtocolListnfABIPtrTy);
7620 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
7621 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
7624 if (isEmptyCategory) {
7625 // Empty category, don't emit any metadata.
7627 MethodDefinitions.clear();
7632 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.CategorynfABITy);
7633 values.addInt(ObjCTypes.IntTy, Size);
7635 llvm::GlobalVariable *GCATV =
7636 finishAndCreateGlobal(values, ExtCatName.str(), CGM);
7637 CGM.addCompilerUsedGlobal(GCATV);
7638 if (Interface->hasAttr<ObjCClassStubAttr>())
7639 DefinedStubCategories.push_back(GCATV);
7641 DefinedCategories.push_back(GCATV);
7643 // Determine if this category is also "non-lazy
".
7644 if (ImplementationIsNonLazy(OCD))
7645 DefinedNonLazyCategories.push_back(GCATV);
7646 // method definition entries must be clear for next implementation.
7647 MethodDefinitions.clear();
7659void CGObjCNonFragileABIMac::emitMethodConstant(ConstantArrayBuilder &builder,
7660 const ObjCMethodDecl *MD,
7662 auto method = builder.beginStruct(ObjCTypes.MethodTy);
7663 method.add(GetMethodVarName(MD->getSelector()));
7664 method.add(GetMethodVarType(MD));
7667 // Protocol methods have no implementation. So, this entry is always NULL.
7668 method.addNullPointer(ObjCTypes.Int8PtrProgramASTy);
7670 llvm::Function *fn = GetMethodDefinition(MD);
7671 assert(fn && "no definition
for method?
");
7672 if (const PointerAuthSchema &Schema =
7673 CGM.getCodeGenOpts().PointerAuth.ObjCMethodListFunctionPointers) {
7674 llvm::Constant *Bitcast =
7675 llvm::ConstantExpr::getBitCast(fn, ObjCTypes.Int8PtrProgramASTy);
7676 method.addSignedPointer(Bitcast, Schema, GlobalDecl(), QualType());
7681 method.finishAndAddTo(builder);
7692llvm::Constant *CGObjCNonFragileABIMac::emitMethodList(
7693 Twine name, MethodListType kind, ArrayRef<const ObjCMethodDecl *> methods) {
7694 // Return null for empty list.
7695 if (methods.empty())
7696 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
7701 case MethodListType::CategoryInstanceMethods:
7702 prefix = "_OBJC_$_CATEGORY_INSTANCE_METHODS_
";
7703 forProtocol = false;
7705 case MethodListType::CategoryClassMethods:
7706 prefix = "_OBJC_$_CATEGORY_CLASS_METHODS_
";
7707 forProtocol = false;
7709 case MethodListType::InstanceMethods:
7710 prefix = "_OBJC_$_INSTANCE_METHODS_
";
7711 forProtocol = false;
7713 case MethodListType::ClassMethods:
7714 prefix = "_OBJC_$_CLASS_METHODS_
";
7715 forProtocol = false;
7718 case MethodListType::ProtocolInstanceMethods:
7719 prefix = "_OBJC_$_PROTOCOL_INSTANCE_METHODS_
";
7722 case MethodListType::ProtocolClassMethods:
7723 prefix = "_OBJC_$_PROTOCOL_CLASS_METHODS_
";
7726 case MethodListType::OptionalProtocolInstanceMethods:
7727 prefix = "_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_
";
7730 case MethodListType::OptionalProtocolClassMethods:
7731 prefix = "_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_
";
7736 ConstantInitBuilder builder(CGM);
7737 auto values = builder.beginStruct();
7739 // sizeof(struct _objc_method)
7740 unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.MethodTy);
7741 values.addInt(ObjCTypes.IntTy, Size);
7743 values.addInt(ObjCTypes.IntTy, methods.size());
7744 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
7745 for (auto MD : methods)
7746 emitMethodConstant(methodArray, MD, forProtocol);
7747 methodArray.finishAndAddTo(values);
7749 llvm::GlobalVariable *GV = finishAndCreateGlobal(values, prefix + name, CGM);
7750 CGM.addCompilerUsedGlobal(GV);
7756llvm::GlobalVariable *
7757CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
7758 const ObjCIvarDecl *Ivar) {
7759 const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
7760 llvm::SmallString<64> Name("OBJC_IVAR_$_
");
7761 Name += Container->getObjCRuntimeNameAsString();
7763 Name += Ivar->getName();
7764 llvm::GlobalVariable *IvarOffsetGV = CGM.getModule().getGlobalVariable(Name);
7765 if (!IvarOffsetGV) {
7766 IvarOffsetGV = new llvm::GlobalVariable(
7767 CGM.getModule(), ObjCTypes.IvarOffsetVarTy, false,
7768 llvm::GlobalValue::ExternalLinkage, nullptr, Name.str());
7769 if (CGM.getTriple().isOSBinFormatCOFF()) {
7770 bool IsPrivateOrPackage =
7771 Ivar->getAccessControl() == ObjCIvarDecl::Private ||
7772 Ivar->getAccessControl() == ObjCIvarDecl::Package;
7774 const ObjCInterfaceDecl *ContainingID = Ivar->getContainingInterface();
7776 if (ContainingID->hasAttr<DLLImportAttr>())
7777 IvarOffsetGV->setDLLStorageClass(
7778 llvm::GlobalValue::DLLImportStorageClass);
7779 else if (ContainingID->hasAttr<DLLExportAttr>() && !IsPrivateOrPackage)
7780 IvarOffsetGV->setDLLStorageClass(
7781 llvm::GlobalValue::DLLExportStorageClass);
7784 return IvarOffsetGV;
7788CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
7789 const ObjCIvarDecl *Ivar,
7790 unsigned long int Offset) {
7791 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
7792 IvarOffsetGV->setInitializer(
7793 llvm::ConstantInt::get(ObjCTypes.IvarOffsetVarTy, Offset));
7794 IvarOffsetGV->setAlignment(
7795 CGM.getDataLayout().getABITypeAlign(ObjCTypes.IvarOffsetVarTy));
7797 if (!CGM.getTriple().isOSBinFormatCOFF()) {
7798 // FIXME: This matches gcc, but shouldn't the visibility be set on the use
7799 // as well (i.e., in ObjCIvarOffsetVariable).
7800 if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
7801 Ivar->getAccessControl() == ObjCIvarDecl::Package ||
7802 ID->getVisibility() == HiddenVisibility)
7803 IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
7805 IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility);
7808 // If ID's layout is known, then make the global constant. This serves as a
7809 // useful assertion: we'll never use this variable to calculate ivar offsets,
7810 // so if the runtime tries to patch it then we should crash.
7811 if (isClassLayoutKnownStatically(ID))
7812 IvarOffsetGV->setConstant(true);
7814 if (CGM.getTriple().isOSBinFormatMachO())
7815 IvarOffsetGV->setSection("__DATA, __objc_ivar
");
7816 return IvarOffsetGV;
7837CGObjCNonFragileABIMac::EmitIvarList(const ObjCImplementationDecl *ID) {
7839 ConstantInitBuilder builder(CGM);
7840 auto ivarList = builder.beginStruct();
7841 ivarList.addInt(ObjCTypes.IntTy,
7842 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.IvarnfABITy));
7843 auto ivarCountSlot = ivarList.addPlaceholder();
7844 auto ivars = ivarList.beginArray(ObjCTypes.IvarnfABITy);
7846 const ObjCInterfaceDecl *OID = ID->getClassInterface();
7847 assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface
");
7849 // FIXME. Consolidate this with similar code in GenerateClass.
7851 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin(); IVD;
7852 IVD = IVD->getNextIvar()) {
7853 // Ignore unnamed bit-fields.
7854 if (!IVD->getDeclName())
7857 auto ivar = ivars.beginStruct(ObjCTypes.IvarnfABITy);
7858 ivar.add(EmitIvarOffsetVar(ID->getClassInterface(), IVD,
7859 ComputeIvarBaseOffset(CGM, ID, IVD)));
7860 ivar.add(GetMethodVarName(IVD->getIdentifier()));
7861 ivar.add(GetMethodVarType(IVD));
7862 llvm::Type *FieldTy = CGM.getTypes().ConvertTypeForMem(IVD->getType());
7863 unsigned Size = CGM.getDataLayout().getTypeAllocSize(FieldTy);
7865 CGM.getContext().getPreferredTypeAlign(IVD->getType().getTypePtr()) >>
7867 Align = llvm::Log2_32(Align);
7868 ivar.addInt(ObjCTypes.IntTy, Align);
7869 // NOTE. Size of a bitfield does not match gcc's, because of the
7870 // way bitfields are treated special in each. But I am told that
7871 // 'size' for bitfield ivars is ignored by the runtime so it does
7872 // not matter. If it matters, there is enough info to get the
7874 ivar.addInt(ObjCTypes.IntTy, Size);
7875 ivar.finishAndAddTo(ivars);
7877 // Return null for empty list.
7878 if (ivars.empty()) {
7881 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
7884 auto ivarCount = ivars.size();
7885 ivars.finishAndAddTo(ivarList);
7886 ivarList.fillPlaceholderWithInt(ivarCountSlot, ObjCTypes.IntTy, ivarCount);
7888 const char *Prefix = "_OBJC_$_INSTANCE_VARIABLES_
";
7889 llvm::GlobalVariable *GV = finishAndCreateGlobal(
7890 ivarList, Prefix + OID->getObjCRuntimeNameAsString(), CGM);
7891 CGM.addCompilerUsedGlobal(GV);
7896CGObjCNonFragileABIMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {
7897 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
7899 assert(!PD->isNonRuntimeProtocol() &&
7900 "attempting to GetOrEmit a non-runtime protocol
");
7902 // We use the initializer as a marker of whether this is a forward
7903 // reference or not. At module finalization we add the empty
7904 // contents for protocols which were referenced but never defined.
7905 llvm::SmallString<64> Protocol;
7906 llvm::raw_svector_ostream(Protocol)
7907 << "_OBJC_PROTOCOL_$_
" << PD->getObjCRuntimeNameAsString();
7909 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
7910 false, llvm::GlobalValue::ExternalLinkage,
7912 if (!CGM.getTriple().isOSBinFormatMachO())
7913 Entry->setComdat(CGM.getModule().getOrInsertComdat(Protocol));
7940CGObjCNonFragileABIMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
7941 llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
7943 // Early exit if a defining object has already been generated.
7944 if (Entry && Entry->hasInitializer())
7947 // Use the protocol definition, if there is one.
7948 assert(PD->hasDefinition() &&
7949 "emitting protocol metadata without definition
");
7950 PD = PD->getDefinition();
7952 auto methodLists = ProtocolMethodLists::get(PD);
7954 ConstantInitBuilder builder(CGM);
7955 auto values = builder.beginStruct(ObjCTypes.ProtocolnfABITy);
7958 values.addNullPointer(ObjCTypes.ObjectPtrTy);
7959 values.add(GetClassName(PD->getObjCRuntimeNameAsString()));
7960 values.add(EmitProtocolList("_OBJC_$_PROTOCOL_REFS_
" +
7961 PD->getObjCRuntimeNameAsString(),
7962 PD->protocol_begin(), PD->protocol_end()));
7963 values.add(methodLists.emitMethodList(
7964 this, PD, ProtocolMethodLists::RequiredInstanceMethods));
7965 values.add(methodLists.emitMethodList(
7966 this, PD, ProtocolMethodLists::RequiredClassMethods));
7967 values.add(methodLists.emitMethodList(
7968 this, PD, ProtocolMethodLists::OptionalInstanceMethods));
7969 values.add(methodLists.emitMethodList(
7970 this, PD, ProtocolMethodLists::OptionalClassMethods));
7972 EmitPropertyList("_OBJC_$_PROP_LIST_
" + PD->getObjCRuntimeNameAsString(),
7973 nullptr, PD, ObjCTypes, false));
7975 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
7976 values.addInt(ObjCTypes.IntTy, Size);
7977 values.addInt(ObjCTypes.IntTy, 0);
7978 values.add(EmitProtocolMethodTypes(
7979 "_OBJC_$_PROTOCOL_METHOD_TYPES_
" + PD->getObjCRuntimeNameAsString(),
7980 methodLists.emitExtendedTypesArray(this), ObjCTypes));
7982 // const char *demangledName;
7983 values.addNullPointer(ObjCTypes.Int8PtrTy);
7985 values.add(EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_
" +
7986 PD->getObjCRuntimeNameAsString(),
7987 nullptr, PD, ObjCTypes, true));
7990 // Already created, fix the linkage and update the initializer.
7991 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
7992 values.finishAndSetAsInitializer(Entry);
7994 llvm::SmallString<64> symbolName;
7995 llvm::raw_svector_ostream(symbolName)
7996 << "_OBJC_PROTOCOL_$_
" << PD->getObjCRuntimeNameAsString();
7998 Entry = values.finishAndCreateGlobal(symbolName, CGM.getPointerAlign(),
8000 llvm::GlobalValue::WeakAnyLinkage);
8001 if (!CGM.getTriple().isOSBinFormatMachO())
8002 Entry->setComdat(CGM.getModule().getOrInsertComdat(symbolName));
8004 Protocols[PD->getIdentifier()] = Entry;
8006 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
8007 CGM.addUsedGlobal(Entry);
8009 // Use this protocol meta-data to build protocol list table in section
8010 // __DATA, __objc_protolist
8011 llvm::SmallString<64> ProtocolRef;
8012 llvm::raw_svector_ostream(ProtocolRef)
8013 << "_OBJC_LABEL_PROTOCOL_$_
" << PD->getObjCRuntimeNameAsString();
8015 llvm::GlobalVariable *PTGV = new llvm::GlobalVariable(
8016 CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy, false,
8017 llvm::GlobalValue::WeakAnyLinkage, Entry, ProtocolRef);
8018 if (!CGM.getTriple().isOSBinFormatMachO())
8019 PTGV->setComdat(CGM.getModule().getOrInsertComdat(ProtocolRef));
8021 CGM.getDataLayout().getABITypeAlign(ObjCTypes.ProtocolnfABIPtrTy));
8023 GetSectionName("__objc_protolist
", "coalesced,no_dead_strip
"));
8024 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
8025 CGM.addUsedGlobal(PTGV);
8037llvm::Constant *CGObjCNonFragileABIMac::EmitProtocolList(
8038 Twine Name, ObjCProtocolDecl::protocol_iterator begin,
8039 ObjCProtocolDecl::protocol_iterator end) {
8040 // Just return null for empty protocol lists
8041 auto Protocols = GetRuntimeProtocolList(begin, end);
8042 if (Protocols.empty())
8043 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
8045 SmallVector<llvm::Constant *, 16> ProtocolRefs;
8046 ProtocolRefs.reserve(Protocols.size());
8048 for (const auto *PD : Protocols)
8049 ProtocolRefs.push_back(GetProtocolRef(PD));
8051 // If all of the protocols in the protocol list are objc_non_runtime_protocol
8053 if (ProtocolRefs.size() == 0)
8054 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
8056 // FIXME: We shouldn't need to do this lookup here, should we?
8057 SmallString<256> TmpName;
8058 Name.toVector(TmpName);
8059 llvm::GlobalVariable *GV =
8060 CGM.getModule().getGlobalVariable(TmpName.str(), true);
8064 ConstantInitBuilder builder(CGM);
8065 auto values = builder.beginStruct();
8066 auto countSlot = values.addPlaceholder();
8068 // A null-terminated array of protocols.
8069 auto array = values.beginArray(ObjCTypes.ProtocolnfABIPtrTy);
8070 for (auto const &proto : ProtocolRefs)
8072 auto count = array.size();
8073 array.addNullPointer(ObjCTypes.ProtocolnfABIPtrTy);
8075 array.finishAndAddTo(values);
8076 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
8078 GV = finishAndCreateGlobal(values, Name, CGM);
8079 CGM.addCompilerUsedGlobal(GV);
8089LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
8090 CodeGen::CodeGenFunction &CGF, QualType ObjectTy, llvm::Value *BaseValue,
8091 const ObjCIvarDecl *Ivar, unsigned CVRQualifiers) {
8092 ObjCInterfaceDecl *ID = ObjectTy->castAs<ObjCObjectType>()->getInterface();
8093 llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
8094 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
8099CGObjCNonFragileABIMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
8100 const ObjCInterfaceDecl *Interface,
8101 const ObjCIvarDecl *Ivar) {
8102 llvm::Value *IvarOffsetValue;
8103 if (isClassLayoutKnownStatically(Interface)) {
8104 IvarOffsetValue = llvm::ConstantInt::get(
8105 ObjCTypes.IvarOffsetVarTy,
8106 ComputeIvarBaseOffset(CGM, Interface->getImplementation(), Ivar));
8108 llvm::GlobalVariable *GV = ObjCIvarOffsetVariable(Interface, Ivar);
8109 IvarOffsetValue = CGF.Builder.CreateAlignedLoad(GV->getValueType(), GV,
8110 CGF.getSizeAlign(), "ivar
");
8111 if (IsIvarOffsetKnownIdempotent(CGF, Ivar))
8112 cast<llvm::LoadInst>(IvarOffsetValue)
8113 ->setMetadata(llvm::LLVMContext::MD_invariant_load,
8114 llvm::MDNode::get(VMContext, {}));
8117 // This could be 32bit int or 64bit integer depending on the architecture.
8118 // Cast it to 64bit integer value, if it is a 32bit integer ivar offset value
8119 // as this is what caller always expects.
8120 if (ObjCTypes.IvarOffsetVarTy == ObjCTypes.IntTy)
8121 IvarOffsetValue = CGF.Builder.CreateIntCast(
8122 IvarOffsetValue, ObjCTypes.LongTy, true, "ivar.conv
");
8123 return IvarOffsetValue;
8126static void appendSelectorForMessageRefTable(std::string &buffer,
8127 Selector selector) {
8128 if (selector.isUnarySelector()) {
8129 buffer += selector.getNameForSlot(0);
8133 for (unsigned i = 0, e = selector.getNumArgs(); i != e; ++i) {
8134 buffer += selector.getNameForSlot(i);
8149RValue CGObjCNonFragileABIMac::EmitVTableMessageSend(
8150 CodeGenFunction &CGF, ReturnValueSlot returnSlot, QualType resultType,
8151 Selector selector, llvm::Value *arg0, QualType arg0Type, bool isSuper,
8152 const CallArgList &formalArgs, const ObjCMethodDecl *method) {
8153 // Compute the actual arguments.
8156 // First argument: the receiver / super-call structure.
8158 arg0 = CGF.Builder.CreateBitCast(arg0, ObjCTypes.ObjectPtrTy);
8159 args.add(RValue::get(arg0), arg0Type);
8161 // Second argument: a pointer to the message ref structure. Leave
8162 // the actual argument value blank for now.
8163 args.add(RValue::get(nullptr), ObjCTypes.MessageRefCPtrTy);
8165 llvm::append_range(args, formalArgs);
8167 MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);
8169 NullReturnState nullReturn;
8171 // Find the function to call and the mangled name for the message
8172 // ref structure. Using a different mangled name wouldn't actually
8173 // be a problem; it would just be a waste.
8175 // The runtime currently never uses vtable dispatch for anything
8176 // except normal, non-super message-sends.
8177 // FIXME: don't use this for that.
8178 llvm::FunctionCallee fn = nullptr;
8179 std::string messageRefName("_
");
8180 if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
8182 fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
8183 messageRefName += "objc_msgSendSuper2_stret_fixup
";
8185 nullReturn.init(CGF, arg0);
8186 fn = ObjCTypes.getMessageSendStretFixupFn();
8187 messageRefName += "objc_msgSend_stret_fixup
";
8189 } else if (!isSuper && CGM.ReturnTypeUsesFPRet(resultType)) {
8190 fn = ObjCTypes.getMessageSendFpretFixupFn();
8191 messageRefName += "objc_msgSend_fpret_fixup
";
8194 fn = ObjCTypes.getMessageSendSuper2FixupFn();
8195 messageRefName += "objc_msgSendSuper2_fixup
";
8197 fn = ObjCTypes.getMessageSendFixupFn();
8198 messageRefName += "objc_msgSend_fixup
";
8201 assert(fn && "CGObjCNonFragileABIMac::EmitMessageSend
");
8202 messageRefName += '_';
8204 // Append the selector name, except use underscores anywhere we
8205 // would have used colons.
8206 appendSelectorForMessageRefTable(messageRefName, selector);
8208 llvm::GlobalVariable *messageRef =
8209 CGM.getModule().getGlobalVariable(messageRefName);
8211 // Build the message ref structure.
8212 ConstantInitBuilder builder(CGM);
8213 auto values = builder.beginStruct();
8214 values.add(cast<llvm::Constant>(fn.getCallee()));
8215 values.add(GetMethodVarName(selector));
8216 messageRef = values.finishAndCreateGlobal(
8217 messageRefName, CharUnits::fromQuantity(16),
8218 /*constant*/ false, llvm::GlobalValue::WeakAnyLinkage);
8219 messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility);
8220 messageRef->setSection(GetSectionName("__objc_msgrefs
", "coalesced
"));
8223 bool requiresnullCheck = false;
8224 if (CGM.getLangOpts().ObjCAutoRefCount && method)
8225 for (const auto *ParamDecl : method->parameters()) {
8226 if (ParamDecl->isDestroyedInCallee()) {
8227 if (!nullReturn.NullBB)
8228 nullReturn.init(CGF, arg0);
8229 requiresnullCheck = true;
8235 Address(CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy),
8236 ObjCTypes.MessageRefTy, CGF.getPointerAlign());
8238 // Update the message ref argument.
8239 args[1].setRValue(RValue::get(mref, CGF));
8241 // Load the function to call from the message ref table.
8242 Address calleeAddr = CGF.Builder.CreateStructGEP(mref, 0);
8243 llvm::Value *calleePtr = CGF.Builder.CreateLoad(calleeAddr, "msgSend_fn
");
8245 calleePtr = CGF.Builder.CreateBitCast(calleePtr, MSI.MessengerType);
8246 CGCallee callee(CGCalleeInfo(), calleePtr);
8248 RValue result = CGF.EmitCall(MSI.CallInfo, callee, returnSlot, args);
8249 return nullReturn.complete(CGF, returnSlot, result, resultType, formalArgs,
8250 requiresnullCheck ? method : nullptr);
8254CodeGen::RValue CGObjCNonFragileABIMac::GenerateMessageSend(
8255 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
8256 Selector Sel, llvm::Value *Receiver, const CallArgList &CallArgs,
8257 const ObjCInterfaceDecl *Class, const ObjCMethodDecl *Method) {
8258 return isVTableDispatchedSelector(Sel)
8259 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel, Receiver,
8260 CGF.getContext().getObjCIdType(), false,
8262 : EmitMessageSend(CGF, Return, ResultType, Sel, Receiver,
8263 CGF.getContext().getObjCIdType(), false,
8264 CallArgs, Method, Class, ObjCTypes);
8268CGObjCNonFragileABIMac::GetClassGlobal(const ObjCInterfaceDecl *ID,
8270 ForDefinition_t isForDefinition) {
8272 (metaclass ? getMetaclassSymbolPrefix() : getClassSymbolPrefix());
8273 return GetClassGlobal((prefix + ID->getObjCRuntimeNameAsString()).str(),
8274 isForDefinition, ID->isWeakImported(),
8276 CGM.getTriple().isOSBinFormatCOFF() &&
8277 ID->hasAttr<DLLImportAttr>());
8281CGObjCNonFragileABIMac::GetClassGlobal(StringRef Name,
8282 ForDefinition_t IsForDefinition,
8283 bool Weak, bool DLLImport) {
8284 llvm::GlobalValue::LinkageTypes L =
8285 Weak ? llvm::GlobalValue::ExternalWeakLinkage
8286 : llvm::GlobalValue::ExternalLinkage;
8288 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
8289 if (!GV || GV->getValueType() != ObjCTypes.ClassnfABITy) {
8290 auto *NewGV = new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, L,
8294 NewGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
8297 GV->replaceAllUsesWith(NewGV);
8298 GV->eraseFromParent();
8301 CGM.getModule().insertGlobalVariable(GV);
8304 assert(GV->getLinkage() == L);
8309CGObjCNonFragileABIMac::GetClassGlobalForClassRef(const ObjCInterfaceDecl *ID) {
8310 llvm::Constant *ClassGV =
8311 GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition);
8313 if (!ID->hasAttr<ObjCClassStubAttr>())
8316 ClassGV = llvm::ConstantExpr::getPointerCast(ClassGV, ObjCTypes.Int8PtrTy);
8318 // Stub classes are pointer-aligned. Classrefs pointing at stub classes
8319 // must set the least significant bit set to 1.
8320 auto *Idx = llvm::ConstantInt::get(CGM.Int32Ty, 1);
8321 return llvm::ConstantExpr::getPtrAdd(ClassGV, Idx);
8325CGObjCNonFragileABIMac::EmitLoadOfClassRef(CodeGenFunction &CGF,
8326 const ObjCInterfaceDecl *ID,
8327 llvm::GlobalVariable *Entry) {
8328 if (ID && ID->hasAttr<ObjCClassStubAttr>()) {
8329 // Classrefs pointing at Objective-C stub classes must be loaded by calling
8330 // a special runtime function.
8331 return CGF.EmitRuntimeCall(ObjCTypes.getLoadClassrefFn(), Entry,
8332 "load_classref_result
");
8335 CharUnits Align = CGF.getPointerAlign();
8336 return CGF.Builder.CreateAlignedLoad(Entry->getValueType(), Entry, Align);
8339llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(
8340 CodeGenFunction &CGF, IdentifierInfo *II, const ObjCInterfaceDecl *ID) {
8341 llvm::GlobalVariable *&Entry = ClassReferences[II];
8344 llvm::Constant *ClassGV;
8346 ClassGV = GetClassGlobalForClassRef(ID);
8348 ClassGV = GetClassGlobal((getClassSymbolPrefix() + II->getName()).str(),
8350 assert(ClassGV->getType() == ObjCTypes.ClassnfABIPtrTy &&
8351 "classref was emitted with the wrong
type?
");
8354 std::string SectionName =
8355 GetSectionName("__objc_classrefs
", "regular,no_dead_strip
");
8356 Entry = new llvm::GlobalVariable(
8357 CGM.getModule(), ClassGV->getType(), false,
8358 getLinkageTypeForObjCMetadata(CGM, SectionName), ClassGV,
8359 "OBJC_CLASSLIST_REFERENCES_$_
");
8360 Entry->setAlignment(CGF.getPointerAlign().getAsAlign());
8361 if (!ID || !ID->hasAttr<ObjCClassStubAttr>())
8362 Entry->setSection(SectionName);
8364 CGM.addCompilerUsedGlobal(Entry);
8367 return EmitLoadOfClassRef(CGF, ID, Entry);
8370llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CodeGenFunction &CGF,
8371 const ObjCInterfaceDecl *ID) {
8372 // If the class has the objc_runtime_visible attribute, we need to
8373 // use the Objective-C runtime to get the class.
8374 if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
8375 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
8377 return EmitClassRefFromId(CGF, ID->getIdentifier(), ID);
8381CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
8382 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool
");
8383 return EmitClassRefFromId(CGF, II, nullptr);
8387CGObjCNonFragileABIMac::EmitSuperClassRef(CodeGenFunction &CGF,
8388 const ObjCInterfaceDecl *ID) {
8389 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
8392 llvm::Constant *ClassGV = GetClassGlobalForClassRef(ID);
8393 std::string SectionName =
8394 GetSectionName("__objc_superrefs
", "regular,no_dead_strip
");
8395 Entry = new llvm::GlobalVariable(CGM.getModule(), ClassGV->getType(), false,
8396 llvm::GlobalValue::PrivateLinkage, ClassGV,
8397 "OBJC_CLASSLIST_SUP_REFS_$_
");
8398 Entry->setAlignment(CGF.getPointerAlign().getAsAlign());
8399 // Loading a reference to a class stub calls objc_loadClassref, which
8400 // updates the reference in place. We cannot use the __objc_superrefs
8401 // section here because it's a constant section.
8402 if (!ID->hasAttr<ObjCClassStubAttr>())
8403 Entry->setSection(SectionName);
8404 CGM.addCompilerUsedGlobal(Entry);
8407 return EmitLoadOfClassRef(CGF, ID, Entry);
8413llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(
8414 CodeGenFunction &CGF, const ObjCInterfaceDecl *ID, bool Weak) {
8415 CharUnits Align = CGF.getPointerAlign();
8416 llvm::GlobalVariable *&Entry = MetaClassReferences[ID->getIdentifier()];
8418 auto MetaClassGV = GetClassGlobal(ID, /*metaclass*/ true, NotForDefinition);
8419 std::string SectionName =
8420 GetSectionName("__objc_superrefs
", "regular,no_dead_strip
");
8421 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
8422 false, llvm::GlobalValue::PrivateLinkage,
8423 MetaClassGV, "OBJC_CLASSLIST_SUP_REFS_$_
");
8424 Entry->setAlignment(Align.getAsAlign());
8425 Entry->setSection(SectionName);
8426 CGM.addCompilerUsedGlobal(Entry);
8429 return CGF.Builder.CreateAlignedLoad(ObjCTypes.ClassnfABIPtrTy, Entry, Align);
8434llvm::Value *CGObjCNonFragileABIMac::GetClass(CodeGenFunction &CGF,
8435 const ObjCInterfaceDecl *ID) {
8436 if (ID->isWeakImported()) {
8437 auto ClassGV = GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition);
8439 assert(!isa<llvm::GlobalVariable>(ClassGV) ||
8440 cast<llvm::GlobalVariable>(ClassGV)->hasExternalWeakLinkage());
8443 return EmitClassRef(CGF, ID);
8449CodeGen::RValue CGObjCNonFragileABIMac::GenerateMessageSendSuper(
8450 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
8451 Selector Sel, const ObjCInterfaceDecl *Class, bool isCategoryImpl,
8452 llvm::Value *Receiver, bool IsClassMessage,
8453 const CodeGen::CallArgList &CallArgs, const ObjCMethodDecl *Method) {
8455 // Create and init a super structure; this is a (receiver, class)
8456 // pair we will pass to objc_msgSendSuper.
8457 RawAddress ObjCSuper = CGF.CreateTempAlloca(
8458 ObjCTypes.SuperTy, CGF.getPointerAlign(), "objc_super
");
8460 llvm::Value *ReceiverAsObject =
8461 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
8462 CGF.Builder.CreateStore(ReceiverAsObject,
8463 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
8465 // If this is a class message the metaclass is passed as the target.
8466 llvm::Value *Target;
8468 Target = EmitMetaClassRef(CGF, Class, Class->isWeakImported());
8470 Target = EmitSuperClassRef(CGF, Class);
8472 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
8474 llvm::Type *ClassTy =
8475 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
8476 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
8477 CGF.Builder.CreateStore(Target, CGF.Builder.CreateStructGEP(ObjCSuper, 1));
8479 return (isVTableDispatchedSelector(Sel))
8480 ? EmitVTableMessageSend(
8481 CGF, Return, ResultType, Sel, ObjCSuper.getPointer(),
8482 ObjCTypes.SuperPtrCTy, true, CallArgs, Method)
8483 : EmitMessageSend(CGF, Return, ResultType, Sel,
8484 ObjCSuper.getPointer(), ObjCTypes.SuperPtrCTy,
8485 true, CallArgs, Method, Class, ObjCTypes);
8488llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CodeGenFunction &CGF,
8490 Address Addr = EmitSelectorAddr(Sel);
8492 llvm::LoadInst *LI = CGF.Builder.CreateLoad(Addr);
8493 LI->setMetadata(llvm::LLVMContext::MD_invariant_load,
8494 llvm::MDNode::get(VMContext, {}));
8498ConstantAddress CGObjCNonFragileABIMac::EmitSelectorAddr(Selector Sel) {
8499 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
8500 CharUnits Align = CGM.getPointerAlign();
8502 std::string SectionName =
8503 GetSectionName("__objc_selrefs
", "literal_pointers,no_dead_strip
");
8504 Entry = new llvm::GlobalVariable(
8505 CGM.getModule(), ObjCTypes.SelectorPtrTy, false,
8506 getLinkageTypeForObjCMetadata(CGM, SectionName), GetMethodVarName(Sel),
8507 "OBJC_SELECTOR_REFERENCES_
");
8508 Entry->setExternallyInitialized(true);
8509 Entry->setSection(SectionName);
8510 Entry->setAlignment(Align.getAsAlign());
8511 CGM.addCompilerUsedGlobal(Entry);
8514 return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align);
8520void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
8521 llvm::Value *src, Address dst,
8522 llvm::Value *ivarOffset) {
8523 llvm::Type *SrcTy = src->getType();
8524 if (!isa<llvm::PointerType>(SrcTy)) {
8525 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
8526 assert(Size <= 8 && "does
not support size > 8
");
8527 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
8528 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
8529 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
8531 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
8532 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
8533 ObjCTypes.PtrObjectPtrTy);
8534 llvm::Value *args[] = {src, dstVal, ivarOffset};
8535 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
8541void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
8542 CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dst) {
8543 llvm::Type *SrcTy = src->getType();
8544 if (!isa<llvm::PointerType>(SrcTy)) {
8545 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
8546 assert(Size <= 8 && "does
not support size > 8
");
8547 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
8548 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
8549 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
8551 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
8552 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
8553 ObjCTypes.PtrObjectPtrTy);
8554 llvm::Value *args[] = {src, dstVal};
8555 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), args,
8559void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
8560 CodeGen::CodeGenFunction &CGF, Address DestPtr, Address SrcPtr,
8561 llvm::Value *Size) {
8562 llvm::Value *args[] = {DestPtr.emitRawPointer(CGF),
8563 SrcPtr.emitRawPointer(CGF), Size};
8564 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
8571CGObjCNonFragileABIMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
8572 Address AddrWeakObj) {
8573 llvm::Type *DestTy = AddrWeakObj.getElementType();
8574 llvm::Value *AddrWeakObjVal = CGF.Builder.CreateBitCast(
8575 AddrWeakObj.emitRawPointer(CGF), ObjCTypes.PtrObjectPtrTy);
8576 llvm::Value *read_weak = CGF.EmitNounwindRuntimeCall(
8577 ObjCTypes.getGcReadWeakFn(), AddrWeakObjVal, "weakread
");
8578 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
8585void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
8586 llvm::Value *src, Address dst) {
8587 llvm::Type *SrcTy = src->getType();
8588 if (!isa<llvm::PointerType>(SrcTy)) {
8589 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
8590 assert(Size <= 8 && "does
not support size > 8
");
8591 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
8592 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
8593 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
8595 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
8596 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
8597 ObjCTypes.PtrObjectPtrTy);
8598 llvm::Value *args[] = {src, dstVal};
8599 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), args,
8606void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
8607 llvm::Value *src, Address dst,
8609 llvm::Type *SrcTy = src->getType();
8610 if (!isa<llvm::PointerType>(SrcTy)) {
8611 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
8612 assert(Size <= 8 && "does
not support size > 8
");
8613 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
8614 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
8615 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
8617 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
8618 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
8619 ObjCTypes.PtrObjectPtrTy);
8620 llvm::Value *args[] = {src, dstVal};
8622 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), args,
8625 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(), args,
8626 "threadlocalassign
");
8629void CGObjCNonFragileABIMac::EmitSynchronizedStmt(
8630 CodeGen::CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S) {
8631 EmitAtSynchronizedStmt(CGF, S, ObjCTypes.getSyncEnterFn(),
8632 ObjCTypes.getSyncExitFn());
8635llvm::Constant *CGObjCNonFragileABIMac::GetEHType(QualType T) {
8636 // There's a particular fixed type info for 'id'.
8637 if (T->isObjCIdType() || T->isObjCQualifiedIdType()) {
8638 auto *IDEHType = CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id
");
8640 IDEHType = new llvm::GlobalVariable(
8641 CGM.getModule(), ObjCTypes.EHTypeTy, false,
8642 llvm::GlobalValue::ExternalLinkage, nullptr, "OBJC_EHTYPE_id
");
8643 if (CGM.getTriple().isOSBinFormatCOFF())
8644 IDEHType->setDLLStorageClass(getStorage(CGM, "OBJC_EHTYPE_id
"));
8649 // All other types should be Objective-C interface pointer types.
8650 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
8653 const ObjCInterfaceType *IT = PT->getInterfaceType();
8654 assert(IT && "Invalid
@catch type.
");
8656 return GetInterfaceEHType(IT->getDecl(), NotForDefinition);
8659void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
8660 const ObjCAtTryStmt &S) {
8661 EmitTryCatchStmt(CGF, S, ObjCTypes.getObjCBeginCatchFn(),
8662 ObjCTypes.getObjCEndCatchFn(),
8663 ObjCTypes.getExceptionRethrowFn());
8667void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
8668 const ObjCAtThrowStmt &S,
8669 bool ClearInsertionPoint) {
8670 if (const Expr *ThrowExpr = S.getThrowExpr()) {
8671 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
8672 Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
8673 llvm::CallBase *Call =
8674 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception);
8675 Call->setDoesNotReturn();
8677 llvm::CallBase *Call =
8678 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionRethrowFn());
8679 Call->setDoesNotReturn();
8682 CGF.Builder.CreateUnreachable();
8683 if (ClearInsertionPoint)
8684 CGF.Builder.ClearInsertionPoint();
8688CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
8689 ForDefinition_t IsForDefinition) {
8690 llvm::GlobalVariable *&Entry = EHTypeReferences[ID->getIdentifier()];
8691 StringRef ClassName = ID->getObjCRuntimeNameAsString();
8693 // If we don't need a definition, return the entry if found or check
8694 // if we use an external reference.
8695 if (!IsForDefinition) {
8699 // If this type (or a super class) has the __objc_exception__
8700 // attribute, emit an external reference.
8701 if (hasObjCExceptionAttribute(CGM.getContext(), ID)) {
8702 std::string EHTypeName = ("OBJC_EHTYPE_$_
" + ClassName).str();
8703 Entry = new llvm::GlobalVariable(
8704 CGM.getModule(), ObjCTypes.EHTypeTy, false,
8705 llvm::GlobalValue::ExternalLinkage, nullptr, EHTypeName);
8706 CGM.setGVProperties(Entry, ID);
8711 // Otherwise we need to either make a new entry or fill in the initializer.
8712 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition
");
8714 std::string VTableName = "objc_ehtype_vtable
";
8715 auto *VTableGV = CGM.getModule().getGlobalVariable(VTableName);
8717 VTableGV = new llvm::GlobalVariable(
8718 CGM.getModule(), ObjCTypes.Int8PtrTy, false,
8719 llvm::GlobalValue::ExternalLinkage, nullptr, VTableName);
8720 if (CGM.getTriple().isOSBinFormatCOFF())
8721 VTableGV->setDLLStorageClass(getStorage(CGM, VTableName));
8724 llvm::Constant *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2);
8725 llvm::Constant *VTablePtr = llvm::ConstantExpr::getGetElementPtr(
8726 CGM.getDataLayout(), VTableGV->getValueType(), VTableGV, VTableIdx,
8727 llvm::GEPNoWrapFlags::inBounds());
8729 ConstantInitBuilder builder(CGM);
8730 auto values = builder.beginStruct(ObjCTypes.EHTypeTy);
8731 const PointerAuthSchema &TypeInfoSchema =
8732 CGM.getCodeGenOpts().PointerAuth.CXXTypeInfoVTablePointer;
8733 values.addSignedPointer(VTablePtr, TypeInfoSchema, GlobalDecl(), QualType());
8735 values.add(GetClassName(ClassName));
8736 values.add(GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition));
8738 llvm::GlobalValue::LinkageTypes L = IsForDefinition
8739 ? llvm::GlobalValue::ExternalLinkage
8740 : llvm::GlobalValue::WeakAnyLinkage;
8742 values.finishAndSetAsInitializer(Entry);
8743 Entry->setAlignment(CGM.getPointerAlign().getAsAlign());
8745 Entry = values.finishAndCreateGlobal("OBJC_EHTYPE_$_
" + ClassName,
8746 CGM.getPointerAlign(),
8747 /*constant*/ false, L);
8748 if (hasObjCExceptionAttribute(CGM.getContext(), ID))
8749 CGM.setGVProperties(Entry, ID);
8751 assert(Entry->getLinkage() == L);
8753 if (!CGM.getTriple().isOSBinFormatCOFF())
8754 if (ID->getVisibility() == HiddenVisibility)
8755 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
8757 if (IsForDefinition)
8758 if (CGM.getTriple().isOSBinFormatMachO())
8759 Entry->setSection("__DATA,__objc_const
");
8766CodeGen::CGObjCRuntime *
8767CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
8768 switch (CGM.getLangOpts().ObjCRuntime.getKind()) {
8769 case ObjCRuntime::FragileMacOSX:
8770 return new CGObjCMac(CGM);
8772 case ObjCRuntime::MacOSX:
8773 case ObjCRuntime::iOS:
8774 case ObjCRuntime::WatchOS:
8775 return new CGObjCNonFragileABIMac(CGM);
8777 case ObjCRuntime::GNUstep:
8778 case ObjCRuntime::GCC:
8779 case ObjCRuntime::ObjFW:
8780 llvm_unreachable("these runtimes are
not Mac runtimes
");
8782 llvm_unreachable("bad runtime
");
8785// Public wrapper function for external compilers (e.g., Swift) to access
8786// the Mac runtime's GetDirectMethodCallee functionality.
8787llvm::Function *clang::CodeGen::getObjCDirectMethodCallee(
8788 CodeGenModule &CGM, const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD,
8789 bool ReceiverCanBeNull, bool ClassObjectCanBeUnrealized) {
8790 // This function should only be called when targeting Darwin platforms,
8791 // which always use the Mac runtime.
8792 assert(CGM.getLangOpts().ObjCRuntime.isNeXTFamily() &&
8794 CGObjCCommonMac *MacRuntime =
8795 static_cast<CGObjCCommonMac *>(&CGM.getObjCRuntime());
8796 return MacRuntime->GetDirectMethodCallee(OMD, CD, ReceiverCanBeNull,
8797 ClassObjectCanBeUnrealized);
Defines the clang::ASTContext interface.
@ FragileABI_Class_Meta
Is a meta-class.
@ FragileABI_Class_Hidden
Has hidden visibility.
@ FragileABI_Class_Factory
Apparently: is not a meta-class.
@ FragileABI_Class_HasCXXStructors
Has a non-trivial constructor or destructor.
@ FragileABI_Class_HasMRCWeakIvars
Class implementation was compiled under MRC and has MRC weak ivars.
@ FragileABI_Class_CompiledByARC
Class implementation was compiled under ARC.
static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT, bool pointee=false)
static bool hasWeakMember(QualType type)
static std::string getBlockLayoutInfoString(const SmallVectorImpl< CGObjCCommonMac::RUN_SKIP > &RunSkipBlockVars, bool HasCopyDisposeHelpers)
static llvm::StringMapEntry< llvm::GlobalVariable * > & GetConstantStringEntry(llvm::StringMap< llvm::GlobalVariable * > &Map, const StringLiteral *Literal, unsigned &StringLength)
static llvm::GlobalValue::LinkageTypes getLinkageTypeForObjCMetadata(CodeGenModule &CGM, StringRef Section)
static void addIfPresent(llvm::DenseSet< llvm::Value * > &S, Address V)
@ kCFTaggedObjectID_Integer
static void PushProtocolProperties(llvm::SmallPtrSet< const IdentifierInfo *, 16 > &PropertySet, SmallVectorImpl< const ObjCPropertyDecl * > &Properties, const ObjCProtocolDecl *Proto, bool IsClassProperty)
static llvm::GlobalVariable * finishAndCreateGlobal(ConstantInitBuilder::StructBuilder &Builder, const llvm::Twine &Name, CodeGenModule &CGM)
A helper function to create an internal or private global variable.
static bool hasMRCWeakIvars(CodeGenModule &CGM, const ObjCImplementationDecl *ID)
For compatibility, we only want to set the "HasMRCWeakIvars" flag (and actually fill in a layout stri...
@ NonFragileABI_Class_HasCXXDestructorOnly
Class has non-trivial destructors, but zero-initialization is okay.
@ NonFragileABI_Class_Hidden
Has hidden visibility.
@ NonFragileABI_Class_HasCXXStructors
Has a non-trivial constructor or destructor.
@ NonFragileABI_Class_Exception
Has the exception attribute.
@ NonFragileABI_Class_HasIvarReleaser
(Obsolete) ARC-specific: this class has a .release_ivars method
@ NonFragileABI_Class_Root
Is a root class.
@ NonFragileABI_Class_Meta
Is a meta-class.
@ NonFragileABI_Class_HasMRCWeakIvars
Class implementation was compiled under MRC and has MRC weak ivars.
@ NonFragileABI_Class_CompiledByARC
Class implementation was compiled under ARC.
static bool hasObjCExceptionAttribute(ASTContext &Context, const ObjCInterfaceDecl *OID)
hasObjCExceptionAttribute - Return true if this class or any super class has the objc_exception attri...
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
Result
Implement __builtin_bit_cast and related operations.
Defines the clang::LangOptions interface.
llvm::MachO::Target Target
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
Defines the Objective-C statement AST node classes.
__SIZE_TYPE__ size_t
The unsigned integer type of the result of the sizeof operator.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CanQualType getCanonicalParamType(QualType T) const
Return the canonical parameter type corresponding to the specific potentially non-canonical one.
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
QualType getObjCClassType() const
Represents the Objective-C Class type.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const LangOptions & getLangOpts() const
SelectorTable & Selectors
CanQualType getCanonicalSizeType() const
const ASTRecordLayout & getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const
Get or compute information about the layout of the specified Objective-C interface.
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
QualType getObjCIdType() const
Represents the Objective-CC id type.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType getObjCClassRedefinitionType() const
Retrieve the type that Class has been defined to, which may be different from the built-in Class if C...
QualType getObjCIdRedefinitionType() const
Retrieve the type that id has been defined to, which may be different from the built-in id if id has ...
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
CanQualType getNSUIntegerType() const
CharUnits getSize() const
getSize - Get the record size in characters.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
QualType withConst() const
Retrieves a version of this type with const applied.
llvm::Align getAsAlign() const
Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit bytes.
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
static CharUnits One()
Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Construct a CharUnits quantity of zero.
PointerAuthOptions PointerAuth
Configuration for pointer-signing.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
llvm::Type * getElementType() const
Return the type of the values stored in this address.
unsigned getIndex() const
CharUnits getOffset() const
const BlockDecl * getBlockDecl() const
llvm::StructType * StructureType
CharUnits BlockHeaderForcedGapOffset
bool NeedsCopyDispose
True if the block has captures that would necessitate custom copy or dispose helper functions if the ...
CharUnits BlockHeaderForcedGapSize
const Capture & getCapture(const VarDecl *var) const
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::Value * CreateIsNull(Address Addr, const Twine &Name="")
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
CGFunctionInfo - Class to encapsulate the information about a function definition.
Implements runtime-specific code generation functions.
static void destroyCalleeDestroyedArguments(CodeGenFunction &CGF, const ObjCMethodDecl *method, const CallArgList &callArgs)
Destroy the callee-destroyed arguments of the given method, if it has any.
void add(RValue rvalue, QualType type)
void addFrom(const CallArgList &other)
Add all the arguments from another CallArgList to this one.
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)
The given basic block lies in the current EH scope, but may be a target of a potentially scope-crossi...
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
llvm::Type * ConvertType(QualType T)
bool CurFuncIsThunk
In C++, whether we are code generating a thunk.
void EmitAutoVarDecl(const VarDecl &D)
EmitAutoVarDecl - Emit an auto variable declaration.
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void FinishObjCDirectPreconditionThunk()
Finish an Objective-C direct method thunk.
llvm::Value * EmitObjCThrowOperand(const Expr *expr)
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
void StartObjCDirectPreconditionThunk(const ObjCMethodDecl *OMD, llvm::Function *Fn, const CGFunctionInfo &FI)
Start an Objective-C direct method thunk.
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
JumpDest ReturnBlock
ReturnBlock - Unified return block.
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
RawAddress getNormalCleanupDestSlot()
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})
EmitStmt - Emit the code for the statement.
bool AutoreleaseResult
In ARC, whether we should autorelease the return value.
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
RawAddress NormalCleanupDest
i32s containing the indexes of the cleanup destinations.
SmallVector< llvm::Value *, 8 > ObjCEHValueStack
ObjCEHValueStack - Stack of Objective-C exception values, used for rethrows.
void EmitVarDecl(const VarDecl &D)
EmitVarDecl - Emit a local variable declaration.
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
llvm::Value * EmitFromMemory(llvm::Value *Value, QualType Ty)
EmitFromMemory - Change a scalar value from its memory representation to its value representation.
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
llvm::LLVMContext & getLLVMContext()
void PopCleanupBlock(bool FallThroughIsBranchThrough=false, bool ForDeactivation=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
This class organizes the cross-function state that is used while generating LLVM code.
llvm::Module & getModule() const
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
void addCompilerUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.compiler.used metadata.
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
bool ReturnTypeUsesFPRet(QualType ResultType)
Return true iff the given type uses 'fpret' when used as a return type.
bool isObjCDirectPreconditionThunkEnabled() const
Check if the precondition thunk optimization is enabled.
bool shouldHavePreconditionThunk(const ObjCMethodDecl *OMD) const
Check if a direct method should use precondition thunks at call sites.
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
const llvm::DataLayout & getDataLayout() const
bool ReturnTypeUsesFP2Ret(QualType ResultType)
Return true iff the given type uses 'fp2ret' when used as a return type.
const llvm::Triple & getTriple() const
bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI)
Return true iff the given type uses an argument slot when 'sret' is used as a return type.
llvm::Constant * CreateRuntimeVariable(llvm::Type *Ty, StringRef Name)
Create a new runtime global variable with the specified type and name.
void ConstructAttributeList(StringRef Name, const CGFunctionInfo &Info, CGCalleeInfo CalleeInfo, llvm::AttributeList &Attrs, unsigned &CallingConv, bool AttrOnCallSite, bool IsThunk)
Get the LLVM attributes and calling convention to use for a particular function type.
ConstantAddress GetAddrOfConstantCFString(const StringLiteral *Literal)
Return a pointer to a constant CFString object for the given string.
ASTContext & getContext() const
bool shouldHavePreconditionInline(const ObjCMethodDecl *OMD) const
Check if a direct method should have inline precondition checks at call sites.
bool ReturnTypeUsesSRet(const CGFunctionInfo &FI)
Return true iff the given type uses 'sret' when used as a return type.
const CodeGenOptions & getCodeGenOpts() const
llvm::LLVMContext & getLLVMContext()
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info, llvm::Function *F, bool IsThunk)
Set the LLVM function attributes (sext, zext, etc).
void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F)
Set the LLVM function attributes which only apply to a function definition.
ConstantAddress GetAddrOfConstantCString(const std::string &Str, StringRef GlobalName=".str")
Returns a pointer to a character array containing the literal and a terminating '\0' character.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
const CGFunctionInfo & arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD)
Objective-C methods are C functions with some implicit parameters.
llvm::Constant * getPointer() const
StructBuilder beginStruct(llvm::StructType *ty=nullptr)
FunctionArgList - Type for representing both the decl and type of parameters to a function.
static RValue get(llvm::Value *V)
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
llvm::Value * getPointer() const
SourceLocation getLocation() const
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
GlobalDecl - represents a global declaration.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
clang::ObjCRuntime ObjCRuntime
std::string ObjCConstantIntegerNumberClass
std::string ObjCConstantDoubleNumberClass
std::string ObjCConstantArrayClass
std::string ObjCConstantStringClass
std::string ObjCConstantDictionaryClass
std::string ObjCConstantFloatNumberClass
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
const Expr * getThrowExpr() const
const ObjCAtFinallyStmt * getFinallyStmt() const
Retrieve the @finally statement, if any.
catch_range catch_stmts()
ObjCContainerDecl - Represents a container for method declarations.
method_range methods() const
prop_range properties() const
const ObjCInterfaceDecl * getClassInterface() const
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Represents an ObjC class declaration.
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for class's metadata.
ObjCInterfaceDecl * getSuperClass() const
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...
ObjCIvarDecl - Represents an ObjC instance variable.
ObjCInterfaceDecl * getContainingInterface()
Return the class interface that this ivar is logically contained in; this is either the interface whe...
ObjCIvarDecl * getNextIvar()
ObjCMethodDecl - Represents an instance or class method declaration.
ImplicitParamDecl * getSelfDecl() const
param_const_iterator param_end() const
param_const_iterator param_begin() const
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
ObjCMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Selector getSelector() const
ImplicitParamDecl * getCmdDecl() const
bool isInstanceMethod() const
QualType getReturnType() const
bool isClassMethod() const
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
bool isObjCIdType() const
True if this is equivalent to the 'id' type, i.e.
Represents an Objective-C protocol declaration.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for protocol's metadata.
ObjCProtocolList::iterator protocol_iterator
protocol_iterator protocol_begin() const
protocol_range protocols() const
protocol_iterator protocol_end() const
bool hasConstantEmptyCollections() const
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
bool hasConstantCFBooleans() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
bool isObjCGCStrong() const
true when Type is objc's strong.
bool isObjCGCWeak() const
true when Type is objc's weak.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
field_range fields() const
RecordDecl * getDefinitionOrSelf() const
Selector getSelector(unsigned NumArgs, const IdentifierInfo **IIV)
Can create any sort of selector.
std::string getAsString() const
Derive the full selector name (e.g.
StringLiteral - This represents a string literal expression, e.g.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
unsigned getCharWidth() const
bool isBlockPointerType() const
CanQualType getCanonicalTypeUnqualified() const
bool isObjCQualifiedIdType() const
bool isObjCIdType() const
bool isObjCObjectPointerType() const
bool isObjCQualifiedClassType() const
bool isObjCClassType() const
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
const T * castAsCanonical() const
Return this type's canonical type cast to the specified type.
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
llvm::Function * getObjCDirectMethodCallee(CodeGenModule &CGM, const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD, bool ReceiverCanBeNull, bool ClassObjectCanBeUnrealized)
Get the appropriate callee for an ObjC direct method.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, BlockDecl > blockDecl
Matches block declarations.
bool LT(InterpState &S, CodePtr OpPC)
@ Address
A pointer to a ValueDecl.
Top level wrappers for InstallAPI frontend operations.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
@ Match
This is not an overload because the signature exactly matches an existing declaration.
bool isa(CodeGen::Address addr)
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
Selector GetUnarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing an unary selector.
const FunctionProtoType * T
Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
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.