31#include "llvm/ADT/CachedHashString.h"
32#include "llvm/ADT/DenseSet.h"
33#include "llvm/ADT/SetVector.h"
34#include "llvm/ADT/SmallPtrSet.h"
35#include "llvm/ADT/SmallString.h"
36#include "llvm/IR/DataLayout.h"
37#include "llvm/IR/InlineAsm.h"
38#include "llvm/IR/IntrinsicInst.h"
39#include "llvm/IR/LLVMContext.h"
40#include "llvm/IR/Module.h"
41#include "llvm/Support/ScopedPrinter.h"
42#include "llvm/Support/raw_ostream.h"
54class ObjCCommonTypesHelper {
56 llvm::LLVMContext &VMContext;
66 llvm::FunctionCallee getMessageSendFn()
const {
69 llvm::Type *params[] = {ObjectPtrTy, SelectorPtrTy};
70 return CGM.CreateRuntimeFunction(
71 llvm::FunctionType::get(ObjectPtrTy, params,
true),
"objc_msgSend",
72 llvm::AttributeList::get(CGM.getLLVMContext(),
73 llvm::AttributeList::FunctionIndex,
74 llvm::Attribute::NonLazyBind));
82 llvm::FunctionCallee getMessageSendStretFn()
const {
83 llvm::Type *params[] = {ObjectPtrTy, SelectorPtrTy};
84 return CGM.CreateRuntimeFunction(
85 llvm::FunctionType::get(CGM.VoidTy, params,
true),
86 "objc_msgSend_stret");
94 llvm::FunctionCallee getMessageSendFpretFn()
const {
95 llvm::Type *params[] = {ObjectPtrTy, SelectorPtrTy};
96 return CGM.CreateRuntimeFunction(
97 llvm::FunctionType::get(CGM.DoubleTy, params,
true),
98 "objc_msgSend_fpret");
106 llvm::FunctionCallee getMessageSendFp2retFn()
const {
107 llvm::Type *params[] = {ObjectPtrTy, SelectorPtrTy};
108 llvm::Type *longDoubleType = llvm::Type::getX86_FP80Ty(VMContext);
109 llvm::Type *resultType =
110 llvm::StructType::get(longDoubleType, longDoubleType);
112 return CGM.CreateRuntimeFunction(
113 llvm::FunctionType::get(resultType, params,
true),
114 "objc_msgSend_fp2ret");
122 llvm::FunctionCallee getMessageSendSuperFn()
const {
123 llvm::Type *params[] = {SuperPtrTy, SelectorPtrTy};
124 return CGM.CreateRuntimeFunction(
125 llvm::FunctionType::get(ObjectPtrTy, params,
true),
126 "objc_msgSendSuper");
133 llvm::FunctionCallee getMessageSendSuperFn2()
const {
134 llvm::Type *params[] = {SuperPtrTy, SelectorPtrTy};
135 return CGM.CreateRuntimeFunction(
136 llvm::FunctionType::get(ObjectPtrTy, params,
true),
137 "objc_msgSendSuper2");
144 llvm::FunctionCallee getMessageSendSuperStretFn()
const {
145 llvm::Type *params[] = {Int8PtrTy, SuperPtrTy, SelectorPtrTy};
146 return CGM.CreateRuntimeFunction(
147 llvm::FunctionType::get(CGM.VoidTy, params,
true),
148 "objc_msgSendSuper_stret");
155 llvm::FunctionCallee getMessageSendSuperStretFn2()
const {
156 llvm::Type *params[] = {Int8PtrTy, SuperPtrTy, SelectorPtrTy};
157 return CGM.CreateRuntimeFunction(
158 llvm::FunctionType::get(CGM.VoidTy, params,
true),
159 "objc_msgSendSuper2_stret");
162 llvm::FunctionCallee getMessageSendSuperFpretFn()
const {
164 return getMessageSendSuperFn();
167 llvm::FunctionCallee getMessageSendSuperFpretFn2()
const {
169 return getMessageSendSuperFn2();
173 CodeGen::CodeGenModule &CGM;
176 llvm::IntegerType *ShortTy, *IntTy, *LongTy;
177 llvm::PointerType *Int8PtrTy, *Int8PtrPtrTy;
178 llvm::PointerType *Int8PtrProgramASTy;
179 llvm::Type *IvarOffsetVarTy;
182 llvm::PointerType *ObjectPtrTy;
185 llvm::PointerType *PtrObjectPtrTy;
188 llvm::PointerType *SelectorPtrTy;
193 QualType SuperPtrCTy;
196 llvm::StructType *SuperTy;
198 llvm::PointerType *SuperPtrTy;
202 llvm::StructType *PropertyTy;
206 llvm::StructType *PropertyListTy;
208 llvm::PointerType *PropertyListPtrTy;
211 llvm::StructType *MethodTy;
216 llvm::PointerType *CachePtrTy;
218 llvm::FunctionCallee getGetPropertyFn() {
219 CodeGen::CodeGenTypes &Types = CGM.getTypes();
220 ASTContext &Ctx = CGM.getContext();
229 return CGM.CreateRuntimeFunction(FTy,
"objc_getProperty");
232 llvm::FunctionCallee getSetPropertyFn() {
233 CodeGen::CodeGenTypes &Types = CGM.getTypes();
234 ASTContext &Ctx = CGM.getContext();
247 return CGM.CreateRuntimeFunction(FTy,
"objc_setProperty");
250 llvm::FunctionCallee getOptimizedSetPropertyFn(
bool atomic,
bool copy) {
251 CodeGen::CodeGenTypes &Types = CGM.getTypes();
252 ASTContext &Ctx = CGM.getContext();
262 SmallVector<CanQualType, 4> Params;
265 Params.push_back(IdType);
266 Params.push_back(SelType);
267 Params.push_back(IdType);
273 name =
"objc_setProperty_atomic_copy";
274 else if (atomic && !copy)
275 name =
"objc_setProperty_atomic";
276 else if (!atomic && copy)
277 name =
"objc_setProperty_nonatomic_copy";
279 name =
"objc_setProperty_nonatomic";
281 return CGM.CreateRuntimeFunction(FTy, name);
284 llvm::FunctionCallee getCopyStructFn() {
285 CodeGen::CodeGenTypes &Types = CGM.getTypes();
286 ASTContext &Ctx = CGM.getContext();
288 SmallVector<CanQualType, 5> Params;
292 Params.push_back(Ctx.
BoolTy);
293 Params.push_back(Ctx.
BoolTy);
296 return CGM.CreateRuntimeFunction(FTy,
"objc_copyStruct");
303 llvm::FunctionCallee getCppAtomicObjectFunction() {
304 CodeGen::CodeGenTypes &Types = CGM.getTypes();
305 ASTContext &Ctx = CGM.getContext();
308 SmallVector<CanQualType, 3> Params;
314 return CGM.CreateRuntimeFunction(FTy,
"objc_copyCppObjectAtomic");
317 llvm::FunctionCallee getEnumerationMutationFn() {
318 CodeGen::CodeGenTypes &Types = CGM.getTypes();
319 ASTContext &Ctx = CGM.getContext();
321 SmallVector<CanQualType, 1> Params;
325 return CGM.CreateRuntimeFunction(FTy,
"objc_enumerationMutation");
328 llvm::FunctionCallee getLookUpClassFn() {
329 CodeGen::CodeGenTypes &Types = CGM.getTypes();
330 ASTContext &Ctx = CGM.getContext();
332 SmallVector<CanQualType, 1> Params;
335 llvm::FunctionType *FTy =
338 return CGM.CreateRuntimeFunction(FTy,
"objc_lookUpClass");
342 llvm::FunctionCallee getGcReadWeakFn() {
344 llvm::Type *args[] = {CGM.DefaultPtrTy};
345 llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, args,
false);
346 return CGM.CreateRuntimeFunction(FTy,
"objc_read_weak");
350 llvm::FunctionCallee getGcAssignWeakFn() {
352 llvm::Type *args[] = {ObjectPtrTy, CGM.DefaultPtrTy};
353 llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, args,
false);
354 return CGM.CreateRuntimeFunction(FTy,
"objc_assign_weak");
358 llvm::FunctionCallee getGcAssignGlobalFn() {
360 llvm::Type *args[] = {ObjectPtrTy, CGM.DefaultPtrTy};
361 llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, args,
false);
362 return CGM.CreateRuntimeFunction(FTy,
"objc_assign_global");
366 llvm::FunctionCallee getGcAssignThreadLocalFn() {
368 llvm::Type *args[] = {ObjectPtrTy, CGM.DefaultPtrTy};
369 llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, args,
false);
370 return CGM.CreateRuntimeFunction(FTy,
"objc_assign_threadlocal");
374 llvm::FunctionCallee getGcAssignIvarFn() {
376 llvm::Type *args[] = {ObjectPtrTy, CGM.DefaultPtrTy, CGM.PtrDiffTy};
377 llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, args,
false);
378 return CGM.CreateRuntimeFunction(FTy,
"objc_assign_ivar");
382 llvm::FunctionCallee GcMemmoveCollectableFn() {
384 llvm::Type *args[] = {Int8PtrTy, Int8PtrTy, LongTy};
385 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, args,
false);
386 return CGM.CreateRuntimeFunction(FTy,
"objc_memmove_collectable");
390 llvm::FunctionCallee getGcAssignStrongCastFn() {
392 llvm::Type *args[] = {ObjectPtrTy, CGM.DefaultPtrTy};
393 llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, args,
false);
394 return CGM.CreateRuntimeFunction(FTy,
"objc_assign_strongCast");
398 llvm::FunctionCallee getExceptionThrowFn() {
400 llvm::Type *args[] = {ObjectPtrTy};
401 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy, args,
false);
402 return CGM.CreateRuntimeFunction(FTy,
"objc_exception_throw");
406 llvm::FunctionCallee getExceptionRethrowFn() {
408 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy,
false);
409 return CGM.CreateRuntimeFunction(FTy,
"objc_exception_rethrow");
413 llvm::FunctionCallee getSyncEnterFn() {
415 llvm::Type *args[] = {ObjectPtrTy};
416 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.IntTy, args,
false);
417 return CGM.CreateRuntimeFunction(FTy,
"objc_sync_enter");
421 llvm::FunctionCallee getSyncExitFn() {
423 llvm::Type *args[] = {ObjectPtrTy};
424 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.IntTy, args,
false);
425 return CGM.CreateRuntimeFunction(FTy,
"objc_sync_exit");
428 llvm::FunctionCallee getSendFn(
bool IsSuper)
const {
429 return IsSuper ? getMessageSendSuperFn() : getMessageSendFn();
432 llvm::FunctionCallee getSendFn2(
bool IsSuper)
const {
433 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();
436 llvm::FunctionCallee getSendStretFn(
bool IsSuper)
const {
437 return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();
440 llvm::FunctionCallee getSendStretFn2(
bool IsSuper)
const {
441 return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();
444 llvm::FunctionCallee getSendFpretFn(
bool IsSuper)
const {
445 return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();
448 llvm::FunctionCallee getSendFpretFn2(
bool IsSuper)
const {
449 return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();
452 llvm::FunctionCallee getSendFp2retFn(
bool IsSuper)
const {
453 return IsSuper ? getMessageSendSuperFn() : getMessageSendFp2retFn();
456 llvm::FunctionCallee getSendFp2RetFn2(
bool IsSuper)
const {
457 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFp2retFn();
460 ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm);
465class ObjCTypesHelper :
public ObjCCommonTypesHelper {
468 llvm::StructType *SymtabTy;
470 llvm::PointerType *SymtabPtrTy;
472 llvm::StructType *ModuleTy;
475 llvm::StructType *ProtocolTy;
477 llvm::PointerType *ProtocolPtrTy;
480 llvm::StructType *ProtocolExtensionTy;
483 llvm::PointerType *ProtocolExtensionPtrTy;
486 llvm::StructType *MethodDescriptionTy;
489 llvm::StructType *MethodDescriptionListTy;
492 llvm::PointerType *MethodDescriptionListPtrTy;
494 llvm::StructType *ProtocolListTy;
496 llvm::PointerType *ProtocolListPtrTy;
498 llvm::StructType *CategoryTy;
500 llvm::StructType *ClassTy;
502 llvm::PointerType *ClassPtrTy;
504 llvm::StructType *ClassExtensionTy;
506 llvm::PointerType *ClassExtensionPtrTy;
508 llvm::StructType *IvarTy;
510 llvm::StructType *IvarListTy;
512 llvm::PointerType *IvarListPtrTy;
514 llvm::StructType *MethodListTy;
516 llvm::PointerType *MethodListPtrTy;
519 llvm::StructType *ExceptionDataTy;
522 llvm::FunctionCallee getExceptionTryEnterFn() {
525 llvm::FunctionType::get(CGM.
VoidTy, params,
false),
526 "objc_exception_try_enter");
530 llvm::FunctionCallee getExceptionTryExitFn() {
533 llvm::FunctionType::get(CGM.
VoidTy, params,
false),
534 "objc_exception_try_exit");
538 llvm::FunctionCallee getExceptionExtractFn() {
541 llvm::FunctionType::get(ObjectPtrTy, params,
false),
542 "objc_exception_extract");
546 llvm::FunctionCallee getExceptionMatchFn() {
547 llvm::Type *params[] = {ClassPtrTy, ObjectPtrTy};
549 llvm::FunctionType::get(CGM.
Int32Ty, params,
false),
550 "objc_exception_match");
554 llvm::FunctionCallee getSetJmpFn() {
558 llvm::FunctionType::get(CGM.
Int32Ty, params,
false),
"_setjmp",
560 llvm::AttributeList::FunctionIndex,
561 llvm::Attribute::NonLazyBind));
565 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
570class ObjCNonFragileABITypesHelper :
public ObjCCommonTypesHelper {
573 llvm::StructType *MethodListnfABITy;
576 llvm::PointerType *MethodListnfABIPtrTy;
579 llvm::StructType *ProtocolnfABITy;
582 llvm::PointerType *ProtocolnfABIPtrTy;
585 llvm::StructType *ProtocolListnfABITy;
588 llvm::PointerType *ProtocolListnfABIPtrTy;
591 llvm::StructType *ClassnfABITy;
594 llvm::PointerType *ClassnfABIPtrTy;
597 llvm::StructType *IvarnfABITy;
600 llvm::StructType *IvarListnfABITy;
603 llvm::PointerType *IvarListnfABIPtrTy;
606 llvm::StructType *ClassRonfABITy;
609 llvm::PointerType *ImpnfABITy;
612 llvm::StructType *CategorynfABITy;
621 llvm::StructType *MessageRefTy;
623 QualType MessageRefCTy;
626 llvm::Type *MessageRefPtrTy;
628 QualType MessageRefCPtrTy;
635 llvm::StructType *SuperMessageRefTy;
638 llvm::PointerType *SuperMessageRefPtrTy;
640 llvm::FunctionCallee getMessageSendFixupFn() {
642 llvm::Type *params[] = {ObjectPtrTy, MessageRefPtrTy};
644 llvm::FunctionType::get(ObjectPtrTy, params,
true),
645 "objc_msgSend_fixup");
648 llvm::FunctionCallee getMessageSendFpretFixupFn() {
650 llvm::Type *params[] = {ObjectPtrTy, MessageRefPtrTy};
652 llvm::FunctionType::get(ObjectPtrTy, params,
true),
653 "objc_msgSend_fpret_fixup");
656 llvm::FunctionCallee getMessageSendStretFixupFn() {
658 llvm::Type *params[] = {ObjectPtrTy, MessageRefPtrTy};
660 llvm::FunctionType::get(ObjectPtrTy, params,
true),
661 "objc_msgSend_stret_fixup");
664 llvm::FunctionCallee getMessageSendSuper2FixupFn() {
667 llvm::Type *params[] = {SuperPtrTy, SuperMessageRefPtrTy};
669 llvm::FunctionType::get(ObjectPtrTy, params,
true),
670 "objc_msgSendSuper2_fixup");
673 llvm::FunctionCallee getMessageSendSuper2StretFixupFn() {
676 llvm::Type *params[] = {SuperPtrTy, SuperMessageRefPtrTy};
678 llvm::FunctionType::get(ObjectPtrTy, params,
true),
679 "objc_msgSendSuper2_stret_fixup");
682 llvm::FunctionCallee getObjCEndCatchFn() {
687 llvm::FunctionCallee getObjCBeginCatchFn() {
688 llvm::Type *params[] = {Int8PtrTy};
690 llvm::FunctionType::get(Int8PtrTy, params,
false),
"objc_begin_catch");
698 llvm::FunctionCallee getLoadClassrefFn()
const {
704 llvm::Type *params[] = {Int8PtrPtrTy};
706 llvm::AttributeSet AS = llvm::AttributeSet::get(
708 llvm::Attribute::get(
C, llvm::Attribute::NonLazyBind),
709 llvm::Attribute::getWithMemoryEffects(
710 C, llvm::MemoryEffects::none()),
711 llvm::Attribute::get(
C, llvm::Attribute::NoUnwind),
714 llvm::FunctionType::get(ClassnfABIPtrTy, params,
false),
717 llvm::AttributeList::FunctionIndex, AS));
718 if (!CGM.
getTriple().isOSBinFormatCOFF())
720 ->setLinkage(llvm::Function::ExternalWeakLinkage);
725 llvm::StructType *EHTypeTy;
726 llvm::Type *EHTypePtrTy;
728 ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm);
731enum class ObjCLabelType {
748 SKIP_SCAN(
unsigned _skip = 0,
unsigned _scan = 0)
749 : skip(_skip), scan(_scan) {}
757 enum BLOCK_LAYOUT_OPCODE {
764 BLOCK_LAYOUT_OPERATOR = 0,
770 BLOCK_LAYOUT_NON_OBJECT_BYTES = 1,
775 BLOCK_LAYOUT_NON_OBJECT_WORDS = 2,
779 BLOCK_LAYOUT_STRONG = 3,
782 BLOCK_LAYOUT_BYREF = 4,
786 BLOCK_LAYOUT_WEAK = 5,
790 BLOCK_LAYOUT_UNRETAINED = 6
808 enum BLOCK_LAYOUT_OPCODE opcode;
809 CharUnits block_var_bytepos;
810 CharUnits block_var_size;
811 RUN_SKIP(
enum BLOCK_LAYOUT_OPCODE Opcode = BLOCK_LAYOUT_OPERATOR,
814 : opcode(
Opcode), block_var_bytepos(BytePos), block_var_size(
Size) {}
818 return block_var_bytepos <
b.block_var_bytepos;
823 llvm::LLVMContext &VMContext;
828 SmallVector<RUN_SKIP, 16> RunSkipBlockVars;
832 llvm::SetVector<IdentifierInfo *> LazySymbols;
838 llvm::SetVector<IdentifierInfo *> DefinedSymbols;
841 llvm::StringMap<llvm::GlobalVariable *> ClassNames;
844 llvm::DenseMap<Selector, llvm::GlobalVariable *> MethodVarNames;
847 llvm::SmallSetVector<llvm::CachedHashString, 16> DefinedCategoryNames;
851 llvm::StringMap<llvm::GlobalVariable *> MethodVarTypes;
855 llvm::DenseMap<const ObjCMethodDecl *, llvm::Function *> MethodDefinitions;
858 struct DirectMethodInfo {
861 llvm::Function *Thunk;
863 DirectMethodInfo(llvm::Function *Impl, llvm::Function *Thunk =
nullptr)
864 : Implementation(Impl), Thunk(Thunk) {}
869 llvm::DenseMap<const ObjCMethodDecl *, DirectMethodInfo>
870 DirectMethodDefinitions;
873 llvm::DenseMap<std::pair<Selector, StringRef>, llvm::Function *>
877 llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> PropertyNames;
880 llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> ClassReferences;
883 llvm::DenseMap<Selector, llvm::GlobalVariable *> SelectorReferences;
888 llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> Protocols;
892 llvm::DenseSet<IdentifierInfo *> DefinedProtocols;
895 SmallVector<llvm::GlobalValue *, 16> DefinedClasses;
898 SmallVector<const ObjCInterfaceDecl *, 16> ImplementedClasses;
901 SmallVector<llvm::GlobalValue *, 16> DefinedNonLazyClasses;
904 SmallVector<llvm::GlobalValue *, 16> DefinedCategories;
907 SmallVector<llvm::GlobalValue *, 16> DefinedStubCategories;
910 SmallVector<llvm::GlobalValue *, 16> DefinedNonLazyCategories;
914 llvm::WeakTrackingVH ConstantStringClassRef;
915 llvm::WeakTrackingVH ConstantArrayClassRef;
916 llvm::WeakTrackingVH ConstantDictionaryClassRef;
918 llvm::WeakTrackingVH ConstantIntegerNumberClassRef;
919 llvm::WeakTrackingVH ConstantFloatNumberClassRef;
920 llvm::WeakTrackingVH ConstantDoubleNumberClassRef;
923 llvm::StructType *NSConstantStringType =
nullptr;
924 llvm::StructType *NSConstantArrayType =
nullptr;
925 llvm::StructType *NSConstantDictionaryType =
nullptr;
927 llvm::StructType *NSConstantIntegerNumberType =
nullptr;
928 llvm::StructType *NSConstantFloatNumberType =
nullptr;
929 llvm::StructType *NSConstantDoubleNumberType =
nullptr;
931 llvm::StringMap<llvm::GlobalVariable *> NSConstantStringMap;
934 llvm::GlobalVariable *DefinedCFBooleanTrue =
nullptr;
935 llvm::GlobalVariable *DefinedCFBooleanFalse =
nullptr;
938 llvm::DenseMap<NSConstantNumberMapInfo, llvm::GlobalVariable *>
942 llvm::GlobalVariable *DefinedEmptyNSDictionary =
nullptr;
943 llvm::GlobalVariable *DefinedEmptyNSArray =
nullptr;
947 llvm::Constant *GetMethodVarName(Selector Sel);
948 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
954 llvm::Constant *GetMethodVarType(
const ObjCMethodDecl *D,
955 bool Extended =
false);
956 llvm::Constant *GetMethodVarType(
const FieldDecl *D);
960 llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
963 llvm::Constant *GetPropertyTypeString(
const ObjCPropertyDecl *PD,
964 const Decl *Container);
969 llvm::Constant *GetClassName(StringRef RuntimeName);
971 llvm::Function *GetMethodDefinition(
const ObjCMethodDecl *MD);
980 llvm::Constant *BuildIvarLayout(
const ObjCImplementationDecl *OI,
981 CharUnits beginOffset, CharUnits endOffset,
984 llvm::Constant *BuildStrongIvarLayout(
const ObjCImplementationDecl *OI,
985 CharUnits beginOffset,
986 CharUnits endOffset) {
987 return BuildIvarLayout(OI, beginOffset, endOffset,
true,
false);
990 llvm::Constant *BuildWeakIvarLayout(
const ObjCImplementationDecl *OI,
991 CharUnits beginOffset,
994 return BuildIvarLayout(OI, beginOffset, endOffset,
false,
hasMRCWeakIvars);
1001 CharUnits FieldOffset, CharUnits FieldSize);
1003 void BuildRCBlockVarRecordLayout(
const RecordType *RT, CharUnits BytePos,
1004 bool &HasUnion,
bool ByrefLayout =
false);
1006 void BuildRCRecordLayout(
const llvm::StructLayout *RecLayout,
1007 const RecordDecl *RD,
1008 ArrayRef<const FieldDecl *> RecFields,
1009 CharUnits BytePos,
bool &HasUnion,
bool ByrefLayout);
1011 uint64_t InlineLayoutInstruction(SmallVectorImpl<unsigned char> &Layout);
1013 llvm::Constant *getBitmapBlockLayout(
bool ComputeByrefLayout);
1017 llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident,
1018 const ObjCCommonTypesHelper &ObjCTypes);
1022 llvm::Constant *EmitPropertyList(Twine Name,
const Decl *Container,
1023 const ObjCContainerDecl *OCD,
1024 const ObjCCommonTypesHelper &ObjCTypes,
1025 bool IsClassProperty);
1030 EmitProtocolMethodTypes(Twine Name, ArrayRef<llvm::Constant *> MethodTypes,
1031 const ObjCCommonTypesHelper &ObjCTypes);
1036 llvm::Constant *GetProtocolRef(
const ObjCProtocolDecl *PD);
1040 llvm::Value *EmitClassRefViaRuntime(CodeGenFunction &CGF,
1041 const ObjCInterfaceDecl *ID,
1042 ObjCCommonTypesHelper &ObjCTypes);
1044 std::string GetSectionName(StringRef Section, StringRef MachOAttributes);
1047 static constexpr llvm::StringLiteral GetNSConstantIntegerNumberSectionName() {
1048 return "__DATA,__objc_intobj,regular,no_dead_strip";
1052 static constexpr llvm::StringLiteral GetNSConstantFloatNumberSectionName() {
1053 return "__DATA,__objc_floatobj,regular,no_dead_strip";
1057 static constexpr llvm::StringLiteral GetNSConstantDoubleNumberSectionName() {
1058 return "__DATA,__objc_doubleobj,regular,no_dead_strip";
1063 static constexpr llvm::StringLiteral
1064 GetNSConstantCollectionStorageSectionName() {
1065 return "__DATA,__objc_arraydata,regular,no_dead_strip";
1069 static constexpr llvm::StringLiteral GetNSConstantArraySectionName() {
1070 return "__DATA,__objc_arrayobj,regular,no_dead_strip";
1074 static constexpr llvm::StringLiteral GetNSConstantDictionarySectionName() {
1075 return "__DATA,__objc_dictobj,regular,no_dead_strip";
1093 llvm::GlobalVariable *CreateMetadataVar(Twine Name,
1094 ConstantStructBuilder &
Init,
1095 StringRef Section, CharUnits Align,
1097 llvm::GlobalVariable *CreateMetadataVar(Twine Name, llvm::Constant *
Init,
1098 StringRef Section, CharUnits Align,
1101 llvm::GlobalVariable *CreateCStringLiteral(StringRef Name,
1102 ObjCLabelType LabelType,
1103 bool ForceNonFragileABI =
false,
1104 bool NullTerminate =
true);
1107 CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
1108 ReturnValueSlot Return, QualType ResultType,
1109 Selector Sel, llvm::Value *Arg0,
1110 QualType Arg0Ty,
bool IsSuper,
1111 const CallArgList &CallArgs,
1112 const ObjCMethodDecl *OMD,
1113 const ObjCInterfaceDecl *ClassReceiver,
1114 const ObjCCommonTypesHelper &ObjCTypes);
1118 void EmitImageInfo();
1121 CGObjCCommonMac(CodeGen::CodeGenModule &cgm)
1122 : CGObjCRuntime(cgm), VMContext(cgm.getLLVMContext()) {}
1124 bool isNonFragileABI()
const {
return ObjCABI == 2; }
1127 llvm::GlobalVariable *EmitConstantCFBooleanTrue() {
1128 if (DefinedCFBooleanTrue)
1129 return DefinedCFBooleanTrue;
1132 "The current ABI doesn't support the constant CFBooleanTrue "
1137 DefinedCFBooleanTrue->addAttribute(
"objc_arc_inert");
1138 return DefinedCFBooleanTrue;
1142 llvm::GlobalVariable *EmitConstantCFBooleanFalse() {
1143 if (DefinedCFBooleanFalse)
1144 return DefinedCFBooleanFalse;
1147 "The current ABI doesn't support the constant CFBooleanFalse "
1152 DefinedCFBooleanFalse->addAttribute(
"objc_arc_inert");
1153 return DefinedCFBooleanFalse;
1157 llvm::GlobalVariable *EmitEmptyConstantNSDictionary() {
1158 if (DefinedEmptyNSDictionary)
1159 return DefinedEmptyNSDictionary;
1162 "The current ABI doesn't support an empty constant NSDictionary "
1167 DefinedEmptyNSDictionary->addAttribute(
"objc_arc_inert");
1168 return DefinedEmptyNSDictionary;
1172 llvm::GlobalVariable *EmitEmptyConstantNSArray() {
1173 if (DefinedEmptyNSArray)
1174 return DefinedEmptyNSArray;
1178 "The current ABI doesn't support an empty constant NSArray singleton!");
1182 DefinedEmptyNSArray->addAttribute(
"objc_arc_inert");
1183 return DefinedEmptyNSArray;
1186 ConstantAddress GenerateConstantString(
const StringLiteral *SL)
override;
1188 ConstantAddress GenerateConstantNumber(
const bool Value,
1189 const QualType &Ty)
override;
1190 ConstantAddress GenerateConstantNumber(
const llvm::APSInt &
Value,
1191 const QualType &Ty)
override;
1192 ConstantAddress GenerateConstantNumber(
const llvm::APFloat &
Value,
1193 const QualType &Ty)
override;
1195 GenerateConstantArray(
const ArrayRef<llvm::Constant *> &Objects)
override;
1196 ConstantAddress GenerateConstantDictionary(
1197 const ObjCDictionaryLiteral *E,
1198 ArrayRef<std::pair<llvm::Constant *, llvm::Constant *>> KeysAndObjects)
1201 ConstantAddress GenerateConstantNSString(
const StringLiteral *SL);
1202 ConstantAddress GenerateConstantNSNumber(
const bool Value,
1203 const QualType &Ty);
1204 ConstantAddress GenerateConstantNSNumber(
const llvm::APSInt &
Value,
1205 const QualType &Ty);
1206 ConstantAddress GenerateConstantNSNumber(
const llvm::APFloat &
Value,
1207 const QualType &Ty);
1209 GenerateConstantNSArray(
const ArrayRef<llvm::Constant *> &Objects);
1210 ConstantAddress GenerateConstantNSDictionary(
1211 const ObjCDictionaryLiteral *E,
1212 ArrayRef<std::pair<llvm::Constant *, llvm::Constant *>> KeysAndObjects);
1215 GenerateMethod(
const ObjCMethodDecl *OMD,
1216 const ObjCContainerDecl *CD =
nullptr)
override;
1218 DirectMethodInfo &GenerateDirectMethod(
const ObjCMethodDecl *OMD,
1219 const ObjCContainerDecl *CD);
1221 llvm::Function *GenerateObjCDirectThunk(
const ObjCMethodDecl *OMD,
1222 const ObjCContainerDecl *CD,
1223 llvm::Function *Implementation);
1225 llvm::Function *GetDirectMethodCallee(
const ObjCMethodDecl *OMD,
1226 const ObjCContainerDecl *CD,
1227 bool ReceiverCanBeNull,
1228 bool ClassObjectCanBeUnrealized);
1233 llvm::Value *GenerateClassRealization(CodeGenFunction &CGF,
1234 llvm::Value *classObject,
1235 const ObjCInterfaceDecl *OID);
1237 void GenerateDirectMethodsPreconditionCheck(
1238 CodeGenFunction &CGF, llvm::Function *Fn,
const ObjCMethodDecl *OMD,
1239 const ObjCContainerDecl *CD)
override;
1241 void GenerateDirectMethodPrologue(CodeGenFunction &CGF, llvm::Function *Fn,
1242 const ObjCMethodDecl *OMD,
1243 const ObjCContainerDecl *CD)
override;
1246 GenerateMethodSelectorStub(Selector Sel, StringRef ClassName,
1247 const ObjCCommonTypesHelper &ObjCTypes);
1249 void GenerateProtocol(
const ObjCProtocolDecl *PD)
override;
1255 virtual llvm::Constant *GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD) = 0;
1257 virtual llvm::Constant *getNSConstantStringClassRef() = 0;
1258 virtual llvm::Constant *getNSConstantArrayClassRef() = 0;
1259 virtual llvm::Constant *getNSConstantDictionaryClassRef() = 0;
1261 virtual llvm::Constant *getNSConstantIntegerNumberClassRef() = 0;
1262 virtual llvm::Constant *getNSConstantFloatNumberClassRef() = 0;
1263 virtual llvm::Constant *getNSConstantDoubleNumberClassRef() = 0;
1265 llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM,
1266 const CGBlockInfo &blockInfo)
override;
1267 llvm::Constant *BuildRCBlockLayout(CodeGen::CodeGenModule &CGM,
1268 const CGBlockInfo &blockInfo)
override;
1269 std::string getRCBlockLayoutStr(CodeGen::CodeGenModule &CGM,
1270 const CGBlockInfo &blockInfo)
override;
1272 llvm::Constant *BuildByrefLayout(CodeGen::CodeGenModule &CGM,
1273 QualType T)
override;
1276 void fillRunSkipBlockVars(CodeGenModule &CGM,
const CGBlockInfo &blockInfo);
1277 llvm::GlobalVariable *EmitNSConstantCollectionLiteralArrayStorage(
1278 const ArrayRef<llvm::Constant *> &Elements);
1283enum class MethodListType {
1284 CategoryInstanceMethods,
1285 CategoryClassMethods,
1288 ProtocolInstanceMethods,
1289 ProtocolClassMethods,
1290 OptionalProtocolInstanceMethods,
1291 OptionalProtocolClassMethods,
1296class ProtocolMethodLists {
1299 RequiredInstanceMethods,
1300 RequiredClassMethods,
1301 OptionalInstanceMethods,
1302 OptionalClassMethods
1304 enum { NumProtocolMethodLists = 4 };
1306 static MethodListType getMethodListKind(Kind
kind) {
1308 case RequiredInstanceMethods:
1309 return MethodListType::ProtocolInstanceMethods;
1310 case RequiredClassMethods:
1311 return MethodListType::ProtocolClassMethods;
1312 case OptionalInstanceMethods:
1313 return MethodListType::OptionalProtocolInstanceMethods;
1314 case OptionalClassMethods:
1315 return MethodListType::OptionalProtocolClassMethods;
1317 llvm_unreachable(
"bad kind");
1320 SmallVector<const ObjCMethodDecl *, 4> Methods[NumProtocolMethodLists];
1322 static ProtocolMethodLists get(
const ObjCProtocolDecl *PD) {
1323 ProtocolMethodLists result;
1325 for (
auto *MD : PD->
methods()) {
1327 (2 *
size_t(MD->isOptional())) + (
size_t(MD->isClassMethod()));
1328 result.Methods[index].push_back(MD);
1334 template <
class Self>
1335 SmallVector<llvm::Constant *, 8> emitExtendedTypesArray(
Self *self)
const {
1342 SmallVector<llvm::Constant *, 8> result;
1345 for (
auto &list : Methods) {
1346 for (
auto MD : list) {
1347 result.push_back(self->GetMethodVarType(MD,
true));
1354 template <
class Self>
1355 llvm::Constant *emitMethodList(
Self *self,
const ObjCProtocolDecl *PD,
1358 getMethodListKind(
kind), Methods[
kind]);
1364class CGObjCMac :
public CGObjCCommonMac {
1366 friend ProtocolMethodLists;
1368 ObjCTypesHelper ObjCTypes;
1372 void EmitModuleInfo();
1376 llvm::Constant *EmitModuleSymbols();
1380 void FinishModule();
1385 llvm::Constant *EmitClassExtension(
const ObjCImplementationDecl *ID,
1386 CharUnits instanceSize,
1391 llvm::Value *EmitClassRef(CodeGenFunction &CGF,
const ObjCInterfaceDecl *ID);
1393 llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF, IdentifierInfo *II);
1395 llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF)
override;
1398 llvm::Value *EmitSuperClassRef(
const ObjCInterfaceDecl *ID);
1405 llvm::Constant *EmitIvarList(
const ObjCImplementationDecl *ID,
bool ForClass);
1410 llvm::Constant *EmitMetaClassRef(
const ObjCInterfaceDecl *ID);
1414 llvm::Constant *EmitMetaClass(
const ObjCImplementationDecl *ID,
1415 llvm::Constant *Protocols,
1416 ArrayRef<const ObjCMethodDecl *> Methods);
1418 void emitMethodConstant(ConstantArrayBuilder &builder,
1419 const ObjCMethodDecl *MD);
1421 void emitMethodDescriptionConstant(ConstantArrayBuilder &builder,
1422 const ObjCMethodDecl *MD);
1426 llvm::Constant *emitMethodList(Twine Name, MethodListType MLT,
1427 ArrayRef<const ObjCMethodDecl *> Methods);
1432 llvm::Constant *GetOrEmitProtocol(
const ObjCProtocolDecl *PD)
override;
1438 llvm::Constant *GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD)
override;
1444 llvm::Constant *EmitProtocolExtension(
const ObjCProtocolDecl *PD,
1445 const ProtocolMethodLists &methodLists);
1449 llvm::Constant *EmitProtocolList(Twine Name,
1455 llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel);
1456 ConstantAddress EmitSelectorAddr(Selector Sel);
1459 CGObjCMac(CodeGen::CodeGenModule &cgm);
1461 llvm::Constant *getNSConstantStringClassRef()
override;
1462 llvm::Constant *getNSConstantArrayClassRef()
override;
1463 llvm::Constant *getNSConstantDictionaryClassRef()
override;
1465 llvm::Constant *getNSConstantIntegerNumberClassRef()
override;
1466 llvm::Constant *getNSConstantFloatNumberClassRef()
override;
1467 llvm::Constant *getNSConstantDoubleNumberClassRef()
override;
1469 llvm::Function *ModuleInitFunction()
override;
1471 CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1472 ReturnValueSlot Return,
1473 QualType ResultType, Selector Sel,
1474 llvm::Value *Receiver,
1475 const CallArgList &CallArgs,
1476 const ObjCInterfaceDecl *
Class,
1477 const ObjCMethodDecl *
Method)
override;
1479 CodeGen::RValue GenerateMessageSendSuper(
1480 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return,
1481 QualType ResultType, Selector Sel,
const ObjCInterfaceDecl *
Class,
1482 bool isCategoryImpl, llvm::Value *Receiver,
bool IsClassMessage,
1483 const CallArgList &CallArgs,
const ObjCMethodDecl *
Method)
override;
1485 llvm::Value *GetClass(CodeGenFunction &CGF,
1486 const ObjCInterfaceDecl *ID)
override;
1488 llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel)
override;
1489 Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel)
override;
1493 llvm::Value *GetSelector(CodeGenFunction &CGF,
1494 const ObjCMethodDecl *
Method)
override;
1496 llvm::Constant *GetEHType(QualType T)
override;
1498 void GenerateCategory(
const ObjCCategoryImplDecl *CMD)
override;
1500 void GenerateClass(
const ObjCImplementationDecl *ClassDecl)
override;
1502 void RegisterAlias(
const ObjCCompatibleAliasDecl *OAD)
override {}
1504 llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
1505 const ObjCProtocolDecl *PD)
override;
1507 llvm::FunctionCallee GetPropertyGetFunction()
override;
1508 llvm::FunctionCallee GetPropertySetFunction()
override;
1509 llvm::FunctionCallee GetOptimizedPropertySetFunction(
bool atomic,
1510 bool copy)
override;
1511 llvm::FunctionCallee GetGetStructFunction()
override;
1512 llvm::FunctionCallee GetSetStructFunction()
override;
1513 llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override;
1514 llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override;
1515 llvm::FunctionCallee EnumerationMutationFunction()
override;
1517 void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1518 const ObjCAtTryStmt &S)
override;
1519 void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1520 const ObjCAtSynchronizedStmt &S)
override;
1521 void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
const Stmt &S);
1522 void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
const ObjCAtThrowStmt &S,
1523 bool ClearInsertionPoint =
true)
override;
1524 llvm::Value *EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1525 Address AddrWeakObj)
override;
1526 void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1527 Address dst)
override;
1528 void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1529 Address dest,
bool threadlocal =
false)
override;
1530 void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1531 Address dest, llvm::Value *ivarOffset)
override;
1532 void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1533 Address dest)
override;
1534 void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, Address dest,
1535 Address src, llvm::Value *size)
override;
1537 LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy,
1538 llvm::Value *BaseValue,
const ObjCIvarDecl *Ivar,
1539 unsigned CVRQualifiers)
override;
1540 llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1542 const ObjCIvarDecl *Ivar)
override;
1545class CGObjCNonFragileABIMac :
public CGObjCCommonMac {
1547 friend ProtocolMethodLists;
1548 ObjCNonFragileABITypesHelper ObjCTypes;
1549 llvm::GlobalVariable *ObjCEmptyCacheVar;
1550 llvm::Constant *ObjCEmptyVtableVar;
1553 llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> SuperClassReferences;
1556 llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> MetaClassReferences;
1559 llvm::DenseMap<IdentifierInfo *, llvm::GlobalVariable *> EHTypeReferences;
1563 llvm::DenseSet<Selector> VTableDispatchMethods;
1566 std::vector<llvm::GlobalValue *> DefinedMetaClasses;
1570 bool isVTableDispatchedSelector(Selector Sel);
1574 void FinishNonFragileABIModule();
1578 void AddModuleClassList(ArrayRef<llvm::GlobalValue *> Container,
1579 StringRef SymbolName, StringRef SectionName);
1581 llvm::GlobalVariable *
1582 BuildClassRoTInitializer(
unsigned flags,
unsigned InstanceStart,
1583 unsigned InstanceSize,
1584 const ObjCImplementationDecl *ID);
1585 llvm::GlobalVariable *
1586 BuildClassObject(
const ObjCInterfaceDecl *CI,
bool isMetaclass,
1587 llvm::Constant *IsAGV, llvm::Constant *SuperClassGV,
1590 void emitMethodConstant(ConstantArrayBuilder &builder,
1591 const ObjCMethodDecl *MD,
bool forProtocol);
1595 llvm::Constant *emitMethodList(Twine Name, MethodListType MLT,
1596 ArrayRef<const ObjCMethodDecl *> Methods);
1603 llvm::Constant *EmitIvarList(
const ObjCImplementationDecl *ID);
1605 llvm::Constant *EmitIvarOffsetVar(
const ObjCInterfaceDecl *ID,
1606 const ObjCIvarDecl *Ivar,
1607 unsigned long int offset);
1612 llvm::Constant *GetOrEmitProtocol(
const ObjCProtocolDecl *PD)
override;
1618 llvm::Constant *GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD)
override;
1622 llvm::Constant *EmitProtocolList(Twine Name,
1626 CodeGen::RValue EmitVTableMessageSend(
1627 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return,
1628 QualType ResultType, Selector Sel, llvm::Value *Receiver, QualType Arg0Ty,
1629 bool IsSuper,
const CallArgList &CallArgs,
const ObjCMethodDecl *
Method);
1633 llvm::Constant *GetClassGlobal(StringRef Name,
1635 bool Weak =
false,
bool DLLImport =
false);
1636 llvm::Constant *GetClassGlobal(
const ObjCInterfaceDecl *ID,
bool isMetaclass,
1639 llvm::Constant *GetClassGlobalForClassRef(
const ObjCInterfaceDecl *ID);
1641 llvm::Value *EmitLoadOfClassRef(CodeGenFunction &CGF,
1642 const ObjCInterfaceDecl *ID,
1643 llvm::GlobalVariable *Entry);
1647 llvm::Value *EmitClassRef(CodeGenFunction &CGF,
const ObjCInterfaceDecl *ID);
1649 llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF, IdentifierInfo *II,
1650 const ObjCInterfaceDecl *ID);
1652 llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF)
override;
1656 llvm::Value *EmitSuperClassRef(CodeGenFunction &CGF,
1657 const ObjCInterfaceDecl *ID);
1661 llvm::Value *EmitMetaClassRef(CodeGenFunction &CGF,
1662 const ObjCInterfaceDecl *ID,
bool Weak);
1667 llvm::GlobalVariable *ObjCIvarOffsetVariable(
const ObjCInterfaceDecl *ID,
1668 const ObjCIvarDecl *Ivar);
1672 llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel);
1673 ConstantAddress EmitSelectorAddr(Selector Sel);
1677 llvm::Constant *GetInterfaceEHType(
const ObjCInterfaceDecl *ID,
1680 StringRef getMetaclassSymbolPrefix()
const {
return "OBJC_METACLASS_$_"; }
1682 StringRef getClassSymbolPrefix()
const {
return "OBJC_CLASS_$_"; }
1684 void GetClassSizeInfo(
const ObjCImplementationDecl *OID,
1685 uint32_t &InstanceStart, uint32_t &InstanceSize);
1700 bool ImplementationIsNonLazy(
const ObjCImplDecl *OD)
const;
1702 bool IsIvarOffsetKnownIdempotent(
const CodeGen::CodeGenFunction &CGF,
1703 const ObjCIvarDecl *IV) {
1718 if (
const ObjCMethodDecl *MD =
1719 dyn_cast_or_null<ObjCMethodDecl>(CGF.
CurFuncDecl))
1720 if (MD->isInstanceMethod() && !MD->isDirectMethod())
1721 if (
const ObjCInterfaceDecl *ID = MD->getClassInterface())
1726 bool isClassLayoutKnownStatically(
const ObjCInterfaceDecl *ID) {
1729 assert(ID !=
nullptr &&
"Passed a null class to check layout");
1730 for (;
ID !=
nullptr;
ID =
ID->getSuperClass()) {
1733 if (
ID->getIdentifier()->getName() ==
"NSObject")
1738 if (!
ID->getImplementation())
1747 CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm);
1749 llvm::Constant *getNSConstantStringClassRef()
override;
1750 llvm::Constant *getNSConstantArrayClassRef()
override;
1751 llvm::Constant *getNSConstantDictionaryClassRef()
override;
1753 llvm::Constant *getNSConstantIntegerNumberClassRef()
override;
1754 llvm::Constant *getNSConstantFloatNumberClassRef()
override;
1755 llvm::Constant *getNSConstantDoubleNumberClassRef()
override;
1757 llvm::Function *ModuleInitFunction()
override;
1759 CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1760 ReturnValueSlot Return,
1761 QualType ResultType, Selector Sel,
1762 llvm::Value *Receiver,
1763 const CallArgList &CallArgs,
1764 const ObjCInterfaceDecl *
Class,
1765 const ObjCMethodDecl *
Method)
override;
1767 CodeGen::RValue GenerateMessageSendSuper(
1768 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return,
1769 QualType ResultType, Selector Sel,
const ObjCInterfaceDecl *
Class,
1770 bool isCategoryImpl, llvm::Value *Receiver,
bool IsClassMessage,
1771 const CallArgList &CallArgs,
const ObjCMethodDecl *
Method)
override;
1773 llvm::Value *GetClass(CodeGenFunction &CGF,
1774 const ObjCInterfaceDecl *ID)
override;
1776 llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel)
override {
1777 return EmitSelector(CGF, Sel);
1779 Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel)
override {
1780 return EmitSelectorAddr(Sel);
1785 llvm::Value *GetSelector(CodeGenFunction &CGF,
1786 const ObjCMethodDecl *
Method)
override {
1787 return EmitSelector(CGF,
Method->getSelector());
1790 void GenerateCategory(
const ObjCCategoryImplDecl *CMD)
override;
1792 void GenerateClass(
const ObjCImplementationDecl *ClassDecl)
override;
1794 void RegisterAlias(
const ObjCCompatibleAliasDecl *OAD)
override {}
1796 llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
1797 const ObjCProtocolDecl *PD)
override;
1799 llvm::Constant *GetEHType(QualType T)
override;
1801 llvm::FunctionCallee GetPropertyGetFunction()
override {
1802 return ObjCTypes.getGetPropertyFn();
1804 llvm::FunctionCallee GetPropertySetFunction()
override {
1805 return ObjCTypes.getSetPropertyFn();
1808 llvm::FunctionCallee GetOptimizedPropertySetFunction(
bool atomic,
1809 bool copy)
override {
1810 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
1813 llvm::FunctionCallee GetSetStructFunction()
override {
1814 return ObjCTypes.getCopyStructFn();
1817 llvm::FunctionCallee GetGetStructFunction()
override {
1818 return ObjCTypes.getCopyStructFn();
1821 llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override {
1822 return ObjCTypes.getCppAtomicObjectFunction();
1825 llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override {
1826 return ObjCTypes.getCppAtomicObjectFunction();
1829 llvm::FunctionCallee EnumerationMutationFunction()
override {
1830 return ObjCTypes.getEnumerationMutationFn();
1833 void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1834 const ObjCAtTryStmt &S)
override;
1835 void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1836 const ObjCAtSynchronizedStmt &S)
override;
1837 void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
const ObjCAtThrowStmt &S,
1838 bool ClearInsertionPoint =
true)
override;
1839 llvm::Value *EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1840 Address AddrWeakObj)
override;
1841 void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1842 Address edst)
override;
1843 void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1844 Address dest,
bool threadlocal =
false)
override;
1845 void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1846 Address dest, llvm::Value *ivarOffset)
override;
1847 void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src,
1848 Address dest)
override;
1849 void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, Address dest,
1850 Address src, llvm::Value *size)
override;
1851 LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy,
1852 llvm::Value *BaseValue,
const ObjCIvarDecl *Ivar,
1853 unsigned CVRQualifiers)
override;
1854 llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1856 const ObjCIvarDecl *Ivar)
override;
1861struct NullReturnState {
1862 llvm::BasicBlock *NullBB =
nullptr;
1863 NullReturnState() =
default;
1866 void init(CodeGenFunction &CGF, llvm::Value *receiver) {
1876 CGF.
Builder.CreateCondBr(isNull, NullBB, callBB);
1884 RValue complete(CodeGenFunction &CGF, ReturnValueSlot returnSlot,
1885 RValue result, QualType resultType,
1886 const CallArgList &CallArgs,
const ObjCMethodDecl *
Method) {
1893 llvm::BasicBlock *contBB =
nullptr;
1896 llvm::BasicBlock *callBB = CGF.
Builder.GetInsertBlock();
1911 assert(CGF.
Builder.GetInsertBlock() == NullBB);
1933 llvm::PHINode *phi = CGF.
Builder.CreatePHI(null->getType(), 2);
1935 phi->addIncoming(null, NullBB);
1944 assert(result.
isAggregate() &&
"null init of non-aggregate result?");
1957 llvm::Type *scalarTy = callResult.first->getType();
1958 llvm::Constant *scalarZero = llvm::Constant::getNullValue(scalarTy);
1961 llvm::PHINode *real = CGF.
Builder.CreatePHI(scalarTy, 2);
1962 real->addIncoming(callResult.first, callBB);
1963 real->addIncoming(scalarZero, NullBB);
1964 llvm::PHINode *imag = CGF.
Builder.CreatePHI(scalarTy, 2);
1965 imag->addIncoming(callResult.second, callBB);
1966 imag->addIncoming(scalarZero, NullBB);
1977 llvm::GlobalVariable *
C,
unsigned idx0,
1979 llvm::Value *Idxs[] = {
1980 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),
1981 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)};
1982 return llvm::ConstantExpr::getGetElementPtr(
C->getValueType(),
C, Idxs);
1989 if (OID->
hasAttr<ObjCExceptionAttr>())
1996static llvm::GlobalValue::LinkageTypes
1998 if (CGM.
getTriple().isOSBinFormatMachO() &&
1999 (Section.empty() || Section.starts_with(
"__DATA")))
2000 return llvm::GlobalValue::InternalLinkage;
2001 return llvm::GlobalValue::PrivateLinkage;
2005static llvm::GlobalVariable *
2008 std::string SectionName;
2009 if (CGM.
getTriple().isOSBinFormatMachO())
2010 SectionName =
"__DATA, __objc_const";
2011 auto *GV = Builder.finishAndCreateGlobal(
2014 GV->setSection(SectionName);
2021 : CGObjCCommonMac(cgm), ObjCTypes(cgm) {
2030 return EmitClassRef(CGF, ID);
2034llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF, Selector Sel) {
2035 return EmitSelector(CGF, Sel);
2037Address CGObjCMac::GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) {
2038 return EmitSelectorAddr(Sel);
2040llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF,
2041 const ObjCMethodDecl *
Method) {
2042 return EmitSelector(CGF,
Method->getSelector());
2045llvm::Constant *CGObjCMac::GetEHType(QualType T) {
2057 llvm_unreachable(
"asking for catch type for ObjC type in fragile runtime");
2080CGObjCCommonMac::GenerateConstantString(
const StringLiteral *SL) {
2083 : GenerateConstantNSString(SL));
2086ConstantAddress CGObjCCommonMac::GenerateConstantNumber(
const bool Value,
2087 const QualType &Ty) {
2088 return GenerateConstantNSNumber(
Value, Ty);
2092CGObjCCommonMac::GenerateConstantNumber(
const llvm::APSInt &
Value,
2093 const QualType &Ty) {
2094 return GenerateConstantNSNumber(
Value, Ty);
2098CGObjCCommonMac::GenerateConstantNumber(
const llvm::APFloat &
Value,
2099 const QualType &Ty) {
2100 return GenerateConstantNSNumber(
Value, Ty);
2103ConstantAddress CGObjCCommonMac::GenerateConstantArray(
2104 const ArrayRef<llvm::Constant *> &Objects) {
2105 return GenerateConstantNSArray(Objects);
2108ConstantAddress CGObjCCommonMac::GenerateConstantDictionary(
2109 const ObjCDictionaryLiteral *E,
2110 ArrayRef<std::pair<llvm::Constant *, llvm::Constant *>> KeysAndObjects) {
2111 return GenerateConstantNSDictionary(E, KeysAndObjects);
2114static llvm::StringMapEntry<llvm::GlobalVariable *> &
2117 StringRef String = Literal->getString();
2118 StringLength = String.size();
2119 return *Map.insert(std::make_pair(String,
nullptr)).first;
2122llvm::Constant *CGObjCMac::getNSConstantStringClassRef() {
2123 if (llvm::Value *
V = ConstantStringClassRef)
2127 std::string str = StringClass.empty() ?
"_NSConstantStringClassReference"
2128 :
"_" + StringClass +
"ClassReference";
2130 llvm::Type *PTy = llvm::ArrayType::get(CGM.
IntTy, 0);
2132 ConstantStringClassRef = GV;
2136llvm::Constant *CGObjCMac::getNSConstantArrayClassRef() {
2137 llvm_unreachable(
"constant array literals not supported for fragile ABI");
2140llvm::Constant *CGObjCMac::getNSConstantDictionaryClassRef() {
2141 llvm_unreachable(
"constant dictionary literals not supported for fragile "
2145llvm::Constant *CGObjCMac::getNSConstantIntegerNumberClassRef() {
2146 llvm_unreachable(
"constant number literals not supported for fragile ABI");
2149llvm::Constant *CGObjCMac::getNSConstantFloatNumberClassRef() {
2150 llvm_unreachable(
"constant number literals not supported for fragile ABI");
2153llvm::Constant *CGObjCMac::getNSConstantDoubleNumberClassRef() {
2154 llvm_unreachable(
"constant number literals not supported for fragile ABI");
2157llvm::Constant *CGObjCNonFragileABIMac::getNSConstantStringClassRef() {
2158 if (llvm::Value *
V = ConstantStringClassRef)
2162 std::string str = StringClass.empty() ?
"OBJC_CLASS_$_NSConstantString"
2163 :
"OBJC_CLASS_$_" + StringClass;
2165 ConstantStringClassRef = GV;
2169llvm::Constant *CGObjCNonFragileABIMac::getNSConstantArrayClassRef() {
2170 if (llvm::Value *
V = ConstantArrayClassRef)
2174 std::string Str = ArrayClass.empty() ?
"OBJC_CLASS_$_NSConstantArray"
2175 :
"OBJC_CLASS_$_" + ArrayClass;
2178 ConstantArrayClassRef = GV;
2182llvm::Constant *CGObjCNonFragileABIMac::getNSConstantDictionaryClassRef() {
2183 if (llvm::Value *
V = ConstantDictionaryClassRef)
2186 const std::string &DictionaryClass =
2188 std::string Str = DictionaryClass.empty()
2189 ?
"OBJC_CLASS_$_NSConstantDictionary"
2190 :
"OBJC_CLASS_$_" + DictionaryClass;
2193 ConstantDictionaryClassRef = GV;
2197llvm::Constant *CGObjCNonFragileABIMac::getNSConstantIntegerNumberClassRef() {
2198 if (llvm::Value *
V = ConstantIntegerNumberClassRef)
2201 const std::string &NumberClass =
2203 std::string Str = NumberClass.empty() ?
"OBJC_CLASS_$_NSConstantIntegerNumber"
2204 :
"OBJC_CLASS_$_" + NumberClass;
2207 ConstantIntegerNumberClassRef = GV;
2211llvm::Constant *CGObjCNonFragileABIMac::getNSConstantFloatNumberClassRef() {
2212 if (llvm::Value *
V = ConstantFloatNumberClassRef)
2215 const std::string &NumberClass =
2217 std::string Str = NumberClass.empty() ?
"OBJC_CLASS_$_NSConstantFloatNumber"
2218 :
"OBJC_CLASS_$_" + NumberClass;
2221 ConstantFloatNumberClassRef = GV;
2225llvm::Constant *CGObjCNonFragileABIMac::getNSConstantDoubleNumberClassRef() {
2226 if (llvm::Value *
V = ConstantDoubleNumberClassRef)
2229 const std::string &NumberClass =
2231 std::string Str = NumberClass.empty() ?
"OBJC_CLASS_$_NSConstantDoubleNumber"
2232 :
"OBJC_CLASS_$_" + NumberClass;
2235 ConstantDoubleNumberClassRef = GV;
2240CGObjCCommonMac::GenerateConstantNSString(
const StringLiteral *Literal) {
2241 unsigned StringLength = 0;
2242 llvm::StringMapEntry<llvm::GlobalVariable *> &Entry =
2245 if (
auto *
C = Entry.second)
2246 return ConstantAddress(
C,
C->getValueType(),
2250 llvm::Constant *
Class = getNSConstantStringClassRef();
2253 if (!NSConstantStringType) {
2257 NSConstantStringType =
2259 "struct.__builtin_NSString");
2262 ConstantInitBuilder Builder(CGM);
2263 auto Fields = Builder.beginStruct(NSConstantStringType);
2266 Fields.addSignedPointer(
Class,
2268 GlobalDecl(), QualType());
2272 llvm::ConstantDataArray::getString(VMContext, Entry.first());
2274 llvm::GlobalValue::LinkageTypes
Linkage = llvm::GlobalValue::PrivateLinkage;
2275 bool isConstant = !CGM.
getLangOpts().WritableStrings;
2277 auto *GV =
new llvm::GlobalVariable(CGM.
getModule(),
C->getType(), isConstant,
2279 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2282 GV->setAlignment(llvm::Align(1));
2286 Fields.addInt(CGM.
IntTy, StringLength);
2290 GV = Fields.finishAndCreateGlobal(
"_unnamed_nsstring_", Alignment,
2292 llvm::GlobalVariable::PrivateLinkage);
2293 const char *NSStringSection =
"__OBJC,__cstring_object,regular,no_dead_strip";
2294 const char *NSStringNonFragileABISection =
2295 "__DATA,__objc_stringobj,regular,no_dead_strip";
2298 ? NSStringNonFragileABISection
2302 return ConstantAddress(GV, GV->getValueType(), Alignment);
2306ConstantAddress CGObjCCommonMac::GenerateConstantNSNumber(
const bool Value,
2307 const QualType &Ty) {
2308 llvm::GlobalVariable *Val =
2309 Value ? EmitConstantCFBooleanTrue() : EmitConstantCFBooleanFalse();
2310 return ConstantAddress(Val, Val->getValueType(), CGM.
getPointerAlign());
2322CGObjCCommonMac::GenerateConstantNSNumber(
const llvm::APSInt &
Value,
2323 const QualType &Ty) {
2327 llvm::GlobalVariable *&Entry =
2330 return ConstantAddress(Entry, Entry->getValueType(), Alignment);
2334 std::string ObjCEncodingType;
2335 CodeGenFunction(CGM).getContext().getObjCEncodingForType(Ty,
2338 llvm::Constant *
const Class = getNSConstantIntegerNumberClassRef();
2340 if (!NSConstantIntegerNumberType) {
2341 NSConstantIntegerNumberType = llvm::StructType::create(
2347 "struct.__builtin_NSConstantIntegerNumber");
2350 ConstantInitBuilder Builder(CGM);
2351 auto Fields = Builder.beginStruct(NSConstantIntegerNumberType);
2360 llvm::Constant *IntegerValue =
2361 llvm::ConstantInt::get(CGM.
Int64Ty,
Value.extOrTrunc(64));
2363 Fields.add(IntegerValue);
2366 llvm::GlobalVariable *
const GV = Fields.finishAndCreateGlobal(
2367 "_unnamed_nsconstantintegernumber_", Alignment,
2368 true, llvm::GlobalVariable::PrivateLinkage);
2370 GV->setSection(GetNSConstantIntegerNumberSectionName());
2371 GV->addAttribute(
"objc_arc_inert");
2375 return ConstantAddress(GV, GV->getValueType(), Alignment);
2391CGObjCCommonMac::GenerateConstantNSNumber(
const llvm::APFloat &
Value,
2392 const QualType &Ty) {
2396 llvm::GlobalVariable *&Entry =
2399 return ConstantAddress(Entry, Entry->getValueType(), Alignment);
2403 std::string ObjCEncodingType;
2404 CodeGenFunction(CGM).getContext().getObjCEncodingForType(Ty,
2407 assert((ObjCEncodingType ==
"d" || ObjCEncodingType ==
"f") &&
2408 "Unexpected or unknown ObjCEncodingType used in constant NSNumber");
2410 llvm::GlobalValue::LinkageTypes
Linkage =
2411 llvm::GlobalVariable::PrivateLinkage;
2414 if (ObjCEncodingType ==
"f") {
2415 llvm::Constant *
const Class = getNSConstantFloatNumberClassRef();
2417 if (!NSConstantFloatNumberType) {
2418 NSConstantFloatNumberType = llvm::StructType::create(
2423 "struct.__builtin_NSConstantFloatNumber");
2426 ConstantInitBuilder Builder(CGM);
2427 auto Fields = Builder.beginStruct(NSConstantFloatNumberType);
2433 llvm::Constant *FV = llvm::ConstantFP::get(CGM.
FloatTy,
Value);
2437 llvm::GlobalVariable *
const GV = Fields.finishAndCreateGlobal(
2438 "_unnamed_nsconstantfloatnumber_", Alignment,
2441 GV->setSection(GetNSConstantFloatNumberSectionName());
2442 GV->addAttribute(
"objc_arc_inert");
2446 return ConstantAddress(GV, GV->getValueType(), Alignment);
2449 llvm::Constant *
const Class = getNSConstantDoubleNumberClassRef();
2450 if (!NSConstantDoubleNumberType) {
2452 NSConstantDoubleNumberType = llvm::StructType::create(
2457 "struct.__builtin_NSConstantDoubleNumber");
2460 ConstantInitBuilder Builder(CGM);
2461 auto Fields = Builder.beginStruct(NSConstantDoubleNumberType);
2467 llvm::Constant *DV = llvm::ConstantFP::get(CGM.
DoubleTy,
Value);
2471 llvm::GlobalVariable *
const GV = Fields.finishAndCreateGlobal(
2472 "_unnamed_nsconstantdoublenumber_", Alignment,
2475 GV->setSection(GetNSConstantDoubleNumberSectionName());
2476 GV->addAttribute(
"objc_arc_inert");
2480 return ConstantAddress(GV, GV->getValueType(), Alignment);
2485llvm::GlobalVariable *
2486CGObjCCommonMac::EmitNSConstantCollectionLiteralArrayStorage(
2487 const ArrayRef<llvm::Constant *> &Elements) {
2488 llvm::Type *ElementsTy = Elements[0]->getType();
2489 llvm::ArrayType *ArrayTy = llvm::ArrayType::get(ElementsTy, Elements.size());
2491 llvm::Constant *
const ArrayData = llvm::ConstantArray::get(ArrayTy, Elements);
2493 llvm::GlobalVariable *ObjectsGV =
new llvm::GlobalVariable(
2494 CGM.
getModule(), ArrayTy,
true, llvm::GlobalValue::InternalLinkage,
2495 ArrayData,
"_unnamed_array_storage");
2498 ObjectsGV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2499 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);
2543 uint64_t ObjectCount = Objects.size();
2544 llvm::Constant *Count = llvm::ConstantInt::get(NSUIntegerTy, ObjectCount);
2548 llvm::GlobalVariable *ObjectsGV =
2549 EmitNSConstantCollectionLiteralArrayStorage(Objects);
2550 Fields.add(ObjectsGV);
2553 llvm::GlobalVariable *GV = Fields.finishAndCreateGlobal(
2554 "_unnamed_nsarray_", Alignment,
2555 true, llvm::GlobalValue::PrivateLinkage);
2557 GV->setSection(GetNSConstantArraySectionName());
2558 GV->addAttribute(
"objc_arc_inert");
2560 return ConstantAddress(GV, GV->getValueType(), Alignment);
2573ConstantAddress CGObjCCommonMac::GenerateConstantNSDictionary(
2574 const ObjCDictionaryLiteral *E,
2575 ArrayRef<std::pair<llvm::Constant *, llvm::Constant *>> KeysAndObjects) {
2578 if (KeysAndObjects.size() == 0) {
2579 llvm::GlobalVariable *GV = EmitEmptyConstantNSDictionary();
2580 return ConstantAddress(GV, GV->getValueType(), Alignment);
2584 CodeGenTypes &Types = CGM.
getTypes();
2585 llvm::Constant *
const Class = getNSConstantDictionaryClassRef();
2587 llvm::Type *
const NSUIntegerTy =
2590 if (!NSConstantDictionaryType) {
2591 NSConstantDictionaryType = llvm::StructType::create(
2599 "struct.__builtin_NSDictionary");
2602 ConstantInitBuilder Builder(CGM);
2603 auto Fields = Builder.beginStruct(NSConstantDictionaryType);
2609 auto HashOpts(NSDictionaryBuilder::Options::Sorted);
2610 NSDictionaryBuilder DictBuilder(E, KeysAndObjects, HashOpts);
2613 uint64_t const NumElements = DictBuilder.getNumElements();
2615 llvm::Constant *OptionsConstant = llvm::ConstantInt::get(
2616 NSUIntegerTy,
static_cast<uint64_t>(DictBuilder.getOptions()));
2617 Fields.add(OptionsConstant);
2620 llvm::Constant *Count = llvm::ConstantInt::get(NSUIntegerTy, NumElements);
2624 SmallVector<llvm::Constant *, 16> SortedKeys, SortedObjects;
2625 SortedKeys.reserve(NumElements);
2626 SortedObjects.reserve(NumElements);
2627 for (
auto &[Key, Obj] : DictBuilder.getElements()) {
2628 SortedKeys.push_back(Key);
2629 SortedObjects.push_back(Obj);
2633 llvm::GlobalVariable *KeysGV =
2634 EmitNSConstantCollectionLiteralArrayStorage(SortedKeys);
2638 llvm::GlobalVariable *ObjectsGV =
2639 EmitNSConstantCollectionLiteralArrayStorage(SortedObjects);
2640 Fields.add(ObjectsGV);
2643 llvm::GlobalVariable *GV = Fields.finishAndCreateGlobal(
2644 "_unnamed_nsdictionary_", Alignment,
2645 true, llvm::GlobalValue::PrivateLinkage);
2647 GV->setSection(GetNSConstantDictionarySectionName());
2648 GV->addAttribute(
"objc_arc_inert");
2650 return ConstantAddress(GV, GV->getValueType(), Alignment);
2658CodeGen::RValue CGObjCMac::GenerateMessageSendSuper(
2659 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
2660 Selector Sel,
const ObjCInterfaceDecl *
Class,
bool isCategoryImpl,
2661 llvm::Value *Receiver,
bool IsClassMessage,
2662 const CodeGen::CallArgList &CallArgs,
const ObjCMethodDecl *
Method) {
2667 llvm::Value *ReceiverAsObject =
2668 CGF.
Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
2673 llvm::Type *ClassTyPtr = llvm::PointerType::getUnqual(VMContext);
2675 if (IsClassMessage) {
2676 if (isCategoryImpl) {
2683 Target = EmitClassRef(CGF,
Class->getSuperClass());
2688 llvm::Constant *MetaClassPtr = EmitMetaClassRef(
Class);
2689 llvm::Value *SuperPtr =
2695 }
else if (isCategoryImpl)
2696 Target = EmitClassRef(CGF,
Class->getSuperClass());
2698 llvm::Value *ClassPtr = EmitSuperClassRef(
Class);
2705 llvm::Type *ClassTy =
2709 return EmitMessageSend(CGF, Return, ResultType, Sel, ObjCSuper.
getPointer(),
2710 ObjCTypes.SuperPtrCTy,
true, CallArgs,
Method,
Class,
2715CodeGen::RValue CGObjCMac::GenerateMessageSend(
2716 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
2717 Selector Sel, llvm::Value *Receiver,
const CallArgList &CallArgs,
2718 const ObjCInterfaceDecl *
Class,
const ObjCMethodDecl *
Method) {
2719 return EmitMessageSend(CGF, Return, ResultType, Sel, Receiver,
2724CodeGen::RValue CGObjCCommonMac::EmitMessageSend(
2725 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
2726 Selector Sel, llvm::Value *Arg0, QualType Arg0Ty,
bool IsSuper,
2727 const CallArgList &CallArgs,
const ObjCMethodDecl *
Method,
2728 const ObjCInterfaceDecl *ClassReceiver,
2729 const ObjCCommonTypesHelper &ObjCTypes) {
2730 CodeGenTypes &Types = CGM.
getTypes();
2732 llvm::Value *ReceiverValue =
2733 llvm::PoisonValue::get(Types.
ConvertType(Arg0Ty));
2734 llvm::Value *SelValue = llvm::UndefValue::get(Types.
ConvertType(selTy));
2736 CallArgList ActualArgs;
2738 Arg0 = CGF.
Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy);
2745 MessageSendInfo MSI = getMessageSendInfo(
Method, ResultType, ActualArgs);
2750 "Result type mismatch!");
2752 bool ReceiverCanBeNull =
2753 canMessageReceiverBeNull(CGF,
Method, IsSuper, ClassReceiver, Arg0);
2754 bool ClassObjectCanBeUnrealized =
2756 canClassObjectBeUnrealized(ClassReceiver, CGF);
2758 bool RequiresNullCheck =
false;
2759 bool RequiresReceiverValue =
true;
2760 bool RequiresSelValue =
true;
2762 llvm::FunctionCallee
Fn =
nullptr;
2766 ReceiverCanBeNull, ClassObjectCanBeUnrealized);
2769 RequiresSelValue =
false;
2771 if (ReceiverCanBeNull)
2772 RequiresNullCheck =
true;
2773 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
2774 : ObjCTypes.getSendStretFn(IsSuper);
2776 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
2777 : ObjCTypes.getSendFpretFn(IsSuper);
2779 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)
2780 : ObjCTypes.getSendFp2retFn(IsSuper);
2785 RequiresNullCheck =
true;
2787 StringRef ClassName;
2793 if (CGM.
getCodeGenOpts().ObjCMsgSendClassSelectorStubs && ClassReceiver &&
2795 !ClassReceiver->
hasAttr<ObjCClassStubAttr>() &&
2796 !ClassReceiver->
hasAttr<ObjCRuntimeVisibleAttr>() &&
2800 bool UseClassStub = ClassName.data();
2803 (CGM.
getCodeGenOpts().ObjCMsgSendSelectorStubs || UseClassStub)) {
2804 Fn = GenerateMethodSelectorStub(Sel, ClassName, ObjCTypes);
2806 RequiresReceiverValue = !UseClassStub;
2807 RequiresSelValue =
false;
2809 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
2810 : ObjCTypes.getSendFn(IsSuper);
2816 CGF.
Builder.CreateBitCast(
Fn.getCallee(), MSI.MessengerType));
2821 RequiresNullCheck =
false;
2824 if (!RequiresNullCheck &&
Method &&
Method->hasParamDestroyedInCallee())
2825 RequiresNullCheck =
true;
2832 if (ClassReceiver && ClassObjectCanBeUnrealized) {
2834 Arg0 = GenerateClassRealization(CGF, Arg0, ClassReceiver);
2835 ActualArgs[0] = CallArg(
RValue::get(Arg0), ActualArgs[0].Ty);
2841 RequiresNullCheck |= ReceiverCanBeNull;
2844 NullReturnState nullReturn;
2845 if (RequiresNullCheck) {
2846 nullReturn.init(CGF, Arg0);
2850 if (RequiresReceiverValue)
2851 ActualArgs[0] = CallArg(
RValue::get(Arg0), Arg0Ty);
2854 if (RequiresSelValue) {
2855 SelValue = GetSelector(CGF, Sel);
2856 ActualArgs[1] = CallArg(
RValue::get(SelValue), selTy);
2859 llvm::CallBase *CallSite;
2862 CGF.
EmitCall(MSI.CallInfo, Callee, Return, ActualArgs, &CallSite);
2866 if (
Method &&
Method->hasAttr<NoReturnAttr>() && !ReceiverCanBeNull) {
2867 CallSite->setDoesNotReturn();
2870 return nullReturn.complete(CGF, Return, rvalue, ResultType, CallArgs,
2871 RequiresNullCheck ?
Method :
nullptr);
2875 bool pointee =
false) {
2889 switch (ownership) {
2897 llvm_unreachable(
"autoreleasing ivar?");
2899 llvm_unreachable(
"known nonzero");
2901 llvm_unreachable(
"bad objc ownership");
2921 IvarInfo(CharUnits offset, uint64_t sizeInWords)
2922 : Offset(offset), SizeInWords(sizeInWords) {}
2925 bool operator<(
const IvarInfo &other)
const {
return Offset < other.Offset; }
2929class IvarLayoutBuilder {
2934 CharUnits InstanceBegin;
2937 CharUnits InstanceEnd;
2940 bool ForStrongLayout;
2943 bool IsDisordered =
false;
2945 llvm::SmallVector<IvarInfo, 8> IvarsInfo;
2948 IvarLayoutBuilder(CodeGenModule &CGM, CharUnits instanceBegin,
2949 CharUnits instanceEnd,
bool forStrongLayout)
2950 : CGM(CGM), InstanceBegin(instanceBegin), InstanceEnd(instanceEnd),
2951 ForStrongLayout(forStrongLayout) {}
2953 void visitRecord(
const RecordType *RT, CharUnits offset);
2955 template <
class Iterator,
class GetOffsetFn>
2956 void visitAggregate(Iterator begin, Iterator end, CharUnits aggrOffset,
2957 const GetOffsetFn &getOffset);
2959 void visitField(
const FieldDecl *field, CharUnits offset);
2962 void visitBlock(
const CGBlockInfo &blockInfo);
2965 bool hasBitmapData()
const {
return !IvarsInfo.empty(); }
2967 llvm::Constant *buildBitmap(CGObjCCommonMac &CGObjC,
2968 llvm::SmallVectorImpl<unsigned char> &buffer);
2970 static void dump(ArrayRef<unsigned char> buffer) {
2971 const unsigned char *
s = buffer.data();
2972 for (
unsigned i = 0, e = buffer.size(); i < e; i++)
2974 printf(
"0x0%x%s",
s[i],
s[i] != 0 ?
", " :
"");
2976 printf(
"0x%x%s",
s[i],
s[i] != 0 ?
", " :
"");
2983CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,
2984 const CGBlockInfo &blockInfo) {
2986 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2987 if (CGM.
getLangOpts().getGC() == LangOptions::NonGC)
2993 builder.visitBlock(blockInfo);
2995 if (!builder.hasBitmapData())
2998 llvm::SmallVector<unsigned char, 32> buffer;
2999 llvm::Constant *
C = builder.buildBitmap(*
this, buffer);
3000 if (CGM.
getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
3001 printf(
"\n block variable layout for block: ");
3002 builder.dump(buffer);
3008void IvarLayoutBuilder::visitBlock(
const CGBlockInfo &blockInfo) {
3018 CharUnits lastFieldOffset;
3021 for (
const auto &CI :
blockDecl->captures()) {
3022 const VarDecl *variable = CI.getVariable();
3025 const CGBlockInfo::Capture &capture = blockInfo.
getCapture(variable);
3031 CharUnits fieldOffset = capture.
getOffset();
3035 if (fieldOffset < lastFieldOffset)
3036 IsDisordered =
true;
3037 lastFieldOffset = fieldOffset;
3041 IvarsInfo.push_back(IvarInfo(fieldOffset, 1));
3045 assert(!
type->isArrayType() &&
"array variable should not be caught");
3046 if (
const RecordType *record =
type->getAsCanonical<RecordType>()) {
3047 visitRecord(record, fieldOffset);
3056 IvarsInfo.push_back(IvarInfo(fieldOffset, 1));
3065CGObjCCommonMac::getBlockCaptureLifetime(QualType FQT,
bool ByrefLayout) {
3081void CGObjCCommonMac::UpdateRunSkipBlockVars(
bool IsByref,
3083 CharUnits FieldOffset,
3084 CharUnits FieldSize) {
3087 RunSkipBlockVars.push_back(
3088 RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset, FieldSize));
3090 RunSkipBlockVars.push_back(
3091 RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset, FieldSize));
3093 RunSkipBlockVars.push_back(
3094 RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset, FieldSize));
3096 RunSkipBlockVars.push_back(
3097 RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset, FieldSize));
3099 RunSkipBlockVars.push_back(
3100 RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES, FieldOffset, FieldSize));
3103void CGObjCCommonMac::BuildRCRecordLayout(
const llvm::StructLayout *RecLayout,
3104 const RecordDecl *RD,
3105 ArrayRef<const FieldDecl *> RecFields,
3106 CharUnits BytePos,
bool &HasUnion,
3108 bool IsUnion = (RD && RD->
isUnion());
3110 const FieldDecl *MaxField =
nullptr;
3111 const FieldDecl *LastFieldBitfieldOrUnnamed =
nullptr;
3115 if (RecFields.empty())
3119 for (
unsigned i = 0, e = RecFields.size(); i != e; ++i) {
3120 const FieldDecl *
Field = RecFields[i];
3124 CharUnits FieldOffset =
3128 if (!
Field->getIdentifier() ||
Field->isBitField()) {
3129 LastFieldBitfieldOrUnnamed =
Field;
3130 LastBitfieldOrUnnamedOffset = FieldOffset;
3134 LastFieldBitfieldOrUnnamed =
nullptr;
3135 QualType FQT =
Field->getType();
3141 BytePos + FieldOffset, HasUnion);
3147 uint64_t ElCount = CArray->getZExtSize();
3148 assert(CArray &&
"only array with known element size is supported");
3149 FQT = CArray->getElementType();
3152 ElCount *= CArray->getZExtSize();
3153 FQT = CArray->getElementType();
3156 int OldIndex = RunSkipBlockVars.size() - 1;
3158 BuildRCBlockVarRecordLayout(RT, BytePos + FieldOffset, HasUnion);
3163 for (
int FirstIndex = RunSkipBlockVars.size() - 1; ElIx < ElCount;
3166 for (
int i = OldIndex + 1; i <= FirstIndex; ++i)
3167 RunSkipBlockVars.push_back(
3168 RUN_SKIP(RunSkipBlockVars[i].opcode,
3169 RunSkipBlockVars[i].block_var_bytepos + Size * ElIx,
3170 RunSkipBlockVars[i].block_var_size));
3177 CharUnits UnionIvarSize = FieldSize;
3178 if (UnionIvarSize > MaxUnionSize) {
3179 MaxUnionSize = UnionIvarSize;
3181 MaxFieldOffset = FieldOffset;
3184 UpdateRunSkipBlockVars(
false, getBlockCaptureLifetime(FQT, ByrefLayout),
3185 BytePos + FieldOffset, FieldSize);
3189 if (LastFieldBitfieldOrUnnamed) {
3190 if (LastFieldBitfieldOrUnnamed->
isBitField()) {
3193 unsigned UnsSize = (BitFieldSize / ByteSizeInBits) +
3194 ((BitFieldSize % ByteSizeInBits) != 0);
3196 Size += LastBitfieldOrUnnamedOffset;
3197 UpdateRunSkipBlockVars(
3199 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
3201 BytePos + LastBitfieldOrUnnamedOffset, Size);
3204 "Expected unnamed");
3207 LastFieldBitfieldOrUnnamed->
getType());
3208 UpdateRunSkipBlockVars(
3210 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
3212 BytePos + LastBitfieldOrUnnamedOffset, FieldSize);
3217 UpdateRunSkipBlockVars(
3218 false, getBlockCaptureLifetime(MaxField->
getType(), ByrefLayout),
3219 BytePos + MaxFieldOffset, MaxUnionSize);
3222void CGObjCCommonMac::BuildRCBlockVarRecordLayout(
const RecordType *RT,
3226 const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
3227 SmallVector<const FieldDecl *, 16> Fields(RD->
fields());
3229 const llvm::StructLayout *RecLayout =
3232 BuildRCRecordLayout(RecLayout, RD, Fields, BytePos, HasUnion, ByrefLayout);
3244uint64_t CGObjCCommonMac::InlineLayoutInstruction(
3245 SmallVectorImpl<unsigned char> &Layout) {
3247 if (Layout.size() <= 3) {
3248 unsigned size = Layout.size();
3249 unsigned strong_word_count = 0, byref_word_count = 0, weak_word_count = 0;
3251 enum BLOCK_LAYOUT_OPCODE opcode;
3255 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3256 if (opcode == BLOCK_LAYOUT_STRONG)
3257 strong_word_count = (inst & 0xF) + 1;
3261 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3262 if (opcode == BLOCK_LAYOUT_BYREF)
3263 byref_word_count = (inst & 0xF) + 1;
3267 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3268 if (opcode == BLOCK_LAYOUT_WEAK)
3269 weak_word_count = (inst & 0xF) + 1;
3276 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3277 if (opcode == BLOCK_LAYOUT_STRONG) {
3278 strong_word_count = (inst & 0xF) + 1;
3280 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3281 if (opcode == BLOCK_LAYOUT_BYREF)
3282 byref_word_count = (inst & 0xF) + 1;
3283 else if (opcode == BLOCK_LAYOUT_WEAK)
3284 weak_word_count = (inst & 0xF) + 1;
3287 }
else if (opcode == BLOCK_LAYOUT_BYREF) {
3288 byref_word_count = (inst & 0xF) + 1;
3290 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3291 if (opcode == BLOCK_LAYOUT_WEAK)
3292 weak_word_count = (inst & 0xF) + 1;
3301 opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3302 if (opcode == BLOCK_LAYOUT_STRONG)
3303 strong_word_count = (inst & 0xF) + 1;
3304 else if (opcode == BLOCK_LAYOUT_BYREF)
3305 byref_word_count = (inst & 0xF) + 1;
3306 else if (opcode == BLOCK_LAYOUT_WEAK)
3307 weak_word_count = (inst & 0xF) + 1;
3319 if (strong_word_count == 16 || byref_word_count == 16 ||
3320 weak_word_count == 16)
3323 unsigned count = (strong_word_count != 0) + (byref_word_count != 0) +
3324 (weak_word_count != 0);
3326 if (size == count) {
3327 if (strong_word_count)
3328 Result = strong_word_count;
3330 if (byref_word_count)
3331 Result += byref_word_count;
3333 if (weak_word_count)
3334 Result += weak_word_count;
3340llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(
bool ComputeByrefLayout) {
3341 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
3342 if (RunSkipBlockVars.empty())
3346 unsigned WordSizeInBytes = WordSizeInBits / ByteSizeInBits;
3350 llvm::array_pod_sort(RunSkipBlockVars.begin(), RunSkipBlockVars.end());
3351 SmallVector<unsigned char, 16> Layout;
3353 unsigned size = RunSkipBlockVars.size();
3354 for (
unsigned i = 0; i < size; i++) {
3355 enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode;
3356 CharUnits start_byte_pos = RunSkipBlockVars[i].block_var_bytepos;
3357 CharUnits end_byte_pos = start_byte_pos;
3360 if (opcode == RunSkipBlockVars[j].opcode) {
3361 end_byte_pos = RunSkipBlockVars[j++].block_var_bytepos;
3366 CharUnits size_in_bytes =
3367 end_byte_pos - start_byte_pos + RunSkipBlockVars[j - 1].block_var_size;
3369 CharUnits gap = RunSkipBlockVars[j].block_var_bytepos -
3370 RunSkipBlockVars[j - 1].block_var_bytepos -
3371 RunSkipBlockVars[j - 1].block_var_size;
3372 size_in_bytes += gap;
3375 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) {
3376 residue_in_bytes = size_in_bytes % WordSizeInBytes;
3377 size_in_bytes -= residue_in_bytes;
3378 opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS;
3381 unsigned size_in_words = size_in_bytes.
getQuantity() / WordSizeInBytes;
3382 while (size_in_words >= 16) {
3385 unsigned char inst = (opcode << 4) | 0xf;
3386 Layout.push_back(inst);
3387 size_in_words -= 16;
3389 if (size_in_words > 0) {
3392 unsigned char inst = (opcode << 4) | (size_in_words - 1);
3393 Layout.push_back(inst);
3396 unsigned char inst = (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) |
3398 Layout.push_back(inst);
3402 while (!Layout.empty()) {
3403 unsigned char inst = Layout.back();
3404 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3405 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES ||
3406 opcode == BLOCK_LAYOUT_NON_OBJECT_WORDS)
3416 if (ComputeByrefLayout)
3417 printf(
"\n Inline BYREF variable layout: ");
3419 printf(
"\n Inline block variable layout: ");
3421 if (
auto numStrong = (
Result & 0xF00) >> 8)
3422 printf(
", BL_STRONG:%d", (
int)numStrong);
3423 if (
auto numByref = (
Result & 0x0F0) >> 4)
3424 printf(
", BL_BYREF:%d", (
int)numByref);
3425 if (
auto numWeak = (
Result & 0x00F) >> 0)
3426 printf(
", BL_WEAK:%d", (
int)numWeak);
3427 printf(
", BL_OPERATOR:0\n");
3432 unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0;
3433 Layout.push_back(inst);
3435 for (
unsigned char C : Layout)
3439 if (ComputeByrefLayout)
3440 printf(
"\n Byref variable layout: ");
3442 printf(
"\n Block variable layout: ");
3443 for (
unsigned i = 0, e = BitMap.size(); i != e; i++) {
3444 unsigned char inst = BitMap[i];
3445 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE)(inst >> 4);
3448 case BLOCK_LAYOUT_OPERATOR:
3452 case BLOCK_LAYOUT_NON_OBJECT_BYTES:
3453 printf(
"BL_NON_OBJECT_BYTES:");
3455 case BLOCK_LAYOUT_NON_OBJECT_WORDS:
3456 printf(
"BL_NON_OBJECT_WORD:");
3458 case BLOCK_LAYOUT_STRONG:
3461 case BLOCK_LAYOUT_BYREF:
3464 case BLOCK_LAYOUT_WEAK:
3467 case BLOCK_LAYOUT_UNRETAINED:
3468 printf(
"BL_UNRETAINED:");
3473 printf(
"%d", (inst & 0xf) + delta);
3481 auto *Entry = CreateCStringLiteral(BitMap, ObjCLabelType::LayoutBitMap,
3489 bool HasCopyDisposeHelpers) {
3491 for (
const CGObjCCommonMac::RUN_SKIP &R : RunSkipBlockVars) {
3492 if (R.opcode == CGObjCCommonMac::BLOCK_LAYOUT_UNRETAINED) {
3496 }
else if (HasCopyDisposeHelpers) {
3504 case CGObjCCommonMac::BLOCK_LAYOUT_STRONG:
3507 case CGObjCCommonMac::BLOCK_LAYOUT_BYREF:
3510 case CGObjCCommonMac::BLOCK_LAYOUT_WEAK:
3517 Str += llvm::to_string(R.block_var_bytepos.getQuantity());
3518 Str +=
"l" + llvm::to_string(R.block_var_size.getQuantity());
3523void CGObjCCommonMac::fillRunSkipBlockVars(CodeGenModule &CGM,
3524 const CGBlockInfo &blockInfo) {
3525 assert(CGM.
getLangOpts().getGC() == LangOptions::NonGC);
3527 RunSkipBlockVars.clear();
3528 bool hasUnion =
false;
3532 unsigned WordSizeInBytes = WordSizeInBits / ByteSizeInBits;
3537 const llvm::StructLayout *layout =
3547 for (
const auto &CI :
blockDecl->captures()) {
3548 const VarDecl *variable = CI.getVariable();
3551 const CGBlockInfo::Capture &capture = blockInfo.
getCapture(variable);
3557 CharUnits fieldOffset =
3560 assert(!
type->isArrayType() &&
"array variable should not be caught");
3562 if (
const auto *record =
type->getAsCanonical<RecordType>()) {
3563 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion);
3566 CharUnits fieldSize;
3571 UpdateRunSkipBlockVars(CI.isByRef(), getBlockCaptureLifetime(
type,
false),
3572 fieldOffset, fieldSize);
3577CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM,
3578 const CGBlockInfo &blockInfo) {
3579 fillRunSkipBlockVars(CGM, blockInfo);
3580 return getBitmapBlockLayout(
false);
3583std::string CGObjCCommonMac::getRCBlockLayoutStr(CodeGenModule &CGM,
3584 const CGBlockInfo &blockInfo) {
3585 fillRunSkipBlockVars(CGM, blockInfo);
3589llvm::Constant *CGObjCCommonMac::BuildByrefLayout(CodeGen::CodeGenModule &CGM,
3591 assert(CGM.
getLangOpts().getGC() == LangOptions::NonGC);
3592 assert(!T->
isArrayType() &&
"__block array variable should not be caught");
3593 CharUnits fieldOffset;
3594 RunSkipBlockVars.clear();
3595 bool hasUnion =
false;
3597 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion,
3599 llvm::Constant *
Result = getBitmapBlockLayout(
true);
3604 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
3608llvm::Value *CGObjCMac::GenerateProtocolRef(CodeGenFunction &CGF,
3609 const ObjCProtocolDecl *PD) {
3614 return GetProtocolRef(PD);
3617void CGObjCCommonMac::GenerateProtocol(
const ObjCProtocolDecl *PD) {
3626 GetOrEmitProtocol(PD);
3629llvm::Constant *CGObjCCommonMac::GetProtocolRef(
const ObjCProtocolDecl *PD) {
3631 return GetOrEmitProtocol(PD);
3633 return GetOrEmitProtocolRef(PD);
3637CGObjCCommonMac::EmitClassRefViaRuntime(CodeGenFunction &CGF,
3638 const ObjCInterfaceDecl *ID,
3639 ObjCCommonTypesHelper &ObjCTypes) {
3640 llvm::FunctionCallee lookUpClassFn = ObjCTypes.getLookUpClassFn();
3642 llvm::Value *className = CGF.
CGM
3644 ID->getObjCRuntimeNameAsString()))
3647 className = CGF.
Builder.CreateBitCast(
3649 llvm::CallInst *call = CGF.
Builder.CreateCall(lookUpClassFn, className);
3650 call->setDoesNotThrow();
3666llvm::Constant *CGObjCMac::GetOrEmitProtocol(
const ObjCProtocolDecl *PD) {
3667 llvm::GlobalVariable *Entry = Protocols[PD->
getIdentifier()];
3670 if (Entry && Entry->hasInitializer())
3682 auto methodLists = ProtocolMethodLists::get(PD);
3684 ConstantInitBuilder builder(CGM);
3685 auto values = builder.beginStruct(ObjCTypes.ProtocolTy);
3686 values.add(EmitProtocolExtension(PD, methodLists));
3688 values.add(EmitProtocolList(
"OBJC_PROTOCOL_REFS_" + PD->
getName(),
3690 values.add(methodLists.emitMethodList(
3691 this, PD, ProtocolMethodLists::RequiredInstanceMethods));
3692 values.add(methodLists.emitMethodList(
3693 this, PD, ProtocolMethodLists::RequiredClassMethods));
3697 assert(Entry->hasPrivateLinkage());
3698 values.finishAndSetAsInitializer(Entry);
3700 Entry = values.finishAndCreateGlobal(
3702 false, llvm::GlobalValue::PrivateLinkage);
3703 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
3712llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD) {
3713 llvm::GlobalVariable *&Entry = Protocols[PD->
getIdentifier()];
3719 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolTy,
3720 false, llvm::GlobalValue::PrivateLinkage,
3721 nullptr,
"OBJC_PROTOCOL_" + PD->
getName());
3722 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
3724 Entry->setAlignment(llvm::Align(4));
3741CGObjCMac::EmitProtocolExtension(
const ObjCProtocolDecl *PD,
3742 const ProtocolMethodLists &methodLists) {
3743 auto optInstanceMethods = methodLists.emitMethodList(
3744 this, PD, ProtocolMethodLists::OptionalInstanceMethods);
3745 auto optClassMethods = methodLists.emitMethodList(
3746 this, PD, ProtocolMethodLists::OptionalClassMethods);
3748 auto extendedMethodTypes = EmitProtocolMethodTypes(
3749 "OBJC_PROTOCOL_METHOD_TYPES_" + PD->
getName(),
3750 methodLists.emitExtendedTypesArray(
this), ObjCTypes);
3752 auto instanceProperties = EmitPropertyList(
3753 "OBJC_$_PROP_PROTO_LIST_" + PD->
getName(),
nullptr, PD, ObjCTypes,
false);
3754 auto classProperties =
3755 EmitPropertyList(
"OBJC_$_CLASS_PROP_PROTO_LIST_" + PD->
getName(),
nullptr,
3756 PD, ObjCTypes,
true);
3759 if (optInstanceMethods->isNullValue() && optClassMethods->isNullValue() &&
3760 extendedMethodTypes->isNullValue() && instanceProperties->isNullValue() &&
3761 classProperties->isNullValue()) {
3762 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
3766 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
3768 ConstantInitBuilder builder(CGM);
3769 auto values = builder.beginStruct(ObjCTypes.ProtocolExtensionTy);
3770 values.addInt(ObjCTypes.IntTy, size);
3771 values.add(optInstanceMethods);
3772 values.add(optClassMethods);
3773 values.add(instanceProperties);
3774 values.add(extendedMethodTypes);
3775 values.add(classProperties);
3778 return CreateMetadataVar(
"_OBJC_PROTOCOLEXT_" + PD->
getName(), values,
3790CGObjCMac::EmitProtocolList(Twine name,
3794 auto PDs = GetRuntimeProtocolList(begin, end);
3796 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
3798 ConstantInitBuilder builder(CGM);
3799 auto values = builder.beginStruct();
3802 values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
3805 auto countSlot = values.addPlaceholder();
3807 auto refsArray = values.beginArray(ObjCTypes.ProtocolPtrTy);
3808 for (
const auto *Proto : PDs)
3809 refsArray.add(GetProtocolRef(Proto));
3811 auto count = refsArray.size();
3814 refsArray.addNullPointer(ObjCTypes.ProtocolPtrTy);
3816 refsArray.finishAndAddTo(values);
3817 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
3820 if (CGM.
getTriple().isOSBinFormatMachO())
3821 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3823 llvm::GlobalVariable *GV =
3824 CreateMetadataVar(name, values, section, CGM.
getPointerAlign(),
false);
3833 if (IsClassProperty != PD->isClassProperty())
3837 Properties.push_back(PD);
3840 for (
const auto *P : Proto->
protocols())
3856llvm::Constant *CGObjCCommonMac::EmitPropertyList(
3857 Twine Name,
const Decl *Container,
const ObjCContainerDecl *OCD,
3858 const ObjCCommonTypesHelper &ObjCTypes,
bool IsClassProperty) {
3859 if (IsClassProperty) {
3863 if ((Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 11)) ||
3864 (Triple.isiOS() && Triple.isOSVersionLT(9)))
3865 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3868 SmallVector<const ObjCPropertyDecl *, 16> Properties;
3869 llvm::SmallPtrSet<const IdentifierInfo *, 16> PropertySet;
3871 if (
const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD))
3872 for (
const ObjCCategoryDecl *ClassExt : OID->known_extensions())
3873 for (
auto *PD : ClassExt->properties()) {
3874 if (IsClassProperty != PD->isClassProperty())
3876 if (PD->isDirectProperty())
3879 Properties.push_back(PD);
3883 if (IsClassProperty != PD->isClassProperty())
3889 if (PD->isDirectProperty())
3891 Properties.push_back(PD);
3894 if (
const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) {
3895 for (
const auto *P : OID->all_referenced_protocols())
3897 }
else if (
const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD)) {
3898 for (
const auto *P : CD->protocols())
3903 if (Properties.empty())
3904 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3906 unsigned propertySize =
3909 ConstantInitBuilder builder(CGM);
3910 auto values = builder.beginStruct();
3911 values.addInt(ObjCTypes.IntTy, propertySize);
3912 values.addInt(ObjCTypes.IntTy, Properties.size());
3913 auto propertiesArray = values.beginArray(ObjCTypes.PropertyTy);
3914 for (
auto PD : Properties) {
3915 auto property = propertiesArray.beginStruct(ObjCTypes.PropertyTy);
3917 property.add(GetPropertyTypeString(PD, Container));
3918 property.finishAndAddTo(propertiesArray);
3920 propertiesArray.finishAndAddTo(values);
3923 if (CGM.
getTriple().isOSBinFormatMachO())
3924 Section = (ObjCABI == 2) ?
"__DATA, __objc_const"
3925 :
"__OBJC,__property,regular,no_dead_strip";
3927 llvm::GlobalVariable *GV =
3928 CreateMetadataVar(Name, values, Section, CGM.
getPointerAlign(),
true);
3932llvm::Constant *CGObjCCommonMac::EmitProtocolMethodTypes(
3933 Twine Name, ArrayRef<llvm::Constant *> MethodTypes,
3934 const ObjCCommonTypesHelper &ObjCTypes) {
3936 if (MethodTypes.empty())
3937 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy);
3939 llvm::ArrayType *AT =
3940 llvm::ArrayType::get(ObjCTypes.Int8PtrTy, MethodTypes.size());
3941 llvm::Constant *
Init = llvm::ConstantArray::get(AT, MethodTypes);
3944 if (CGM.
getTriple().isOSBinFormatMachO() && ObjCABI == 2)
3945 Section =
"__DATA, __objc_const";
3947 llvm::GlobalVariable *GV =
3964void CGObjCMac::GenerateCategory(
const ObjCCategoryImplDecl *OCD) {
3972 const ObjCCategoryDecl *Category =
3975 SmallString<256> ExtName;
3976 llvm::raw_svector_ostream(ExtName)
3979 ConstantInitBuilder Builder(CGM);
3980 auto Values = Builder.beginStruct(ObjCTypes.CategoryTy);
3982 enum { InstanceMethods, ClassMethods, NumMethodLists };
3983 SmallVector<const ObjCMethodDecl *, 16> Methods[NumMethodLists];
3984 for (
const auto *MD : OCD->
methods()) {
3985 if (!MD->isDirectMethod())
3986 Methods[unsigned(MD->isClassMethod())].push_back(MD);
3989 Values.add(GetClassName(OCD->
getName()));
3990 Values.add(GetClassName(
Interface->getObjCRuntimeNameAsString()));
3991 LazySymbols.insert(
Interface->getIdentifier());
3993 Values.add(emitMethodList(ExtName, MethodListType::CategoryInstanceMethods,
3994 Methods[InstanceMethods]));
3995 Values.add(emitMethodList(ExtName, MethodListType::CategoryClassMethods,
3996 Methods[ClassMethods]));
3998 Values.add(EmitProtocolList(
"OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
3999 Category->protocol_begin(),
4000 Category->protocol_end()));
4002 Values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
4004 Values.addInt(ObjCTypes.IntTy, Size);
4008 Values.add(EmitPropertyList(
"_OBJC_$_PROP_LIST_" + ExtName.str(), OCD,
4009 Category, ObjCTypes,
false));
4010 Values.add(EmitPropertyList(
"_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(), OCD,
4011 Category, ObjCTypes,
true));
4013 Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
4014 Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
4017 llvm::GlobalVariable *GV = CreateMetadataVar(
4018 "OBJC_CATEGORY_" + ExtName.str(), Values,
4019 "__OBJC,__category,regular,no_dead_strip", CGM.
getPointerAlign(),
true);
4020 DefinedCategories.push_back(GV);
4021 DefinedCategoryNames.insert(llvm::CachedHashString(ExtName));
4023 MethodDefinitions.clear();
4084 if (
auto *RD =
type->getAsRecordDecl()) {
4085 for (
auto *field : RD->
fields()) {
4104 ID->getClassInterface()->all_declared_ivar_begin();
4132void CGObjCMac::GenerateClass(
const ObjCImplementationDecl *ID) {
4133 IdentifierInfo *RuntimeName =
4135 DefinedSymbols.insert(RuntimeName);
4137 std::string ClassName =
ID->getNameAsString();
4140 const_cast<ObjCInterfaceDecl *
>(
ID->getClassInterface());
4141 llvm::Constant *Protocols =
4142 EmitProtocolList(
"OBJC_CLASS_PROTOCOLS_" +
ID->getName(),
4143 Interface->all_referenced_protocol_begin(),
4144 Interface->all_referenced_protocol_end());
4146 if (
ID->hasNonZeroConstructors() ||
ID->hasDestructors())
4149 bool hasMRCWeak =
false;
4164 enum { InstanceMethods, ClassMethods, NumMethodLists };
4165 SmallVector<const ObjCMethodDecl *, 16> Methods[NumMethodLists];
4166 for (
const auto *MD :
ID->methods()) {
4167 if (!MD->isDirectMethod())
4168 Methods[unsigned(MD->isClassMethod())].push_back(MD);
4171 for (
const auto *PID :
ID->property_impls()) {
4173 if (PID->getPropertyDecl()->isDirectProperty())
4175 if (ObjCMethodDecl *MD = PID->getGetterMethodDecl())
4176 if (GetMethodDefinition(MD))
4177 Methods[InstanceMethods].push_back(MD);
4178 if (ObjCMethodDecl *MD = PID->getSetterMethodDecl())
4179 if (GetMethodDefinition(MD))
4180 Methods[InstanceMethods].push_back(MD);
4184 ConstantInitBuilder builder(CGM);
4185 auto values = builder.beginStruct(ObjCTypes.ClassTy);
4186 values.add(EmitMetaClass(ID, Protocols, Methods[ClassMethods]));
4187 if (ObjCInterfaceDecl *Super =
Interface->getSuperClass()) {
4189 LazySymbols.insert(Super->getIdentifier());
4191 values.add(GetClassName(Super->getObjCRuntimeNameAsString()));
4193 values.addNullPointer(ObjCTypes.ClassPtrTy);
4195 values.add(GetClassName(
ID->getObjCRuntimeNameAsString()));
4197 values.addInt(ObjCTypes.LongTy, 0);
4198 values.addInt(ObjCTypes.LongTy, Flags);
4199 values.addInt(ObjCTypes.LongTy,
Size.getQuantity());
4200 values.add(EmitIvarList(ID,
false));
4201 values.add(emitMethodList(
ID->getName(), MethodListType::InstanceMethods,
4202 Methods[InstanceMethods]));
4204 values.addNullPointer(ObjCTypes.CachePtrTy);
4205 values.add(Protocols);
4207 values.add(EmitClassExtension(ID, Size, hasMRCWeak,
4210 std::string Name(
"OBJC_CLASS_");
4212 const char *Section =
"__OBJC,__class,regular,no_dead_strip";
4214 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
4216 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4217 "Forward metaclass reference has incorrect type.");
4218 values.finishAndSetAsInitializer(GV);
4219 GV->setSection(Section);
4223 GV = CreateMetadataVar(Name, values, Section, CGM.
getPointerAlign(),
true);
4224 DefinedClasses.push_back(GV);
4225 ImplementedClasses.push_back(
Interface);
4227 MethodDefinitions.clear();
4231CGObjCMac::EmitMetaClass(
const ObjCImplementationDecl *ID,
4232 llvm::Constant *Protocols,
4233 ArrayRef<const ObjCMethodDecl *> Methods) {
4240 ConstantInitBuilder builder(CGM);
4241 auto values = builder.beginStruct(ObjCTypes.ClassTy);
4243 const ObjCInterfaceDecl *Root =
ID->getClassInterface();
4244 while (
const ObjCInterfaceDecl *Super = Root->
getSuperClass())
4250 if (ObjCInterfaceDecl *Super =
ID->getClassInterface()->getSuperClass()) {
4251 values.add(GetClassName(Super->getObjCRuntimeNameAsString()));
4253 values.addNullPointer(ObjCTypes.ClassPtrTy);
4255 values.add(GetClassName(
ID->getObjCRuntimeNameAsString()));
4257 values.addInt(ObjCTypes.LongTy, 0);
4258 values.addInt(ObjCTypes.LongTy, Flags);
4259 values.addInt(ObjCTypes.LongTy, Size);
4260 values.add(EmitIvarList(ID,
true));
4262 emitMethodList(
ID->getName(), MethodListType::ClassMethods, Methods));
4264 values.addNullPointer(ObjCTypes.CachePtrTy);
4265 values.add(Protocols);
4267 values.addNullPointer(ObjCTypes.Int8PtrTy);
4272 std::string Name(
"OBJC_METACLASS_");
4273 Name +=
ID->getName();
4276 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
4278 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4279 "Forward metaclass reference has incorrect type.");
4280 values.finishAndSetAsInitializer(GV);
4284 llvm::GlobalValue::PrivateLinkage);
4286 GV->setSection(
"__OBJC,__meta_class,regular,no_dead_strip");
4292llvm::Constant *CGObjCMac::EmitMetaClassRef(
const ObjCInterfaceDecl *ID) {
4293 std::string Name =
"OBJC_METACLASS_" +
ID->getNameAsString();
4303 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
4305 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
4306 llvm::GlobalValue::PrivateLinkage,
nullptr,
4309 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4310 "Forward metaclass reference has incorrect type.");
4314llvm::Value *CGObjCMac::EmitSuperClassRef(
const ObjCInterfaceDecl *ID) {
4315 std::string Name =
"OBJC_CLASS_" +
ID->getNameAsString();
4316 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
4319 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
4320 llvm::GlobalValue::PrivateLinkage,
nullptr,
4323 assert(GV->getValueType() == ObjCTypes.ClassTy &&
4324 "Forward class metadata reference has incorrect type.");
4339llvm::Constant *CGObjCMac::EmitClassExtension(
const ObjCImplementationDecl *ID,
4340 CharUnits InstanceSize,
4344 llvm::Constant *layout;
4346 layout = llvm::ConstantPointerNull::get(CGM.
Int8PtrTy);
4353 llvm::Constant *propertyList =
4354 EmitPropertyList((isMetaclass ? Twine(
"_OBJC_$_CLASS_PROP_LIST_")
4355 : Twine(
"_OBJC_$_PROP_LIST_")) +
4357 ID,
ID->getClassInterface(), ObjCTypes, isMetaclass);
4360 if (layout->isNullValue() && propertyList->isNullValue()) {
4361 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
4365 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
4367 ConstantInitBuilder builder(CGM);
4368 auto values = builder.beginStruct(ObjCTypes.ClassExtensionTy);
4369 values.addInt(ObjCTypes.IntTy, size);
4371 values.add(propertyList);
4373 return CreateMetadataVar(
"OBJC_CLASSEXT_" +
ID->getName(), values,
4374 "__OBJC,__class_ext,regular,no_dead_strip",
4390llvm::Constant *CGObjCMac::EmitIvarList(
const ObjCImplementationDecl *ID,
4398 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
4400 const ObjCInterfaceDecl *OID =
ID->getClassInterface();
4402 ConstantInitBuilder builder(CGM);
4403 auto ivarList = builder.beginStruct();
4404 auto countSlot = ivarList.addPlaceholder();
4405 auto ivars = ivarList.beginArray(ObjCTypes.IvarTy);
4410 if (!IVD->getDeclName())
4413 auto ivar = ivars.beginStruct(ObjCTypes.IvarTy);
4414 ivar.add(GetMethodVarName(IVD->getIdentifier()));
4415 ivar.add(GetMethodVarType(IVD));
4416 ivar.addInt(ObjCTypes.IntTy, ComputeIvarBaseOffset(CGM, OID, IVD));
4417 ivar.finishAndAddTo(ivars);
4421 auto count = ivars.size();
4425 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
4428 ivars.finishAndAddTo(ivarList);
4429 ivarList.fillPlaceholderWithInt(countSlot, ObjCTypes.IntTy, count);
4431 llvm::GlobalVariable *GV;
4432 GV = CreateMetadataVar(
"OBJC_INSTANCE_VARIABLES_" +
ID->getName(), ivarList,
4433 "__OBJC,__instance_vars,regular,no_dead_strip",
4444void CGObjCMac::emitMethodDescriptionConstant(ConstantArrayBuilder &builder,
4445 const ObjCMethodDecl *MD) {
4446 auto description = builder.
beginStruct(ObjCTypes.MethodDescriptionTy);
4447 description.add(GetMethodVarName(MD->
getSelector()));
4448 description.add(GetMethodVarType(MD));
4449 description.finishAndAddTo(builder);
4459void CGObjCMac::emitMethodConstant(ConstantArrayBuilder &builder,
4460 const ObjCMethodDecl *MD) {
4461 llvm::Function *fn = GetMethodDefinition(MD);
4462 assert(fn &&
"no definition registered for method");
4464 auto method = builder.
beginStruct(ObjCTypes.MethodTy);
4466 method.add(GetMethodVarType(MD));
4468 method.finishAndAddTo(builder);
4485CGObjCMac::emitMethodList(Twine name, MethodListType MLT,
4486 ArrayRef<const ObjCMethodDecl *> methods) {
4489 bool forProtocol =
false;
4491 case MethodListType::CategoryInstanceMethods:
4492 prefix =
"OBJC_CATEGORY_INSTANCE_METHODS_";
4493 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
4494 forProtocol =
false;
4496 case MethodListType::CategoryClassMethods:
4497 prefix =
"OBJC_CATEGORY_CLASS_METHODS_";
4498 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
4499 forProtocol =
false;
4501 case MethodListType::InstanceMethods:
4502 prefix =
"OBJC_INSTANCE_METHODS_";
4503 section =
"__OBJC,__inst_meth,regular,no_dead_strip";
4504 forProtocol =
false;
4506 case MethodListType::ClassMethods:
4507 prefix =
"OBJC_CLASS_METHODS_";
4508 section =
"__OBJC,__cls_meth,regular,no_dead_strip";
4509 forProtocol =
false;
4511 case MethodListType::ProtocolInstanceMethods:
4512 prefix =
"OBJC_PROTOCOL_INSTANCE_METHODS_";
4513 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
4516 case MethodListType::ProtocolClassMethods:
4517 prefix =
"OBJC_PROTOCOL_CLASS_METHODS_";
4518 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
4521 case MethodListType::OptionalProtocolInstanceMethods:
4522 prefix =
"OBJC_PROTOCOL_INSTANCE_METHODS_OPT_";
4523 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
4526 case MethodListType::OptionalProtocolClassMethods:
4527 prefix =
"OBJC_PROTOCOL_CLASS_METHODS_OPT_";
4528 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
4534 if (methods.empty())
4535 return llvm::Constant::getNullValue(
4536 forProtocol ? ObjCTypes.MethodDescriptionListPtrTy
4537 : ObjCTypes.MethodListPtrTy);
4542 ConstantInitBuilder builder(CGM);
4544 values.addInt(ObjCTypes.IntTy, methods.size());
4545 auto methodArray = values.beginArray(ObjCTypes.MethodDescriptionTy);
4546 for (
auto MD : methods) {
4547 emitMethodDescriptionConstant(methodArray, MD);
4549 methodArray.finishAndAddTo(values);
4551 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
4557 ConstantInitBuilder builder(CGM);
4559 values.addNullPointer(ObjCTypes.Int8PtrTy);
4560 values.addInt(ObjCTypes.IntTy, methods.size());
4561 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
4562 for (
auto MD : methods) {
4564 emitMethodConstant(methodArray, MD);
4566 methodArray.finishAndAddTo(values);
4568 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
4573llvm::Function *CGObjCCommonMac::GenerateMethod(
const ObjCMethodDecl *OMD,
4574 const ObjCContainerDecl *CD) {
4579 DirectMethodInfo &Info = GenerateDirectMethod(OMD, CD);
4580 Method = Info.Implementation;
4582 auto Name = getSymbolNameForMethod(OMD);
4584 CodeGenTypes &Types = CGM.
getTypes();
4585 llvm::FunctionType *MethodTy =
4587 Method = llvm::Function::Create(
4588 MethodTy, llvm::GlobalValue::InternalLinkage, Name, &CGM.
getModule());
4591 MethodDefinitions.insert(std::make_pair(OMD,
Method));
4597CGObjCCommonMac::DirectMethodInfo &
4598CGObjCCommonMac::GenerateDirectMethod(
const ObjCMethodDecl *OMD,
4599 const ObjCContainerDecl *CD) {
4604 auto Cached = DirectMethodDefinitions.find(COMD);
4605 if (Cached != DirectMethodDefinitions.end()) {
4607 return Cached->second;
4610 CodeGenTypes &Types = CGM.
getTypes();
4611 llvm::FunctionType *MethodTy =
4614 getSymbolNameForMethod(OMD,
false,
4616 std::string ThunkName = Name +
"_thunk";
4619 auto ReplaceFunction = [](llvm::Function *OldFn, llvm::Function *NewFn) {
4620 NewFn->takeName(OldFn);
4621 OldFn->replaceAllUsesWith(NewFn);
4622 OldFn->eraseFromParent();
4627 llvm::Function *
Fn = CGM.
getModule().getFunction(Name);
4631 Fn = llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,
4633 return DirectMethodDefinitions.insert({COMD, DirectMethodInfo(Fn)})
4639 if (
Fn->getFunctionType() == MethodTy) {
4641 Fn->setLinkage(llvm::GlobalValue::ExternalLinkage);
4644 DirectMethodInfo Info(Fn);
4645 if (llvm::Function *Thunk = CGM.
getModule().getFunction(ThunkName))
4648 return DirectMethodDefinitions.insert({COMD, Info}).first->second;
4654 llvm::Function *NewFn = llvm::Function::Create(
4655 MethodTy, llvm::GlobalValue::ExternalLinkage,
"", &CGM.
getModule());
4656 ReplaceFunction(Fn, NewFn);
4659 DirectMethodInfo Info(NewFn);
4660 if (llvm::Function *OldThunk = CGM.
getModule().getFunction(ThunkName)) {
4661 llvm::Function *NewThunk = GenerateObjCDirectThunk(OMD, CD, NewFn);
4662 ReplaceFunction(OldThunk, NewThunk);
4663 Info.Thunk = NewThunk;
4666 if (Cached != DirectMethodDefinitions.end()) {
4667 Cached->second = Info;
4668 return Cached->second;
4670 return DirectMethodDefinitions.insert({COMD, Info}).first->second;
4736CGObjCCommonMac::GenerateObjCDirectThunk(
const ObjCMethodDecl *OMD,
4738 llvm::Function *Implementation) {
4741 "Should only generate thunk when optimization enabled");
4742 assert(Implementation &&
"Implementation must exist");
4744 llvm::FunctionType *ThunkTy = Implementation->getFunctionType();
4745 std::string ThunkName = Implementation->getName().str() +
"_thunk";
4748 llvm::Function *Thunk =
4749 llvm::Function::Create(ThunkTy, llvm::GlobalValue::LinkOnceODRLinkage,
4756 Thunk->setVisibility(llvm::GlobalValue::HiddenVisibility);
4757 Thunk->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4776 GenerateDirectMethodsPreconditionCheck(CGF, Thunk, OMD, CD);
4781 for (
auto &Arg : Thunk->args())
4782 Args.push_back(&Arg);
4785 llvm::CallInst *
Call = CGF.
Builder.CreateCall(Implementation, Args);
4786 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
4793 llvm::AttributeList Attrs;
4797 Call->setAttributes(Attrs);
4798 Call->setCallingConv(
static_cast<llvm::CallingConv::ID
>(
CallingConv));
4803 if (ThunkTy->getReturnType()->isVoidTy())
4813llvm::Function *CGObjCCommonMac::GetDirectMethodCallee(
4815 bool ReceiverCanBeNull,
bool ClassObjectCanBeUnrealized) {
4820 DirectMethodInfo Info = GenerateDirectMethod(OMD, CD);
4826 return Info.Implementation;
4830 auto getOrCreateThunk = [&]() {
4832 Info.Thunk = GenerateObjCDirectThunk(OMD, CD, Info.Implementation);
4842 return ReceiverCanBeNull ? getOrCreateThunk() : Info.Implementation;
4845 "OMD should either be a class method or instance method");
4849 return (ReceiverCanBeNull || ClassObjectCanBeUnrealized)
4850 ? getOrCreateThunk()
4851 : Info.Implementation;
4855CGObjCCommonMac::GenerateClassRealization(CodeGenFunction &CGF,
4856 llvm::Value *classObject,
4857 const ObjCInterfaceDecl *OID) {
4864 RValue result = GeneratePossiblySpecializedMessageSend(
4865 CGF, ReturnValueSlot(), ResultType, SelfSel, classObject, Args, OID,
4871void CGObjCCommonMac::GenerateDirectMethodsPreconditionCheck(
4872 CodeGenFunction &CGF, llvm::Function *Fn,
const ObjCMethodDecl *OMD,
4873 const ObjCContainerDecl *CD) {
4875 bool ReceiverCanBeNull =
true;
4877 auto selfValue = Builder.CreateLoad(selfAddr);
4892 "GenerateDirectMethod() should be called with the Class Interface");
4903 llvm::Value *realizedClass = GenerateClassRealization(CGF, selfValue, OID);
4904 Builder.CreateStore(realizedClass, selfAddr);
4909 ReceiverCanBeNull = isWeakLinkedClass(OID);
4913 if (ReceiverCanBeNull) {
4914 llvm::BasicBlock *SelfIsNilBlock =
4916 llvm::BasicBlock *ContBlock =
4921 auto Zero = llvm::ConstantPointerNull::get(selfTy);
4924 Builder.CreateCondBr(Builder.CreateICmpEQ(selfValue,
Zero), SelfIsNilBlock,
4925 ContBlock, MDHelper.createUnlikelyBranchWeights());
4931 Builder.SetInsertPoint(SelfIsNilBlock);
4932 if (!retTy->isVoidType()) {
4940 Builder.SetInsertPoint(ContBlock);
4944void CGObjCCommonMac::GenerateDirectMethodPrologue(
4945 CodeGenFunction &CGF, llvm::Function *Fn,
const ObjCMethodDecl *OMD,
4946 const ObjCContainerDecl *CD) {
4949 GenerateDirectMethodsPreconditionCheck(CGF, Fn, OMD, CD);
4958 Builder.CreateStore(GetSelector(CGF, OMD),
4963llvm::Function *CGObjCCommonMac::GenerateMethodSelectorStub(
4964 Selector Sel, StringRef ClassName,
const ObjCCommonTypesHelper &ObjCTypes) {
4965 assert((!ClassName.data() || !ClassName.empty()) &&
4966 "class name cannot be an empty string");
4967 auto Key = std::make_pair(Sel, ClassName);
4968 auto I = MethodSelectorStubs.find(Key);
4970 if (I != MethodSelectorStubs.end())
4973 auto *FnTy = llvm::FunctionType::get(
4974 ObjCTypes.ObjectPtrTy, {ObjCTypes.ObjectPtrTy, ObjCTypes.SelectorPtrTy},
4978 if (ClassName.data())
4979 FnName = (
"objc_msgSendClass$" + Sel.
getAsString() +
"$_OBJC_CLASS_$_" +
4980 llvm::Twine(ClassName))
4988 MethodSelectorStubs.insert(std::make_pair(Key, Fn));
4992llvm::GlobalVariable *
4993CGObjCCommonMac::CreateMetadataVar(Twine Name, ConstantStructBuilder &
Init,
4994 StringRef Section, CharUnits Align,
4996 llvm::GlobalValue::LinkageTypes
LT =
4998 llvm::GlobalVariable *GV =
4999 Init.finishAndCreateGlobal(Name, Align,
false, LT);
5000 if (!Section.empty())
5001 GV->setSection(Section);
5007llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
5008 llvm::Constant *
Init,
5012 llvm::Type *Ty =
Init->getType();
5013 llvm::GlobalValue::LinkageTypes
LT =
5015 llvm::GlobalVariable *GV =
5016 new llvm::GlobalVariable(CGM.
getModule(), Ty,
false, LT,
Init, Name);
5017 if (!Section.empty())
5018 GV->setSection(Section);
5025llvm::GlobalVariable *
5026CGObjCCommonMac::CreateCStringLiteral(StringRef Name, ObjCLabelType
Type,
5027 bool ForceNonFragileABI,
5028 bool NullTerminate) {
5031 case ObjCLabelType::ClassName:
5032 Label =
"OBJC_CLASS_NAME_";
5034 case ObjCLabelType::MethodVarName:
5035 Label =
"OBJC_METH_VAR_NAME_";
5037 case ObjCLabelType::MethodVarType:
5038 Label =
"OBJC_METH_VAR_TYPE_";
5040 case ObjCLabelType::PropertyName:
5041 Label =
"OBJC_PROP_NAME_ATTR_";
5043 case ObjCLabelType::LayoutBitMap:
5044 Label =
"OBJC_LAYOUT_BITMAP_";
5048 bool NonFragile = ForceNonFragileABI || isNonFragileABI();
5052 case ObjCLabelType::ClassName:
5053 Section = NonFragile ?
"__TEXT,__objc_classname,cstring_literals"
5054 :
"__TEXT,__cstring,cstring_literals";
5056 case ObjCLabelType::MethodVarName:
5057 Section = NonFragile ?
"__TEXT,__objc_methname,cstring_literals"
5058 :
"__TEXT,__cstring,cstring_literals";
5060 case ObjCLabelType::MethodVarType:
5061 Section = NonFragile ?
"__TEXT,__objc_methtype,cstring_literals"
5062 :
"__TEXT,__cstring,cstring_literals";
5064 case ObjCLabelType::PropertyName:
5065 Section = NonFragile ?
"__TEXT,__objc_methname,cstring_literals"
5066 :
"__TEXT,__cstring,cstring_literals";
5068 case ObjCLabelType::LayoutBitMap:
5069 Section =
"__TEXT,__cstring,cstring_literals";
5073 llvm::Constant *
Value =
5074 llvm::ConstantDataArray::getString(VMContext, Name, NullTerminate);
5075 llvm::GlobalVariable *GV =
new llvm::GlobalVariable(
5077 true, llvm::GlobalValue::PrivateLinkage,
Value, Label);
5078 if (CGM.
getTriple().isOSBinFormatMachO())
5079 GV->setSection(Section);
5080 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
5087llvm::Function *CGObjCMac::ModuleInitFunction() {
5093llvm::FunctionCallee CGObjCMac::GetPropertyGetFunction() {
5094 return ObjCTypes.getGetPropertyFn();
5097llvm::FunctionCallee CGObjCMac::GetPropertySetFunction() {
5098 return ObjCTypes.getSetPropertyFn();
5101llvm::FunctionCallee CGObjCMac::GetOptimizedPropertySetFunction(
bool atomic,
5103 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
5106llvm::FunctionCallee CGObjCMac::GetGetStructFunction() {
5107 return ObjCTypes.getCopyStructFn();
5110llvm::FunctionCallee CGObjCMac::GetSetStructFunction() {
5111 return ObjCTypes.getCopyStructFn();
5114llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectGetFunction() {
5115 return ObjCTypes.getCppAtomicObjectFunction();
5118llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectSetFunction() {
5119 return ObjCTypes.getCppAtomicObjectFunction();
5122llvm::FunctionCallee CGObjCMac::EnumerationMutationFunction() {
5123 return ObjCTypes.getEnumerationMutationFn();
5126void CGObjCMac::EmitTryStmt(CodeGenFunction &CGF,
const ObjCAtTryStmt &S) {
5127 return EmitTryOrSynchronizedStmt(CGF, S);
5130void CGObjCMac::EmitSynchronizedStmt(CodeGenFunction &CGF,
5131 const ObjCAtSynchronizedStmt &S) {
5132 return EmitTryOrSynchronizedStmt(CGF, S);
5136struct PerformFragileFinally final : EHScopeStack::Cleanup {
5141 ObjCTypesHelper &ObjCTypes;
5142 PerformFragileFinally(
const Stmt *S, Address SyncArgSlot,
5143 Address CallTryExitVar, Address ExceptionData,
5144 ObjCTypesHelper *ObjCTypes)
5145 : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
5146 ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
5148 void Emit(CodeGenFunction &CGF, Flags flags)
override {
5151 llvm::BasicBlock *FinallyCallExit =
5153 llvm::BasicBlock *FinallyNoCallExit =
5156 FinallyCallExit, FinallyNoCallExit);
5165 if (
const ObjCAtFinallyStmt *FinallyStmt =
5168 if (flags.isForEHCleanup())
5173 llvm::Value *CurCleanupDest =
5176 CGF.
EmitStmt(FinallyStmt->getFinallyBody());
5195class FragileHazards {
5196 CodeGenFunction &CGF;
5197 SmallVector<llvm::Value *, 20> Locals;
5198 llvm::DenseSet<llvm::BasicBlock *> BlocksBeforeTry;
5200 llvm::InlineAsm *ReadHazard;
5201 llvm::InlineAsm *WriteHazard;
5203 llvm::FunctionType *GetAsmFnType();
5205 void collectLocals();
5206 void emitReadHazard(CGBuilderTy &Builder);
5209 FragileHazards(CodeGenFunction &CGF);
5211 void emitWriteHazard();
5212 void emitHazardsInNewBlocks();
5221FragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) {
5228 for (llvm::BasicBlock &BB : *CGF.
CurFn)
5229 BlocksBeforeTry.insert(&BB);
5231 llvm::FunctionType *AsmFnTy = GetAsmFnType();
5239 std::string Constraint;
5240 for (
unsigned I = 0, E = Locals.size(); I != E; ++I) {
5246 ReadHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
5254 std::string Constraint;
5255 for (
unsigned I = 0, E = Locals.size(); I != E; ++I) {
5258 Constraint +=
"=*m";
5261 WriteHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
5266void FragileHazards::emitWriteHazard() {
5271 for (
auto Pair : llvm::enumerate(Locals))
5274 llvm::Attribute::get(
5279void FragileHazards::emitReadHazard(
CGBuilderTy &Builder) {
5280 assert(!Locals.empty());
5281 llvm::CallInst *call = Builder.CreateCall(ReadHazard, Locals);
5282 call->setDoesNotThrow();
5284 for (
auto Pair : llvm::enumerate(Locals))
5287 llvm::Attribute::get(
5288 Builder.getContext(), llvm::Attribute::ElementType,
5294void FragileHazards::emitHazardsInNewBlocks() {
5301 for (llvm::BasicBlock &BB : *CGF.
CurFn) {
5302 if (BlocksBeforeTry.count(&BB))
5306 for (llvm::BasicBlock::iterator BI = BB.begin(), BE = BB.end(); BI != BE;
5308 llvm::Instruction &I = *BI;
5327 Builder.SetInsertPoint(&BB, BI);
5328 emitReadHazard(Builder);
5335 if (llvm::Value *Ptr =
V.getBasePointer())
5339void FragileHazards::collectLocals() {
5341 llvm::DenseSet<llvm::Value *> AllocasToIgnore;
5347 llvm::BasicBlock &Entry = CGF.
CurFn->getEntryBlock();
5348 for (llvm::Instruction &I : Entry)
5350 Locals.push_back(&I);
5353llvm::FunctionType *FragileHazards::GetAsmFnType() {
5354 SmallVector<llvm::Type *, 16> tys(Locals.size());
5355 for (
unsigned i = 0, e = Locals.size(); i != e; ++i)
5356 tys[i] = Locals[i]->getType();
5357 return llvm::FunctionType::get(CGF.
VoidTy, tys,
false);
5468void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
5489 llvm::Value *SyncArg =
5491 SyncArg = CGF.
Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
5502 ObjCTypes.ExceptionDataTy, CGF.
getPointerAlign(),
"exceptiondata.ptr");
5508 FragileHazards Hazards(CGF);
5527 SyncArgSlot, CallTryExitVar,
5528 ExceptionData, &ObjCTypes);
5534 ExceptionData.emitRawPointer(CGF));
5537 llvm::Constant *
Zero = llvm::ConstantInt::get(CGF.
Builder.getInt32Ty(), 0);
5540 ObjCTypes.ExceptionDataTy, ExceptionData.emitRawPointer(CGF), GEPIndexes,
5543 ObjCTypes.getSetJmpFn(), SetJmpBuffer,
"setjmp_result");
5544 SetJmpResult->setCanReturnTwice();
5550 llvm::Value *DidCatch =
5551 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
5552 CGF.
Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
5560 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.
Builder.saveAndClearIP();
5566 Hazards.emitWriteHazard();
5580 ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF),
5591 llvm::BasicBlock *CatchBlock =
nullptr;
5592 llvm::BasicBlock *CatchHandler =
nullptr;
5603 ExceptionData.emitRawPointer(CGF));
5606 ObjCTypes.getSetJmpFn(), SetJmpBuffer,
"setjmp.result");
5607 SetJmpResult->setCanReturnTwice();
5609 llvm::Value *Threw =
5610 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
5614 CGF.
Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
5624 bool AllMatched =
false;
5625 for (
const ObjCAtCatchStmt *CatchStmt : AtTryStmt->
catch_stmts()) {
5626 const VarDecl *CatchParam = CatchStmt->getCatchParamDecl();
5627 const ObjCObjectPointerType *OPT =
nullptr;
5633 OPT = CatchParam->
getType()->
getAs<ObjCObjectPointerType>();
5652 EmitInitOfCatchParam(CGF, Caught, CatchParam);
5655 CGF.
EmitStmt(CatchStmt->getCatchBody());
5658 CatchVarCleanups.ForceCleanup();
5664 assert(OPT &&
"Unexpected non-object pointer type in @catch");
5668 ObjCInterfaceDecl *IDecl = ObjTy->getInterface();
5669 assert(IDecl &&
"Catch parameter must have Objective-C type!");
5672 llvm::Value *
Class = EmitClassRef(CGF, IDecl);
5674 llvm::Value *matchArgs[] = {
Class, Caught};
5676 ObjCTypes.getExceptionMatchFn(), matchArgs,
"match");
5682 MatchedBlock, NextCatchBlock);
5695 llvm::Value *Tmp = CGF.
Builder.CreateBitCast(
5697 EmitInitOfCatchParam(CGF, Tmp, CatchParam);
5699 CGF.
EmitStmt(CatchStmt->getCatchBody());
5702 CatchVarCleanups.ForceCleanup();
5713 if (Caught->use_empty())
5714 Caught->eraseFromParent();
5730 assert(PropagatingExnVar.
isValid());
5732 ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF),
5743 Hazards.emitHazardsInNewBlocks();
5746 CGF.
Builder.restoreIP(TryFallthroughIP);
5753 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
5757 llvm::Value *PropagatingExn;
5758 if (PropagatingExnVar.
isValid()) {
5764 ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF));
5765 PropagatingExn = Caught;
5770 CGF.
Builder.CreateUnreachable();
5773 CGF.
Builder.restoreIP(SavedIP);
5776void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
5777 const ObjCAtThrowStmt &S,
5778 bool ClearInsertionPoint) {
5779 llvm::Value *ExceptionAsObject;
5784 CGF.
Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
5787 "Unexpected rethrow outside @catch block.");
5791 CGF.
EmitRuntimeCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
5792 ->setDoesNotReturn();
5793 CGF.
Builder.CreateUnreachable();
5796 if (ClearInsertionPoint)
5797 CGF.
Builder.ClearInsertionPoint();
5803llvm::Value *CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
5806 llvm::Value *AddrWeakObjVal = CGF.
Builder.CreateBitCast(
5809 ObjCTypes.getGcReadWeakFn(), AddrWeakObjVal,
"weakread");
5810 read_weak = CGF.
Builder.CreateBitCast(read_weak, DestTy);
5817void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
5818 llvm::Value *src,
Address dst) {
5819 llvm::Type *SrcTy = src->getType();
5822 assert(Size <= 8 && "does not support size > 8
");
5823 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
5824 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
5825 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5827 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5828 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
5829 ObjCTypes.PtrObjectPtrTy);
5830 llvm::Value *args[] = {src, dstVal};
5831 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), args,
5838void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
5839 llvm::Value *src, Address dst,
5841 llvm::Type *SrcTy = src->getType();
5842 if (!isa<llvm::PointerType>(SrcTy)) {
5843 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
5844 assert(Size <= 8 && "does
not support size > 8
");
5845 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
5846 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
5847 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5849 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5850 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
5851 ObjCTypes.PtrObjectPtrTy);
5852 llvm::Value *args[] = {src, dstVal};
5854 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), args,
5857 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(), args,
5858 "threadlocalassign
");
5864void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
5865 llvm::Value *src, Address dst,
5866 llvm::Value *ivarOffset) {
5867 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset
is NULL");
5868 llvm::Type *SrcTy = src->getType();
5869 if (!isa<llvm::PointerType>(SrcTy)) {
5870 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
5871 assert(Size <= 8 && "does
not support size > 8
");
5872 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
5873 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
5874 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5876 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5877 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
5878 ObjCTypes.PtrObjectPtrTy);
5879 llvm::Value *args[] = {src, dstVal, ivarOffset};
5880 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
5886void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
5887 llvm::Value *src, Address dst) {
5888 llvm::Type *SrcTy = src->getType();
5889 if (!isa<llvm::PointerType>(SrcTy)) {
5890 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
5891 assert(Size <= 8 && "does
not support size > 8
");
5892 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
5893 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
5894 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5896 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5897 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
5898 ObjCTypes.PtrObjectPtrTy);
5899 llvm::Value *args[] = {src, dstVal};
5900 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), args,
5904void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
5905 Address DestPtr, Address SrcPtr,
5906 llvm::Value *size) {
5907 llvm::Value *args[] = {DestPtr.emitRawPointer(CGF),
5908 SrcPtr.emitRawPointer(CGF), size};
5909 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
5914LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
5916 llvm::Value *BaseValue,
5917 const ObjCIvarDecl *Ivar,
5918 unsigned CVRQualifiers) {
5919 const ObjCInterfaceDecl *ID =
5920 ObjectTy->castAs<ObjCObjectType>()->getInterface();
5921 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
5922 EmitIvarOffset(CGF, ID, Ivar));
5925llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
5926 const ObjCInterfaceDecl *Interface,
5927 const ObjCIvarDecl *Ivar) {
5928 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
5929 return llvm::ConstantInt::get(
5930 CGM.getTypes().ConvertType(CGM.getContext().LongTy), Offset);
5933/* *** Private Interface *** */
5935std::string CGObjCCommonMac::GetSectionName(StringRef Section,
5936 StringRef MachOAttributes) {
5937 switch (CGM.getTriple().getObjectFormat()) {
5938 case llvm::Triple::UnknownObjectFormat:
5939 llvm_unreachable("unexpected
object file format
");
5940 case llvm::Triple::MachO: {
5941 if (MachOAttributes.empty())
5942 return ("__DATA,
" + Section).str();
5943 return ("__DATA,
" + Section + ",
" + MachOAttributes).str();
5945 case llvm::Triple::ELF:
5946 assert(Section.starts_with("__
") && "expected the name to begin with __
");
5947 return Section.substr(2).str();
5948 case llvm::Triple::COFF:
5949 assert(Section.starts_with("__
") && "expected the name to begin with __
");
5950 return (".
" + Section.substr(2) + "$B
").str();
5951 case llvm::Triple::Wasm:
5952 case llvm::Triple::GOFF:
5953 case llvm::Triple::SPIRV:
5954 case llvm::Triple::XCOFF:
5955 case llvm::Triple::DXContainer:
5956 llvm::report_fatal_error(
5957 "Objective-
C support
is unimplemented
for object file format
");
5960 llvm_unreachable("Unhandled llvm::Triple::ObjectFormatType
enum");
5972enum ImageInfoFlags {
5973 eImageInfo_FixAndContinue = (1 << 0), // This flag is no longer set by clang.
5974 eImageInfo_GarbageCollected = (1 << 1),
5975 eImageInfo_GCOnly = (1 << 2),
5976 eImageInfo_OptimizedByDyld = (1 << 3), // This flag is set by the dyld shared cache.
5978 eImageInfo_SignedClassRO = (1 << 4), // Reused (was _CorrectedSynthesize)
5979 eImageInfo_ImageIsSimulated = (1 << 5),
5980 eImageInfo_ClassProperties = (1 << 6)
5984void CGObjCCommonMac::EmitImageInfo() {
5985 unsigned version = 0; // Version is unused?
5986 std::string Section =
5988 ? "__OBJC,__image_info,regular
"
5989 : GetSectionName("__objc_imageinfo
", "regular,no_dead_strip
");
5991 // Generate module-level named metadata to convey this information to the
5992 // linker and code-gen.
5993 llvm::Module &Mod = CGM.getModule();
5995 // Add the ObjC ABI version to the module flags.
5996 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Version
", ObjCABI);
5997 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Image Info Version
",
5999 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Image Info Section
",
6000 llvm::MDString::get(VMContext, Section));
6002 auto Int8Ty = llvm::Type::getInt8Ty(VMContext);
6003 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
6004 // Non-GC overrides those files which specify GC.
6005 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Garbage Collection
",
6006 llvm::ConstantInt::get(Int8Ty, 0));
6008 // Add the ObjC garbage collection value.
6010 llvm::Module::Error, "Objective-
C Garbage Collection
",
6011 llvm::ConstantInt::get(Int8Ty, (uint8_t)eImageInfo_GarbageCollected));
6013 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
6014 // Add the ObjC GC Only value.
6015 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C GC Only
",
6018 // Require that GC be specified and set to eImageInfo_GarbageCollected.
6019 llvm::Metadata *Ops[2] = {
6020 llvm::MDString::get(VMContext, "Objective-
C Garbage Collection
"),
6021 llvm::ConstantAsMetadata::get(
6022 llvm::ConstantInt::get(Int8Ty, eImageInfo_GarbageCollected))};
6023 Mod.addModuleFlag(llvm::Module::Require, "Objective-
C GC Only
",
6024 llvm::MDNode::get(VMContext, Ops));
6028 // Indicate whether we're compiling this to run on a simulator.
6029 if (CGM.getTarget().getTriple().isSimulatorEnvironment())
6030 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Is Simulated
",
6031 eImageInfo_ImageIsSimulated);
6033 // Indicate whether we are generating class properties.
6034 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Class Properties
",
6035 eImageInfo_ClassProperties);
6037 // Indicate whether we want enforcement of pointer signing for class_ro_t
6039 if (CGM.getLangOpts().PointerAuthObjcClassROPointers)
6040 Mod.addModuleFlag(llvm::Module::Error,
6041 "Objective-
C Enforce ClassRO
Pointer Signing
",
6042 eImageInfo_SignedClassRO);
6044 Mod.addModuleFlag(llvm::Module::Error,
6045 "Objective-
C Enforce ClassRO
Pointer Signing
",
6046 llvm::ConstantInt::get(Int8Ty, 0));
6049// struct objc_module {
6050// unsigned long version;
6051// unsigned long size;
6056// FIXME: Get from somewhere
6057static const int ModuleVersion = 7;
6059void CGObjCMac::EmitModuleInfo() {
6060 uint64_t Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ModuleTy);
6062 ConstantInitBuilder builder(CGM);
6063 auto values = builder.beginStruct(ObjCTypes.ModuleTy);
6064 values.addInt(ObjCTypes.LongTy, ModuleVersion);
6065 values.addInt(ObjCTypes.LongTy, Size);
6066 // This used to be the filename, now it is unused. <rdr://4327263>
6067 values.add(GetClassName(StringRef("")));
6068 values.add(EmitModuleSymbols());
6069 CreateMetadataVar("OBJC_MODULES
", values,
6070 "__OBJC,__module_info,regular,no_dead_strip
",
6071 CGM.getPointerAlign(), true);
6074llvm::Constant *CGObjCMac::EmitModuleSymbols() {
6075 unsigned NumClasses = DefinedClasses.size();
6076 unsigned NumCategories = DefinedCategories.size();
6078 // Return null if no symbols were defined.
6079 if (!NumClasses && !NumCategories)
6080 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
6082 ConstantInitBuilder builder(CGM);
6083 auto values = builder.beginStruct();
6084 values.addInt(ObjCTypes.LongTy, 0);
6085 values.addNullPointer(ObjCTypes.SelectorPtrTy);
6086 values.addInt(ObjCTypes.ShortTy, NumClasses);
6087 values.addInt(ObjCTypes.ShortTy, NumCategories);
6089 // The runtime expects exactly the list of defined classes followed
6090 // by the list of defined categories, in a single array.
6091 auto array = values.beginArray(ObjCTypes.Int8PtrTy);
6092 for (unsigned i = 0; i < NumClasses; i++) {
6093 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
6095 if (ObjCImplementationDecl *IMP = ID->getImplementation())
6096 // We are implementing a weak imported interface. Give it external linkage
6097 if (ID->isWeakImported() && !IMP->isWeakImported())
6098 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
6100 array.add(DefinedClasses[i]);
6102 for (unsigned i = 0; i < NumCategories; i++)
6103 array.add(DefinedCategories[i]);
6105 array.finishAndAddTo(values);
6107 llvm::GlobalVariable *GV = CreateMetadataVar(
6108 "OBJC_SYMBOLS
", values, "__OBJC,__symbols,regular,no_dead_strip
",
6109 CGM.getPointerAlign(), true);
6113llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF,
6114 IdentifierInfo *II) {
6115 LazySymbols.insert(II);
6117 llvm::GlobalVariable *&Entry = ClassReferences[II];
6121 CreateMetadataVar("OBJC_CLASS_REFERENCES_
", GetClassName(II->getName()),
6122 "__OBJC,__cls_refs,literal_pointers,no_dead_strip
",
6123 CGM.getPointerAlign(), true);
6126 return CGF.Builder.CreateAlignedLoad(Entry->getValueType(), Entry,
6127 CGF.getPointerAlign());
6130llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF,
6131 const ObjCInterfaceDecl *ID) {
6132 // If the class has the objc_runtime_visible attribute, we need to
6133 // use the Objective-C runtime to get the class.
6134 if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
6135 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
6137 IdentifierInfo *RuntimeName =
6138 &CGM.getContext().Idents.get(ID->getObjCRuntimeNameAsString());
6139 return EmitClassRefFromId(CGF, RuntimeName);
6142llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
6143 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool
");
6144 return EmitClassRefFromId(CGF, II);
6147llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel) {
6148 return CGF.Builder.CreateLoad(EmitSelectorAddr(Sel));
6151ConstantAddress CGObjCMac::EmitSelectorAddr(Selector Sel) {
6152 CharUnits Align = CGM.getPointerAlign();
6154 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
6156 Entry = CreateMetadataVar(
6157 "OBJC_SELECTOR_REFERENCES_
", GetMethodVarName(Sel),
6158 "__OBJC,__message_refs,literal_pointers,no_dead_strip
", Align, true);
6159 Entry->setExternallyInitialized(true);
6162 return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align);
6165llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) {
6166 llvm::GlobalVariable *&Entry = ClassNames[RuntimeName];
6168 Entry = CreateCStringLiteral(RuntimeName, ObjCLabelType::ClassName);
6169 return getConstantGEP(VMContext, Entry, 0, 0);
6172llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
6173 return MethodDefinitions.lookup(MD);
6179CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
6180 const ObjCCommonTypesHelper &ObjCTypes) {
6181 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
6184void IvarLayoutBuilder::visitRecord(const RecordType *RT, CharUnits offset) {
6185 const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
6187 // If this is a union, remember that we had one, because it might mess
6188 // up the ordering of layout entries.
6190 IsDisordered = true;
6192 const ASTRecordLayout *recLayout = nullptr;
6193 visitAggregate(RD->field_begin(), RD->field_end(), offset,
6194 [&](const FieldDecl *field) -> CharUnits {
6196 recLayout = &CGM.getContext().getASTRecordLayout(RD);
6198 recLayout->getFieldOffset(field->getFieldIndex());
6199 return CGM.getContext().toCharUnitsFromBits(offsetInBits);
6203template <class Iterator, class GetOffsetFn>
6204void IvarLayoutBuilder::visitAggregate(Iterator begin, Iterator end,
6205 CharUnits aggregateOffset,
6206 const GetOffsetFn &getOffset) {
6207 for (; begin != end; ++begin) {
6208 auto field = *begin;
6210 // Skip over bitfields.
6211 if (field->isBitField()) {
6215 // Compute the offset of the field within the aggregate.
6216 CharUnits fieldOffset = aggregateOffset + getOffset(field);
6218 visitField(field, fieldOffset);
6223void IvarLayoutBuilder::visitField(const FieldDecl *field,
6224 CharUnits fieldOffset) {
6225 QualType fieldType = field->getType();
6227 // Drill down into arrays.
6228 uint64_t numElts = 1;
6229 if (auto arrayType = CGM.getContext().getAsIncompleteArrayType(fieldType)) {
6231 fieldType = arrayType->getElementType();
6233 // Unlike incomplete arrays, constant arrays can be nested.
6234 while (auto arrayType = CGM.getContext().getAsConstantArrayType(fieldType)) {
6235 numElts *= arrayType->getZExtSize();
6236 fieldType = arrayType->getElementType();
6239 assert(!fieldType->isArrayType() && "ivar of non-constant array
type?
");
6241 // If we ended up with a zero-sized array, we've done what we can do within
6242 // the limits of this layout encoding.
6246 // Recurse if the base element type is a record type.
6247 if (const auto *recType = fieldType->getAsCanonical<RecordType>()) {
6248 size_t oldEnd = IvarsInfo.size();
6250 visitRecord(recType, fieldOffset);
6252 // If we have an array, replicate the first entry's layout information.
6253 auto numEltEntries = IvarsInfo.size() - oldEnd;
6254 if (numElts != 1 && numEltEntries != 0) {
6255 CharUnits eltSize = CGM.getContext().getTypeSizeInChars(recType);
6256 for (uint64_t eltIndex = 1; eltIndex != numElts; ++eltIndex) {
6257 // Copy the last numEltEntries onto the end of the array, adjusting
6258 // each for the element size.
6259 for (size_t i = 0; i != numEltEntries; ++i) {
6260 auto firstEntry = IvarsInfo[oldEnd + i];
6261 IvarsInfo.push_back(IvarInfo(firstEntry.Offset + eltIndex * eltSize,
6262 firstEntry.SizeInWords));
6270 // Classify the element type.
6271 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), fieldType);
6273 // If it matches what we're looking for, add an entry.
6274 if ((ForStrongLayout && GCAttr == Qualifiers::Strong) ||
6275 (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
6276 assert(CGM.getContext().getTypeSizeInChars(fieldType) ==
6277 CGM.getPointerSize());
6278 IvarsInfo.push_back(IvarInfo(fieldOffset, numElts));
6286IvarLayoutBuilder::buildBitmap(CGObjCCommonMac &CGObjC,
6287 llvm::SmallVectorImpl<unsigned char> &buffer) {
6288 // The bitmap is a series of skip/scan instructions, aligned to word
6289 // boundaries. The skip is performed first.
6290 const unsigned char MaxNibble = 0xF;
6291 const unsigned char SkipMask = 0xF0, SkipShift = 4;
6292 const unsigned char ScanMask = 0x0F, ScanShift = 0;
6294 assert(!IvarsInfo.empty() && "generating bitmap
for no data
");
6296 // Sort the ivar info on byte position in case we encounterred a
6297 // union nested in the ivar list.
6299 // This isn't a stable sort, but our algorithm should handle it fine.
6300 llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end());
6302 assert(llvm::is_sorted(IvarsInfo));
6304 assert(IvarsInfo.back().Offset < InstanceEnd);
6306 assert(buffer.empty());
6308 // Skip the next N words.
6309 auto skip = [&](unsigned numWords) {
6310 assert(numWords > 0);
6312 // Try to merge into the previous byte. Since scans happen second, we
6313 // can't do this if it includes a scan.
6314 if (!buffer.empty() && !(buffer.back() & ScanMask)) {
6315 unsigned lastSkip = buffer.back() >> SkipShift;
6316 if (lastSkip < MaxNibble) {
6317 unsigned claimed = std::min(MaxNibble - lastSkip, numWords);
6318 numWords -= claimed;
6319 lastSkip += claimed;
6320 buffer.back() = (lastSkip << SkipShift);
6324 while (numWords >= MaxNibble) {
6325 buffer.push_back(MaxNibble << SkipShift);
6326 numWords -= MaxNibble;
6329 buffer.push_back(numWords << SkipShift);
6333 // Scan the next N words.
6334 auto scan = [&](unsigned numWords) {
6335 assert(numWords > 0);
6337 // Try to merge into the previous byte. Since scans happen second, we can
6338 // do this even if it includes a skip.
6339 if (!buffer.empty()) {
6340 unsigned lastScan = (buffer.back() & ScanMask) >> ScanShift;
6341 if (lastScan < MaxNibble) {
6342 unsigned claimed = std::min(MaxNibble - lastScan, numWords);
6343 numWords -= claimed;
6344 lastScan += claimed;
6345 buffer.back() = (buffer.back() & SkipMask) | (lastScan << ScanShift);
6349 while (numWords >= MaxNibble) {
6350 buffer.push_back(MaxNibble << ScanShift);
6351 numWords -= MaxNibble;
6354 buffer.push_back(numWords << ScanShift);
6358 // One past the end of the last scan.
6359 unsigned endOfLastScanInWords = 0;
6360 const CharUnits WordSize = CGM.getPointerSize();
6362 // Consider all the scan requests.
6363 for (auto &request : IvarsInfo) {
6364 CharUnits beginOfScan = request.Offset - InstanceBegin;
6366 // Ignore scan requests that don't start at an even multiple of the
6367 // word size. We can't encode them.
6368 if (!beginOfScan.isMultipleOf(WordSize))
6371 // Ignore scan requests that start before the instance start.
6372 // This assumes that scans never span that boundary. The boundary
6373 // isn't the true start of the ivars, because in the fragile-ARC case
6374 // it's rounded up to word alignment, but the test above should leave
6375 // us ignoring that possibility.
6376 if (beginOfScan.isNegative()) {
6377 assert(request.Offset + request.SizeInWords * WordSize <= InstanceBegin);
6381 unsigned beginOfScanInWords = beginOfScan / WordSize;
6382 unsigned endOfScanInWords = beginOfScanInWords + request.SizeInWords;
6384 // If the scan starts some number of words after the last one ended,
6386 if (beginOfScanInWords > endOfLastScanInWords) {
6387 skip(beginOfScanInWords - endOfLastScanInWords);
6389 // Otherwise, start scanning where the last left off.
6391 beginOfScanInWords = endOfLastScanInWords;
6393 // If that leaves us with nothing to scan, ignore this request.
6394 if (beginOfScanInWords >= endOfScanInWords)
6398 // Scan to the end of the request.
6399 assert(beginOfScanInWords < endOfScanInWords);
6400 scan(endOfScanInWords - beginOfScanInWords);
6401 endOfLastScanInWords = endOfScanInWords;
6405 return llvm::ConstantPointerNull::get(CGM.Int8PtrTy);
6407 // For GC layouts, emit a skip to the end of the allocation so that we
6408 // have precise information about the entire thing. This isn't useful
6409 // or necessary for the ARC-style layout strings.
6410 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
6411 unsigned lastOffsetInWords =
6412 (InstanceEnd - InstanceBegin + WordSize - CharUnits::One()) / WordSize;
6413 if (lastOffsetInWords > endOfLastScanInWords) {
6414 skip(lastOffsetInWords - endOfLastScanInWords);
6418 // Null terminate the string.
6419 buffer.push_back(0);
6421 auto *Entry = CGObjC.CreateCStringLiteral(
6422 reinterpret_cast<char *>(buffer.data()), ObjCLabelType::LayoutBitMap);
6423 return getConstantGEP(CGM.getLLVMContext(), Entry, 0, 0);
6443CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD,
6444 CharUnits beginOffset, CharUnits endOffset,
6445 bool ForStrongLayout, bool HasMRCWeakIvars) {
6446 // If this is MRC, and we're either building a strong layout or there
6447 // are no weak ivars, bail out early.
6448 llvm::Type *PtrTy = CGM.Int8PtrTy;
6449 if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
6450 !CGM.getLangOpts().ObjCAutoRefCount &&
6451 (ForStrongLayout || !HasMRCWeakIvars))
6452 return llvm::Constant::getNullValue(PtrTy);
6454 const ObjCInterfaceDecl *OI = OMD->getClassInterface();
6455 SmallVector<const ObjCIvarDecl *, 32> ivars;
6457 // GC layout strings include the complete object layout, possibly
6458 // inaccurately in the non-fragile ABI; the runtime knows how to fix this
6461 // ARC layout strings only include the class's ivars. In non-fragile
6462 // runtimes, that means starting at InstanceStart, rounded up to word
6463 // alignment. In fragile runtimes, there's no InstanceStart, so it means
6464 // starting at the offset of the first ivar, rounded up to word alignment.
6466 // MRC weak layout strings follow the ARC style.
6467 CharUnits baseOffset;
6468 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
6469 for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin(); IVD;
6470 IVD = IVD->getNextIvar())
6471 ivars.push_back(IVD);
6473 if (isNonFragileABI()) {
6474 baseOffset = beginOffset; // InstanceStart
6475 } else if (!ivars.empty()) {
6477 CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivars[0]));
6479 baseOffset = CharUnits::Zero();
6482 baseOffset = baseOffset.alignTo(CGM.getPointerAlign());
6484 CGM.getContext().DeepCollectObjCIvars(OI, true, ivars);
6486 baseOffset = CharUnits::Zero();
6490 return llvm::Constant::getNullValue(PtrTy);
6492 IvarLayoutBuilder builder(CGM, baseOffset, endOffset, ForStrongLayout);
6494 builder.visitAggregate(ivars.begin(), ivars.end(), CharUnits::Zero(),
6495 [&](const ObjCIvarDecl *ivar) -> CharUnits {
6496 return CharUnits::fromQuantity(
6497 ComputeIvarBaseOffset(CGM, OMD, ivar));
6500 if (!builder.hasBitmapData())
6501 return llvm::Constant::getNullValue(PtrTy);
6503 llvm::SmallVector<unsigned char, 4> buffer;
6504 llvm::Constant *C = builder.buildBitmap(*this, buffer);
6506 if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
6507 printf("\n%
s ivar layout
for class '%s':
",
6508 ForStrongLayout ? "strong
" : "weak
",
6509 OMD->getClassInterface()->getName().str().c_str());
6510 builder.dump(buffer);
6515llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
6516 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
6517 // FIXME: Avoid std::string in "Sel.
getAsString()
"
6520 CreateCStringLiteral(Sel.getAsString(), ObjCLabelType::MethodVarName);
6521 return getConstantGEP(VMContext, Entry, 0, 0);
6524// FIXME: Merge into a single cstring creation function.
6525llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
6526 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
6529llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
6530 std::string TypeStr;
6531 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
6533 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
6535 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType);
6536 return getConstantGEP(VMContext, Entry, 0, 0);
6539llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D,
6541 std::string TypeStr =
6542 CGM.getContext().getObjCEncodingForMethodDecl(D, Extended);
6544 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
6546 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType);
6547 return getConstantGEP(VMContext, Entry, 0, 0);
6550// FIXME: Merge into a single cstring creation function.
6551llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
6552 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
6554 Entry = CreateCStringLiteral(Ident->getName(), ObjCLabelType::PropertyName);
6555 return getConstantGEP(VMContext, Entry, 0, 0);
6558// FIXME: Merge into a single cstring creation function.
6559// FIXME: This Decl should be more precise.
6561CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
6562 const Decl *Container) {
6563 std::string TypeStr =
6564 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container);
6565 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
6568void CGObjCMac::FinishModule() {
6571 // Emit the dummy bodies for any protocols which were referenced but
6573 for (auto &entry : Protocols) {
6574 llvm::GlobalVariable *global = entry.second;
6575 if (global->hasInitializer())
6578 ConstantInitBuilder builder(CGM);
6579 auto values = builder.beginStruct(ObjCTypes.ProtocolTy);
6580 values.addNullPointer(ObjCTypes.ProtocolExtensionPtrTy);
6581 values.add(GetClassName(entry.first->getName()));
6582 values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
6583 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy);
6584 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy);
6585 values.finishAndSetAsInitializer(global);
6586 CGM.addCompilerUsedGlobal(global);
6589 // Add assembler directives to add lazy undefined symbol references
6590 // for classes which are referenced but not defined. This is
6591 // important for correct linker interaction.
6593 // FIXME: It would be nice if we had an LLVM construct for this.
6594 if ((!LazySymbols.empty() || !DefinedSymbols.empty()) &&
6595 CGM.getTriple().isOSBinFormatMachO()) {
6596 SmallString<256> Asm;
6597 Asm += CGM.getModule().getModuleInlineAsm();
6598 if (!Asm.empty() && Asm.back() != '\n')
6601 llvm::raw_svector_ostream OS(Asm);
6602 for (const auto *Sym : DefinedSymbols)
6603 OS << "\t.objc_class_name_
" << Sym->getName() << "=0\n
"
6604 << "\t.globl .objc_class_name_
" << Sym->getName() << "\n
";
6605 for (const auto *Sym : LazySymbols)
6606 OS << "\t.lazy_reference .objc_class_name_
" << Sym->getName() << "\n
";
6607 for (const auto &Category : DefinedCategoryNames)
6608 OS << "\t.objc_category_name_
" << Category << "=0\n
"
6609 << "\t.globl .objc_category_name_
" << Category << "\n
";
6611 CGM.getModule().setModuleInlineAsm(OS.str());
6615CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
6616 : CGObjCCommonMac(cgm), ObjCTypes(cgm), ObjCEmptyCacheVar(nullptr),
6617 ObjCEmptyVtableVar(nullptr) {
6623ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
6624 : VMContext(cgm.getLLVMContext()), CGM(cgm) {
6625 CodeGen::CodeGenTypes &Types = CGM.getTypes();
6626 ASTContext &Ctx = CGM.getContext();
6627 unsigned ProgramAS = CGM.getDataLayout().getProgramAddressSpace();
6629 ShortTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.ShortTy));
6631 LongTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.LongTy));
6632 Int8PtrTy = CGM.Int8PtrTy;
6633 Int8PtrProgramASTy = llvm::PointerType::get(CGM.getLLVMContext(), ProgramAS);
6634 Int8PtrPtrTy = CGM.Int8PtrPtrTy;
6636 // arm64 targets use "int" ivar offset variables. All others,
6637 // including OS X x86_64 and Windows x86_64, use "long" ivar offsets.
6638 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::aarch64)
6639 IvarOffsetVarTy = IntTy;
6641 IvarOffsetVarTy = LongTy;
6643 ObjectPtrTy = cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCIdType()));
6644 PtrObjectPtrTy = llvm::PointerType::getUnqual(VMContext);
6646 cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCSelType()));
6648 // I'm not sure I like this. The implicit coordination is a bit
6649 // gross. We should solve this in a reasonable fashion because this
6650 // is a pretty common task (match some runtime data structure with
6651 // an LLVM data structure).
6653 // FIXME: This is leaked.
6654 // FIXME: Merge with rewriter code?
6656 // struct _objc_super {
6660 RecordDecl *RD = RecordDecl::Create(
6661 Ctx, TagTypeKind::Struct, Ctx.getTranslationUnitDecl(), SourceLocation(),
6662 SourceLocation(), &Ctx.Idents.get("_objc_super
"));
6663 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
6664 nullptr, Ctx.getObjCIdType(), nullptr, nullptr,
6665 false, ICIS_NoInit));
6666 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
6667 nullptr, Ctx.getObjCClassType(), nullptr,
6668 nullptr, false, ICIS_NoInit));
6669 RD->completeDefinition();
6671 SuperCTy = Ctx.getCanonicalTagType(RD);
6672 SuperPtrCTy = Ctx.getPointerType(SuperCTy);
6674 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
6675 SuperPtrTy = llvm::PointerType::getUnqual(VMContext);
6679 // char *attributes;
6681 PropertyTy = llvm::StructType::create("struct._prop_t
", Int8PtrTy, Int8PtrTy);
6683 // struct _prop_list_t {
6684 // uint32_t entsize; // sizeof(struct _prop_t)
6685 // uint32_t count_of_properties;
6686 // struct _prop_t prop_list[count_of_properties];
6688 PropertyListTy = llvm::StructType::create(
6689 "struct._prop_list_t
", IntTy, IntTy, llvm::ArrayType::get(PropertyTy, 0));
6690 // struct _prop_list_t *
6691 PropertyListPtrTy = llvm::PointerType::getUnqual(VMContext);
6693 // struct _objc_method {
6695 // char *method_type;
6698 MethodTy = llvm::StructType::create("struct._objc_method
", SelectorPtrTy,
6699 Int8PtrTy, Int8PtrProgramASTy);
6701 // struct _objc_cache *
6702 CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache
");
6703 CachePtrTy = llvm::PointerType::getUnqual(VMContext);
6706ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
6707 : ObjCCommonTypesHelper(cgm) {
6708 // struct _objc_method_description {
6712 MethodDescriptionTy = llvm::StructType::create(
6713 "struct._objc_method_description
", SelectorPtrTy, Int8PtrTy);
6715 // struct _objc_method_description_list {
6717 // struct _objc_method_description[1];
6719 MethodDescriptionListTy =
6720 llvm::StructType::create("struct._objc_method_description_list
", IntTy,
6721 llvm::ArrayType::get(MethodDescriptionTy, 0));
6723 // struct _objc_method_description_list *
6724 MethodDescriptionListPtrTy = llvm::PointerType::getUnqual(VMContext);
6726 // Protocol description structures
6728 // struct _objc_protocol_extension {
6729 // uint32_t size; // sizeof(struct _objc_protocol_extension)
6730 // struct _objc_method_description_list *optional_instance_methods;
6731 // struct _objc_method_description_list *optional_class_methods;
6732 // struct _objc_property_list *instance_properties;
6733 // const char ** extendedMethodTypes;
6734 // struct _objc_property_list *class_properties;
6736 ProtocolExtensionTy = llvm::StructType::create(
6737 "struct._objc_protocol_extension
", IntTy, MethodDescriptionListPtrTy,
6738 MethodDescriptionListPtrTy, PropertyListPtrTy, Int8PtrPtrTy,
6741 // struct _objc_protocol_extension *
6742 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(VMContext);
6744 // Handle construction of Protocol and ProtocolList types
6746 // struct _objc_protocol {
6747 // struct _objc_protocol_extension *isa;
6748 // char *protocol_name;
6749 // struct _objc_protocol **_objc_protocol_list;
6750 // struct _objc_method_description_list *instance_methods;
6751 // struct _objc_method_description_list *class_methods;
6753 ProtocolTy = llvm::StructType::create(
6754 {ProtocolExtensionPtrTy, Int8PtrTy,
6755 llvm::PointerType::getUnqual(VMContext), MethodDescriptionListPtrTy,
6756 MethodDescriptionListPtrTy},
6757 "struct._objc_protocol
");
6760 llvm::StructType::create({llvm::PointerType::getUnqual(VMContext), LongTy,
6761 llvm::ArrayType::get(ProtocolTy, 0)},
6762 "struct._objc_protocol_list
");
6764 // struct _objc_protocol_list *
6765 ProtocolListPtrTy = llvm::PointerType::getUnqual(VMContext);
6767 ProtocolPtrTy = llvm::PointerType::getUnqual(VMContext);
6769 // Class description structures
6771 // struct _objc_ivar {
6776 IvarTy = llvm::StructType::create("struct._objc_ivar
", Int8PtrTy, Int8PtrTy,
6779 // struct _objc_ivar_list *
6780 IvarListTy = llvm::StructType::create(VMContext, "struct._objc_ivar_list
");
6781 IvarListPtrTy = llvm::PointerType::getUnqual(VMContext);
6783 // struct _objc_method_list *
6785 llvm::StructType::create(VMContext, "struct._objc_method_list
");
6786 MethodListPtrTy = llvm::PointerType::getUnqual(VMContext);
6788 // struct _objc_class_extension *
6789 ClassExtensionTy = llvm::StructType::create(
6790 "struct._objc_class_extension
", IntTy, Int8PtrTy, PropertyListPtrTy);
6791 ClassExtensionPtrTy = llvm::PointerType::getUnqual(VMContext);
6793 // struct _objc_class {
6795 // Class super_class;
6799 // long instance_size;
6800 // struct _objc_ivar_list *ivars;
6801 // struct _objc_method_list *methods;
6802 // struct _objc_cache *cache;
6803 // struct _objc_protocol_list *protocols;
6804 // char *ivar_layout;
6805 // struct _objc_class_ext *ext;
6807 ClassTy = llvm::StructType::create(
6808 {llvm::PointerType::getUnqual(VMContext),
6809 llvm::PointerType::getUnqual(VMContext), Int8PtrTy, LongTy, LongTy,
6810 LongTy, IvarListPtrTy, MethodListPtrTy, CachePtrTy, ProtocolListPtrTy,
6811 Int8PtrTy, ClassExtensionPtrTy},
6812 "struct._objc_class
");
6814 ClassPtrTy = llvm::PointerType::getUnqual(VMContext);
6816 // struct _objc_category {
6817 // char *category_name;
6818 // char *class_name;
6819 // struct _objc_method_list *instance_method;
6820 // struct _objc_method_list *class_method;
6821 // struct _objc_protocol_list *protocols;
6822 // uint32_t size; // sizeof(struct _objc_category)
6823 // struct _objc_property_list *instance_properties;// category's @property
6824 // struct _objc_property_list *class_properties;
6826 CategoryTy = llvm::StructType::create(
6827 "struct._objc_category
", Int8PtrTy, Int8PtrTy, MethodListPtrTy,
6828 MethodListPtrTy, ProtocolListPtrTy, IntTy, PropertyListPtrTy,
6831 // Global metadata structures
6833 // struct _objc_symtab {
6834 // long sel_ref_cnt;
6836 // short cls_def_cnt;
6837 // short cat_def_cnt;
6838 // char *defs[cls_def_cnt + cat_def_cnt];
6840 SymtabTy = llvm::StructType::create("struct._objc_symtab
", LongTy,
6841 SelectorPtrTy, ShortTy, ShortTy,
6842 llvm::ArrayType::get(Int8PtrTy, 0));
6843 SymtabPtrTy = llvm::PointerType::getUnqual(VMContext);
6845 // struct _objc_module {
6847 // long size; // sizeof(struct _objc_module)
6849 // struct _objc_symtab* symtab;
6851 ModuleTy = llvm::StructType::create("struct._objc_module
", LongTy, LongTy,
6852 Int8PtrTy, SymtabPtrTy);
6854 // FIXME: This is the size of the setjmp buffer and should be target
6855 // specific. 18 is what's used on 32-bit X86.
6856 uint64_t SetJmpBufferSize = 18;
6859 llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4);
6861 ExceptionDataTy = llvm::StructType::create(
6862 "struct._objc_exception_data
",
6863 llvm::ArrayType::get(CGM.Int32Ty, SetJmpBufferSize), StackPtrTy);
6866ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(
6867 CodeGen::CodeGenModule &cgm)
6868 : ObjCCommonTypesHelper(cgm) {
6869 // struct _method_list_t {
6870 // uint32_t entsize; // sizeof(struct _objc_method)
6871 // uint32_t method_count;
6872 // struct _objc_method method_list[method_count];
6875 llvm::StructType::create("struct.__method_list_t
", IntTy, IntTy,
6876 llvm::ArrayType::get(MethodTy, 0));
6877 // struct method_list_t *
6878 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6880 // struct _protocol_t {
6882 // const char * const protocol_name;
6883 // const struct _protocol_list_t * protocol_list; // super protocols
6884 // const struct method_list_t * const instance_methods;
6885 // const struct method_list_t * const class_methods;
6886 // const struct method_list_t *optionalInstanceMethods;
6887 // const struct method_list_t *optionalClassMethods;
6888 // const struct _prop_list_t * properties;
6889 // const uint32_t size; // sizeof(struct _protocol_t)
6890 // const uint32_t flags; // = 0
6891 // const char ** extendedMethodTypes;
6892 // const char *demangledName;
6893 // const struct _prop_list_t * class_properties;
6896 ProtocolnfABITy = llvm::StructType::create(
6897 "struct._protocol_t
", ObjectPtrTy, Int8PtrTy,
6898 llvm::PointerType::getUnqual(VMContext), MethodListnfABIPtrTy,
6899 MethodListnfABIPtrTy, MethodListnfABIPtrTy, MethodListnfABIPtrTy,
6900 PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy, Int8PtrTy,
6903 // struct _protocol_t*
6904 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6906 // struct _protocol_list_t {
6907 // long protocol_count; // Note, this is 32/64 bit
6908 // struct _protocol_t *[protocol_count];
6910 ProtocolListnfABITy = llvm::StructType::create(
6911 {LongTy, llvm::ArrayType::get(ProtocolnfABIPtrTy, 0)},
6912 "struct._objc_protocol_list
");
6914 // struct _objc_protocol_list*
6915 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6918 // unsigned [long] int *offset; // pointer to ivar offset location
6921 // uint32_t alignment;
6924 IvarnfABITy = llvm::StructType::create(
6925 "struct._ivar_t
", llvm::PointerType::getUnqual(VMContext), Int8PtrTy,
6926 Int8PtrTy, IntTy, IntTy);
6928 // struct _ivar_list_t {
6929 // uint32 entsize; // sizeof(struct _ivar_t)
6931 // struct _iver_t list[count];
6934 llvm::StructType::create("struct._ivar_list_t
", IntTy, IntTy,
6935 llvm::ArrayType::get(IvarnfABITy, 0));
6937 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6939 // struct _class_ro_t {
6940 // uint32_t const flags;
6941 // uint32_t const instanceStart;
6942 // uint32_t const instanceSize;
6943 // uint32_t const reserved; // only when building for 64bit targets
6944 // const uint8_t * const ivarLayout;
6945 // const char *const name;
6946 // const struct _method_list_t * const baseMethods;
6947 // const struct _objc_protocol_list *const baseProtocols;
6948 // const struct _ivar_list_t *const ivars;
6949 // const uint8_t * const weakIvarLayout;
6950 // const struct _prop_list_t * const properties;
6953 // FIXME. Add 'reserved' field in 64bit abi mode!
6954 ClassRonfABITy = llvm::StructType::create(
6955 "struct._class_ro_t
", IntTy, IntTy, IntTy, Int8PtrTy, Int8PtrTy,
6956 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, IvarListnfABIPtrTy,
6957 Int8PtrTy, PropertyListPtrTy);
6959 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
6960 ImpnfABITy = CGM.DefaultPtrTy;
6962 // struct _class_t {
6963 // struct _class_t *isa;
6964 // struct _class_t * const superclass;
6967 // struct class_ro_t *ro;
6970 ClassnfABITy = llvm::StructType::create(
6971 {llvm::PointerType::getUnqual(VMContext),
6972 llvm::PointerType::getUnqual(VMContext), CachePtrTy,
6973 llvm::PointerType::getUnqual(VMContext),
6974 llvm::PointerType::getUnqual(VMContext)},
6977 // LLVM for struct _class_t *
6978 ClassnfABIPtrTy = llvm::PointerType::getUnqual(VMContext);
6980 // struct _category_t {
6981 // const char * const name;
6982 // struct _class_t *const cls;
6983 // const struct _method_list_t * const instance_methods;
6984 // const struct _method_list_t * const class_methods;
6985 // const struct _protocol_list_t * const protocols;
6986 // const struct _prop_list_t * const properties;
6987 // const struct _prop_list_t * const class_properties;
6988 // const uint32_t size;
6990 CategorynfABITy = llvm::StructType::create(
6991 "struct._category_t
", Int8PtrTy, ClassnfABIPtrTy, MethodListnfABIPtrTy,
6992 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, PropertyListPtrTy,
6993 PropertyListPtrTy, IntTy);
6995 // New types for nonfragile abi messaging.
6996 CodeGen::CodeGenTypes &Types = CGM.getTypes();
6997 ASTContext &Ctx = CGM.getContext();
6999 // MessageRefTy - LLVM for:
7000 // struct _message_ref_t {
7005 // First the clang type for struct _message_ref_t
7006 RecordDecl *RD = RecordDecl::Create(
7007 Ctx, TagTypeKind::Struct, Ctx.getTranslationUnitDecl(), SourceLocation(),
7008 SourceLocation(), &Ctx.Idents.get("_message_ref_t
"));
7009 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
7010 nullptr, Ctx.VoidPtrTy, nullptr, nullptr, false,
7012 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
7013 nullptr, Ctx.getObjCSelType(), nullptr, nullptr,
7014 false, ICIS_NoInit));
7015 RD->completeDefinition();
7017 MessageRefCTy = Ctx.getCanonicalTagType(RD);
7018 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy);
7019 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy));
7021 // MessageRefPtrTy - LLVM for struct _message_ref_t*
7022 MessageRefPtrTy = llvm::PointerType::getUnqual(VMContext);
7024 // SuperMessageRefTy - LLVM for:
7025 // struct _super_message_ref_t {
7026 // SUPER_IMP messenger;
7029 SuperMessageRefTy = llvm::StructType::create("struct._super_message_ref_t
",
7030 ImpnfABITy, SelectorPtrTy);
7032 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
7033 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(VMContext);
7035 // struct objc_typeinfo {
7036 // const void** vtable; // objc_ehtype_vtable + 2
7037 // const char* name; // c++ typeinfo string
7040 EHTypeTy = llvm::StructType::create("struct._objc_typeinfo
",
7041 llvm::PointerType::getUnqual(VMContext),
7042 Int8PtrTy, ClassnfABIPtrTy);
7043 EHTypePtrTy = llvm::PointerType::getUnqual(VMContext);
7046llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
7047 FinishNonFragileABIModule();
7052void CGObjCNonFragileABIMac::AddModuleClassList(
7053 ArrayRef<llvm::GlobalValue *> Container, StringRef SymbolName,
7054 StringRef SectionName) {
7055 unsigned NumClasses = Container.size();
7060 SmallVector<llvm::Constant *, 8> Symbols(NumClasses);
7061 for (unsigned i = 0; i < NumClasses; i++)
7062 Symbols[i] = Container[i];
7064 llvm::Constant *Init = llvm::ConstantArray::get(
7065 llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Symbols.size()), Symbols);
7067 // Section name is obtained by calling GetSectionName, which returns
7068 // sections in the __DATA segment on MachO.
7069 assert((!CGM.getTriple().isOSBinFormatMachO() ||
7070 SectionName.starts_with("__DATA
")) &&
7071 "SectionName expected to start with __DATA on
MachO");
7072 llvm::GlobalVariable *GV = new llvm::GlobalVariable(
7073 CGM.getModule(), Init->getType(), false,
7074 llvm::GlobalValue::PrivateLinkage, Init, SymbolName);
7075 GV->setAlignment(CGM.getDataLayout().getABITypeAlign(Init->getType()));
7076 GV->setSection(SectionName);
7077 CGM.addCompilerUsedGlobal(GV);
7080void CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
7081 // nonfragile abi has no module definition.
7083 // Build list of all implemented class addresses in array
7084 // L_OBJC_LABEL_CLASS_$.
7086 for (unsigned i = 0, NumClasses = ImplementedClasses.size(); i < NumClasses;
7088 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
7090 if (ObjCImplementationDecl *IMP = ID->getImplementation())
7091 // We are implementing a weak imported interface. Give it external linkage
7092 if (ID->isWeakImported() && !IMP->isWeakImported()) {
7093 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
7094 DefinedMetaClasses[i]->setLinkage(
7095 llvm::GlobalVariable::ExternalLinkage);
7100 DefinedClasses, "OBJC_LABEL_CLASS_$
",
7101 GetSectionName("__objc_classlist
", "regular,no_dead_strip
"));
7104 DefinedNonLazyClasses, "OBJC_LABEL_NONLAZY_CLASS_$
",
7105 GetSectionName("__objc_nlclslist
", "regular,no_dead_strip
"));
7107 // Build list of all implemented category addresses in array
7108 // L_OBJC_LABEL_CATEGORY_$.
7109 AddModuleClassList(DefinedCategories, "OBJC_LABEL_CATEGORY_$
",
7110 GetSectionName("__objc_catlist
", "regular,no_dead_strip
"));
7112 DefinedStubCategories, "OBJC_LABEL_STUB_CATEGORY_$
",
7113 GetSectionName("__objc_catlist2
", "regular,no_dead_strip
"));
7115 DefinedNonLazyCategories, "OBJC_LABEL_NONLAZY_CATEGORY_$
",
7116 GetSectionName("__objc_nlcatlist
", "regular,no_dead_strip
"));
7125bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
7126 // At various points we've experimented with using vtable-based
7127 // dispatch for all methods.
7128 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
7129 case CodeGenOptions::Legacy:
7131 case CodeGenOptions::NonLegacy:
7133 case CodeGenOptions::Mixed:
7137 // If so, see whether this selector is in the white-list of things which must
7138 // use the new dispatch convention. We lazily build a dense set for this.
7139 if (VTableDispatchMethods.empty()) {
7140 VTableDispatchMethods.insert(GetNullarySelector("alloc
"));
7141 VTableDispatchMethods.insert(GetNullarySelector("class"));
7142 VTableDispatchMethods.insert(GetNullarySelector("self
"));
7143 VTableDispatchMethods.insert(GetNullarySelector("isFlipped
"));
7144 VTableDispatchMethods.insert(GetNullarySelector("length"));
7145 VTableDispatchMethods.insert(GetNullarySelector("count
"));
7147 // These are vtable-based if GC is disabled.
7148 // Optimistically use vtable dispatch for hybrid compiles.
7149 if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) {
7150 VTableDispatchMethods.insert(GetNullarySelector("retain
"));
7151 VTableDispatchMethods.insert(GetNullarySelector("release
"));
7152 VTableDispatchMethods.insert(GetNullarySelector("autorelease
"));
7155 VTableDispatchMethods.insert(GetUnarySelector("allocWithZone
"));
7156 VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass
"));
7157 VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector
"));
7158 VTableDispatchMethods.insert(GetUnarySelector("objectForKey
"));
7159 VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex
"));
7160 VTableDispatchMethods.insert(GetUnarySelector("isEqualToString
"));
7161 VTableDispatchMethods.insert(GetUnarySelector("isEqual
"));
7163 // These are vtable-based if GC is enabled.
7164 // Optimistically use vtable dispatch for hybrid compiles.
7165 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
7166 VTableDispatchMethods.insert(GetNullarySelector("hash
"));
7167 VTableDispatchMethods.insert(GetUnarySelector("addObject
"));
7169 // "countByEnumeratingWithState:objects:count
"
7170 const IdentifierInfo *KeyIdents[] = {
7171 &CGM.getContext().Idents.get("countByEnumeratingWithState
"),
7172 &CGM.getContext().Idents.get("objects
"),
7173 &CGM.getContext().Idents.get("count
")};
7174 VTableDispatchMethods.insert(
7175 CGM.getContext().Selectors.getSelector(3, KeyIdents));
7179 return VTableDispatchMethods.count(Sel);
7197llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassRoTInitializer(
7198 unsigned flags, unsigned InstanceStart, unsigned InstanceSize,
7199 const ObjCImplementationDecl *ID) {
7200 std::string ClassName = std::string(ID->getObjCRuntimeNameAsString());
7202 CharUnits beginInstance = CharUnits::fromQuantity(InstanceStart);
7203 CharUnits endInstance = CharUnits::fromQuantity(InstanceSize);
7205 bool hasMRCWeak = false;
7206 if (CGM.getLangOpts().ObjCAutoRefCount)
7207 flags |= NonFragileABI_Class_CompiledByARC;
7208 else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))
7209 flags |= NonFragileABI_Class_HasMRCWeakIvars;
7211 ConstantInitBuilder builder(CGM);
7212 auto values = builder.beginStruct(ObjCTypes.ClassRonfABITy);
7214 values.addInt(ObjCTypes.IntTy, flags);
7215 values.addInt(ObjCTypes.IntTy, InstanceStart);
7216 values.addInt(ObjCTypes.IntTy, InstanceSize);
7217 values.add((flags & NonFragileABI_Class_Meta)
7218 ? GetIvarLayoutName(nullptr, ObjCTypes)
7219 : BuildStrongIvarLayout(ID, beginInstance, endInstance));
7220 values.add(GetClassName(ID->getObjCRuntimeNameAsString()));
7222 // const struct _method_list_t * const baseMethods;
7223 SmallVector<const ObjCMethodDecl *, 16> methods;
7224 if (flags & NonFragileABI_Class_Meta) {
7225 for (const auto *MD : ID->class_methods())
7226 if (!MD->isDirectMethod())
7227 methods.push_back(MD);
7229 for (const auto *MD : ID->instance_methods())
7230 if (!MD->isDirectMethod())
7231 methods.push_back(MD);
7234 llvm::Constant *MethListPtr = emitMethodList(
7235 ID->getObjCRuntimeNameAsString(),
7236 (flags & NonFragileABI_Class_Meta) ? MethodListType::ClassMethods
7237 : MethodListType::InstanceMethods,
7240 const PointerAuthSchema &MethListSchema =
7241 CGM.getCodeGenOpts().PointerAuth.ObjCMethodListPointer;
7242 if (!MethListPtr->isNullValue())
7243 values.addSignedPointer(MethListPtr, MethListSchema, GlobalDecl(),
7246 values.add(MethListPtr);
7248 const ObjCInterfaceDecl *OID = ID->getClassInterface();
7249 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer
");
7250 values.add(EmitProtocolList("_OBJC_CLASS_PROTOCOLS_$_
" +
7251 OID->getObjCRuntimeNameAsString(),
7252 OID->all_referenced_protocol_begin(),
7253 OID->all_referenced_protocol_end()));
7255 if (flags & NonFragileABI_Class_Meta) {
7256 values.addNullPointer(ObjCTypes.IvarListnfABIPtrTy);
7257 values.add(GetIvarLayoutName(nullptr, ObjCTypes));
7258 values.add(EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_
" +
7259 ID->getObjCRuntimeNameAsString(),
7260 ID, ID->getClassInterface(), ObjCTypes, true));
7262 values.add(EmitIvarList(ID));
7263 values.add(BuildWeakIvarLayout(ID, beginInstance, endInstance, hasMRCWeak));
7264 values.add(EmitPropertyList("_OBJC_$_PROP_LIST_
" +
7265 ID->getObjCRuntimeNameAsString(),
7266 ID, ID->getClassInterface(), ObjCTypes, false));
7269 llvm::SmallString<64> roLabel;
7270 llvm::raw_svector_ostream(roLabel)
7271 << ((flags & NonFragileABI_Class_Meta) ? "_OBJC_METACLASS_RO_$_
"
7272 : "_OBJC_CLASS_RO_$_
")
7275 return finishAndCreateGlobal(values, roLabel, CGM);
7288llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassObject(
7289 const ObjCInterfaceDecl *CI, bool isMetaclass, llvm::Constant *IsAGV,
7290 llvm::Constant *SuperClassGV, llvm::Constant *ClassRoGV,
7291 bool HiddenVisibility) {
7292 ConstantInitBuilder builder(CGM);
7293 auto values = builder.beginStruct(ObjCTypes.ClassnfABITy);
7294 const PointerAuthOptions &PointerAuthOpts = CGM.getCodeGenOpts().PointerAuth;
7295 values.addSignedPointer(IsAGV, PointerAuthOpts.ObjCIsaPointers, GlobalDecl(),
7298 values.addSignedPointer(SuperClassGV, PointerAuthOpts.ObjCSuperPointers,
7299 GlobalDecl(), QualType());
7301 values.addNullPointer(ObjCTypes.ClassnfABIPtrTy);
7303 values.add(ObjCEmptyCacheVar);
7304 values.add(ObjCEmptyVtableVar);
7306 values.addSignedPointer(ClassRoGV, PointerAuthOpts.ObjCClassROPointers,
7307 GlobalDecl(), QualType());
7309 llvm::GlobalVariable *GV = cast<llvm::GlobalVariable>(
7310 GetClassGlobal(CI, isMetaclass, ForDefinition));
7311 values.finishAndSetAsInitializer(GV);
7313 if (CGM.getTriple().isOSBinFormatMachO())
7314 GV->setSection("__DATA, __objc_data
");
7315 GV->setAlignment(CGM.getDataLayout().getABITypeAlign(ObjCTypes.ClassnfABITy));
7316 if (!CGM.getTriple().isOSBinFormatCOFF())
7317 if (HiddenVisibility)
7318 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
7319 if (CGM.getCodeGenOpts().ObjCMsgSendClassSelectorStubs && !isMetaclass)
7320 CGM.addUsedGlobal(GV);
7324bool CGObjCNonFragileABIMac::ImplementationIsNonLazy(
7325 const ObjCImplDecl *OD) const {
7326 return OD->getClassMethod(GetNullarySelector("load
")) != nullptr ||
7327 OD->getClassInterface()->hasAttr<ObjCNonLazyClassAttr>() ||
7328 OD->hasAttr<ObjCNonLazyClassAttr>();
7331void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
7332 uint32_t &InstanceStart,
7333 uint32_t &InstanceSize) {
7334 const ASTRecordLayout &RL =
7335 CGM.getContext().getASTObjCInterfaceLayout(OID->getClassInterface());
7337 // InstanceSize is really instance end.
7338 InstanceSize = RL.getDataSize().getQuantity();
7340 // If there are no fields, the start is the same as the end.
7341 if (!RL.getFieldCount())
7342 InstanceStart = InstanceSize;
7344 InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth();
7347static llvm::GlobalValue::DLLStorageClassTypes getStorage(CodeGenModule &CGM,
7349 IdentifierInfo &II = CGM.getContext().Idents.get(Name);
7350 TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl();
7351 DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl);
7353 const VarDecl *VD = nullptr;
7354 for (const auto *Result : DC->lookup(&II))
7355 if ((VD = dyn_cast<VarDecl>(Result)))
7359 return llvm::GlobalValue::DLLImportStorageClass;
7360 if (VD->hasAttr<DLLExportAttr>())
7361 return llvm::GlobalValue::DLLExportStorageClass;
7362 if (VD->hasAttr<DLLImportAttr>())
7363 return llvm::GlobalValue::DLLImportStorageClass;
7364 return llvm::GlobalValue::DefaultStorageClass;
7367void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
7368 if (!ObjCEmptyCacheVar) {
7369 ObjCEmptyCacheVar = new llvm::GlobalVariable(
7370 CGM.getModule(), ObjCTypes.CacheTy, false,
7371 llvm::GlobalValue::ExternalLinkage, nullptr, "_objc_empty_cache
");
7372 if (CGM.getTriple().isOSBinFormatCOFF())
7373 ObjCEmptyCacheVar->setDLLStorageClass(
7374 getStorage(CGM, "_objc_empty_cache
"));
7376 // Only OS X with deployment version <10.9 use the empty vtable symbol
7377 const llvm::Triple &Triple = CGM.getTarget().getTriple();
7378 if (Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 9))
7379 ObjCEmptyVtableVar = new llvm::GlobalVariable(
7380 CGM.getModule(), ObjCTypes.ImpnfABITy, false,
7381 llvm::GlobalValue::ExternalLinkage, nullptr, "_objc_empty_vtable
");
7383 ObjCEmptyVtableVar = llvm::ConstantPointerNull::get(CGM.DefaultPtrTy);
7386 // FIXME: Is this correct (that meta class size is never computed)?
7387 uint32_t InstanceStart =
7388 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy);
7389 uint32_t InstanceSize = InstanceStart;
7390 uint32_t flags = NonFragileABI_Class_Meta;
7392 llvm::Constant *SuperClassGV, *IsAGV;
7394 const auto *CI = ID->getClassInterface();
7395 assert(CI && "CGObjCNonFragileABIMac::GenerateClass -
class is 0
");
7397 // Build the flags for the metaclass.
7398 bool classIsHidden = (CGM.getTriple().isOSBinFormatCOFF())
7399 ? !CI->hasAttr<DLLExportAttr>()
7400 : CI->getVisibility() == HiddenVisibility;
7402 flags |= NonFragileABI_Class_Hidden;
7404 // FIXME: why is this flag set on the metaclass?
7405 // ObjC metaclasses have no fields and don't really get constructed.
7406 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
7407 flags |= NonFragileABI_Class_HasCXXStructors;
7408 if (!ID->hasNonZeroConstructors())
7409 flags |= NonFragileABI_Class_HasCXXDestructorOnly;
7412 if (!CI->getSuperClass()) {
7414 flags |= NonFragileABI_Class_Root;
7416 SuperClassGV = GetClassGlobal(CI, /*metaclass*/ false, NotForDefinition);
7417 IsAGV = GetClassGlobal(CI, /*metaclass*/ true, NotForDefinition);
7419 // Has a root. Current class is not a root.
7420 const ObjCInterfaceDecl *Root = ID->getClassInterface();
7421 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
7424 const auto *Super = CI->getSuperClass();
7425 IsAGV = GetClassGlobal(Root, /*metaclass*/ true, NotForDefinition);
7426 SuperClassGV = GetClassGlobal(Super, /*metaclass*/ true, NotForDefinition);
7429 llvm::GlobalVariable *CLASS_RO_GV =
7430 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
7432 llvm::GlobalVariable *MetaTClass = BuildClassObject(
7433 CI, /*metaclass*/ true, IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden);
7434 CGM.setGVProperties(MetaTClass, CI);
7435 DefinedMetaClasses.push_back(MetaTClass);
7437 // Metadata for the class
7440 flags |= NonFragileABI_Class_Hidden;
7442 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
7443 flags |= NonFragileABI_Class_HasCXXStructors;
7445 // Set a flag to enable a runtime optimization when a class has
7446 // fields that require destruction but which don't require
7447 // anything except zero-initialization during construction. This
7448 // is most notably true of __strong and __weak types, but you can
7449 // also imagine there being C++ types with non-trivial default
7450 // constructors that merely set all fields to null.
7451 if (!ID->hasNonZeroConstructors())
7452 flags |= NonFragileABI_Class_HasCXXDestructorOnly;
7455 if (hasObjCExceptionAttribute(CGM.getContext(), CI))
7456 flags |= NonFragileABI_Class_Exception;
7458 if (!CI->getSuperClass()) {
7459 flags |= NonFragileABI_Class_Root;
7460 SuperClassGV = nullptr;
7462 // Has a root. Current class is not a root.
7463 const auto *Super = CI->getSuperClass();
7464 SuperClassGV = GetClassGlobal(Super, /*metaclass*/ false, NotForDefinition);
7467 GetClassSizeInfo(ID, InstanceStart, InstanceSize);
7469 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
7471 llvm::GlobalVariable *ClassMD =
7472 BuildClassObject(CI, /*metaclass*/ false, MetaTClass, SuperClassGV,
7473 CLASS_RO_GV, classIsHidden);
7474 CGM.setGVProperties(ClassMD, CI);
7475 DefinedClasses.push_back(ClassMD);
7476 ImplementedClasses.push_back(CI);
7478 // Determine if this class is also "non-lazy
".
7479 if (ImplementationIsNonLazy(ID))
7480 DefinedNonLazyClasses.push_back(ClassMD);
7482 // Force the definition of the EHType if necessary.
7483 if (flags & NonFragileABI_Class_Exception)
7484 (void)GetInterfaceEHType(CI, ForDefinition);
7485 // Make sure method definition entries are all clear for next implementation.
7486 MethodDefinitions.clear();
7498CGObjCNonFragileABIMac::GenerateProtocolRef(CodeGenFunction &CGF,
7499 const ObjCProtocolDecl *PD) {
7501 // This routine is called for @protocol only. So, we must build definition
7502 // of protocol's meta-data (not a reference to it!)
7503 assert(!PD->isNonRuntimeProtocol() &&
7504 "attempting to get a protocol ref to a
static protocol.
");
7505 llvm::Constant *Init = GetOrEmitProtocol(PD);
7507 std::string ProtocolName("_OBJC_PROTOCOL_REFERENCE_$_
");
7508 ProtocolName += PD->getObjCRuntimeNameAsString();
7510 CharUnits Align = CGF.getPointerAlign();
7512 llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);
7514 return CGF.Builder.CreateAlignedLoad(PTGV->getValueType(), PTGV, Align);
7515 PTGV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
7516 llvm::GlobalValue::WeakAnyLinkage, Init,
7519 GetSectionName("__objc_protorefs
", "coalesced,no_dead_strip
"));
7520 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
7521 PTGV->setAlignment(Align.getAsAlign());
7522 if (!CGM.getTriple().isOSBinFormatMachO())
7523 PTGV->setComdat(CGM.getModule().getOrInsertComdat(ProtocolName));
7524 CGM.addUsedGlobal(PTGV);
7525 return CGF.Builder.CreateAlignedLoad(PTGV->getValueType(), PTGV, Align);
7540void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
7541 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
7542 const char *Prefix = "_OBJC_$_CATEGORY_
";
7544 llvm::SmallString<64> ExtCatName(Prefix);
7545 ExtCatName += Interface->getObjCRuntimeNameAsString();
7546 ExtCatName += "_$_
";
7547 ExtCatName += OCD->getNameAsString();
7549 ConstantInitBuilder builder(CGM);
7550 auto values = builder.beginStruct(ObjCTypes.CategorynfABITy);
7551 values.add(GetClassName(OCD->getIdentifier()->getName()));
7552 // meta-class entry symbol
7553 values.add(GetClassGlobal(Interface, /*metaclass*/ false, NotForDefinition));
7554 std::string listName =
7555 (Interface->getObjCRuntimeNameAsString() + "_$_
" + OCD->getName()).str();
7557 SmallVector<const ObjCMethodDecl *, 16> instanceMethods;
7558 SmallVector<const ObjCMethodDecl *, 8> classMethods;
7559 for (const auto *MD : OCD->methods()) {
7560 if (MD->isDirectMethod())
7562 if (MD->isInstanceMethod()) {
7563 instanceMethods.push_back(MD);
7565 classMethods.push_back(MD);
7569 llvm::Constant *InstanceMethodList = emitMethodList(
7570 listName, MethodListType::CategoryInstanceMethods, instanceMethods);
7571 const PointerAuthSchema &MethListSchema =
7572 CGM.getCodeGenOpts().PointerAuth.ObjCMethodListPointer;
7573 if (!InstanceMethodList->isNullValue())
7574 values.addSignedPointer(InstanceMethodList, MethListSchema, GlobalDecl(),
7577 values.add(InstanceMethodList);
7579 llvm::Constant *ClassMethodList = emitMethodList(
7580 listName, MethodListType::CategoryClassMethods, classMethods);
7581 if (!ClassMethodList->isNullValue())
7582 values.addSignedPointer(ClassMethodList, MethListSchema, GlobalDecl(),
7585 values.add(ClassMethodList);
7587 // Keep track of whether we have actual metadata to emit.
7588 bool isEmptyCategory =
7589 InstanceMethodList->isNullValue() && ClassMethodList->isNullValue();
7591 const ObjCCategoryDecl *Category =
7592 Interface->FindCategoryDeclaration(OCD->getIdentifier());
7594 SmallString<256> ExtName;
7595 llvm::raw_svector_ostream(ExtName)
7596 << Interface->getObjCRuntimeNameAsString() << "_$_
" << OCD->getName();
7598 EmitProtocolList("_OBJC_CATEGORY_PROTOCOLS_$_
" +
7599 Interface->getObjCRuntimeNameAsString() + "_$_
" +
7600 Category->getName(),
7601 Category->protocol_begin(), Category->protocol_end());
7602 auto propertyList = EmitPropertyList("_OBJC_$_PROP_LIST_
" + ExtName.str(),
7603 OCD, Category, ObjCTypes, false);
7604 auto classPropertyList =
7605 EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_
" + ExtName.str(), OCD,
7606 Category, ObjCTypes, true);
7607 values.add(protocolList);
7608 values.add(propertyList);
7609 values.add(classPropertyList);
7610 isEmptyCategory &= protocolList->isNullValue() &&
7611 propertyList->isNullValue() &&
7612 classPropertyList->isNullValue();
7614 values.addNullPointer(ObjCTypes.ProtocolListnfABIPtrTy);
7615 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
7616 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
7619 if (isEmptyCategory) {
7620 // Empty category, don't emit any metadata.
7622 MethodDefinitions.clear();
7627 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.CategorynfABITy);
7628 values.addInt(ObjCTypes.IntTy, Size);
7630 llvm::GlobalVariable *GCATV =
7631 finishAndCreateGlobal(values, ExtCatName.str(), CGM);
7632 CGM.addCompilerUsedGlobal(GCATV);
7633 if (Interface->hasAttr<ObjCClassStubAttr>())
7634 DefinedStubCategories.push_back(GCATV);
7636 DefinedCategories.push_back(GCATV);
7638 // Determine if this category is also "non-lazy
".
7639 if (ImplementationIsNonLazy(OCD))
7640 DefinedNonLazyCategories.push_back(GCATV);
7641 // method definition entries must be clear for next implementation.
7642 MethodDefinitions.clear();
7654void CGObjCNonFragileABIMac::emitMethodConstant(ConstantArrayBuilder &builder,
7655 const ObjCMethodDecl *MD,
7657 auto method = builder.beginStruct(ObjCTypes.MethodTy);
7658 method.add(GetMethodVarName(MD->getSelector()));
7659 method.add(GetMethodVarType(MD));
7662 // Protocol methods have no implementation. So, this entry is always NULL.
7663 method.addNullPointer(ObjCTypes.Int8PtrProgramASTy);
7665 llvm::Function *fn = GetMethodDefinition(MD);
7666 assert(fn && "no definition
for method?
");
7667 if (const PointerAuthSchema &Schema =
7668 CGM.getCodeGenOpts().PointerAuth.ObjCMethodListFunctionPointers) {
7669 llvm::Constant *Bitcast =
7670 llvm::ConstantExpr::getBitCast(fn, ObjCTypes.Int8PtrProgramASTy);
7671 method.addSignedPointer(Bitcast, Schema, GlobalDecl(), QualType());
7676 method.finishAndAddTo(builder);
7687llvm::Constant *CGObjCNonFragileABIMac::emitMethodList(
7688 Twine name, MethodListType kind, ArrayRef<const ObjCMethodDecl *> methods) {
7689 // Return null for empty list.
7690 if (methods.empty())
7691 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
7696 case MethodListType::CategoryInstanceMethods:
7697 prefix = "_OBJC_$_CATEGORY_INSTANCE_METHODS_
";
7698 forProtocol = false;
7700 case MethodListType::CategoryClassMethods:
7701 prefix = "_OBJC_$_CATEGORY_CLASS_METHODS_
";
7702 forProtocol = false;
7704 case MethodListType::InstanceMethods:
7705 prefix = "_OBJC_$_INSTANCE_METHODS_
";
7706 forProtocol = false;
7708 case MethodListType::ClassMethods:
7709 prefix = "_OBJC_$_CLASS_METHODS_
";
7710 forProtocol = false;
7713 case MethodListType::ProtocolInstanceMethods:
7714 prefix = "_OBJC_$_PROTOCOL_INSTANCE_METHODS_
";
7717 case MethodListType::ProtocolClassMethods:
7718 prefix = "_OBJC_$_PROTOCOL_CLASS_METHODS_
";
7721 case MethodListType::OptionalProtocolInstanceMethods:
7722 prefix = "_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_
";
7725 case MethodListType::OptionalProtocolClassMethods:
7726 prefix = "_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_
";
7731 ConstantInitBuilder builder(CGM);
7732 auto values = builder.beginStruct();
7734 // sizeof(struct _objc_method)
7735 unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.MethodTy);
7736 values.addInt(ObjCTypes.IntTy, Size);
7738 values.addInt(ObjCTypes.IntTy, methods.size());
7739 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
7740 for (auto MD : methods)
7741 emitMethodConstant(methodArray, MD, forProtocol);
7742 methodArray.finishAndAddTo(values);
7744 llvm::GlobalVariable *GV = finishAndCreateGlobal(values, prefix + name, CGM);
7745 CGM.addCompilerUsedGlobal(GV);
7751llvm::GlobalVariable *
7752CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
7753 const ObjCIvarDecl *Ivar) {
7754 const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
7755 llvm::SmallString<64> Name("OBJC_IVAR_$_
");
7756 Name += Container->getObjCRuntimeNameAsString();
7758 Name += Ivar->getName();
7759 llvm::GlobalVariable *IvarOffsetGV = CGM.getModule().getGlobalVariable(Name);
7760 if (!IvarOffsetGV) {
7761 IvarOffsetGV = new llvm::GlobalVariable(
7762 CGM.getModule(), ObjCTypes.IvarOffsetVarTy, false,
7763 llvm::GlobalValue::ExternalLinkage, nullptr, Name.str());
7764 if (CGM.getTriple().isOSBinFormatCOFF()) {
7765 bool IsPrivateOrPackage =
7766 Ivar->getAccessControl() == ObjCIvarDecl::Private ||
7767 Ivar->getAccessControl() == ObjCIvarDecl::Package;
7769 const ObjCInterfaceDecl *ContainingID = Ivar->getContainingInterface();
7771 if (ContainingID->hasAttr<DLLImportAttr>())
7772 IvarOffsetGV->setDLLStorageClass(
7773 llvm::GlobalValue::DLLImportStorageClass);
7774 else if (ContainingID->hasAttr<DLLExportAttr>() && !IsPrivateOrPackage)
7775 IvarOffsetGV->setDLLStorageClass(
7776 llvm::GlobalValue::DLLExportStorageClass);
7779 return IvarOffsetGV;
7783CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
7784 const ObjCIvarDecl *Ivar,
7785 unsigned long int Offset) {
7786 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
7787 IvarOffsetGV->setInitializer(
7788 llvm::ConstantInt::get(ObjCTypes.IvarOffsetVarTy, Offset));
7789 IvarOffsetGV->setAlignment(
7790 CGM.getDataLayout().getABITypeAlign(ObjCTypes.IvarOffsetVarTy));
7792 if (!CGM.getTriple().isOSBinFormatCOFF()) {
7793 // FIXME: This matches gcc, but shouldn't the visibility be set on the use
7794 // as well (i.e., in ObjCIvarOffsetVariable).
7795 if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
7796 Ivar->getAccessControl() == ObjCIvarDecl::Package ||
7797 ID->getVisibility() == HiddenVisibility)
7798 IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
7800 IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility);
7803 // If ID's layout is known, then make the global constant. This serves as a
7804 // useful assertion: we'll never use this variable to calculate ivar offsets,
7805 // so if the runtime tries to patch it then we should crash.
7806 if (isClassLayoutKnownStatically(ID))
7807 IvarOffsetGV->setConstant(true);
7809 if (CGM.getTriple().isOSBinFormatMachO())
7810 IvarOffsetGV->setSection("__DATA, __objc_ivar
");
7811 return IvarOffsetGV;
7832CGObjCNonFragileABIMac::EmitIvarList(const ObjCImplementationDecl *ID) {
7834 ConstantInitBuilder builder(CGM);
7835 auto ivarList = builder.beginStruct();
7836 ivarList.addInt(ObjCTypes.IntTy,
7837 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.IvarnfABITy));
7838 auto ivarCountSlot = ivarList.addPlaceholder();
7839 auto ivars = ivarList.beginArray(ObjCTypes.IvarnfABITy);
7841 const ObjCInterfaceDecl *OID = ID->getClassInterface();
7842 assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface
");
7844 // FIXME. Consolidate this with similar code in GenerateClass.
7846 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin(); IVD;
7847 IVD = IVD->getNextIvar()) {
7848 // Ignore unnamed bit-fields.
7849 if (!IVD->getDeclName())
7852 auto ivar = ivars.beginStruct(ObjCTypes.IvarnfABITy);
7853 ivar.add(EmitIvarOffsetVar(ID->getClassInterface(), IVD,
7854 ComputeIvarBaseOffset(CGM, ID, IVD)));
7855 ivar.add(GetMethodVarName(IVD->getIdentifier()));
7856 ivar.add(GetMethodVarType(IVD));
7857 llvm::Type *FieldTy = CGM.getTypes().ConvertTypeForMem(IVD->getType());
7858 unsigned Size = CGM.getDataLayout().getTypeAllocSize(FieldTy);
7860 CGM.getContext().getPreferredTypeAlign(IVD->getType().getTypePtr()) >>
7862 Align = llvm::Log2_32(Align);
7863 ivar.addInt(ObjCTypes.IntTy, Align);
7864 // NOTE. Size of a bitfield does not match gcc's, because of the
7865 // way bitfields are treated special in each. But I am told that
7866 // 'size' for bitfield ivars is ignored by the runtime so it does
7867 // not matter. If it matters, there is enough info to get the
7869 ivar.addInt(ObjCTypes.IntTy, Size);
7870 ivar.finishAndAddTo(ivars);
7872 // Return null for empty list.
7873 if (ivars.empty()) {
7876 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
7879 auto ivarCount = ivars.size();
7880 ivars.finishAndAddTo(ivarList);
7881 ivarList.fillPlaceholderWithInt(ivarCountSlot, ObjCTypes.IntTy, ivarCount);
7883 const char *Prefix = "_OBJC_$_INSTANCE_VARIABLES_
";
7884 llvm::GlobalVariable *GV = finishAndCreateGlobal(
7885 ivarList, Prefix + OID->getObjCRuntimeNameAsString(), CGM);
7886 CGM.addCompilerUsedGlobal(GV);
7891CGObjCNonFragileABIMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {
7892 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
7894 assert(!PD->isNonRuntimeProtocol() &&
7895 "attempting to GetOrEmit a non-runtime protocol
");
7897 // We use the initializer as a marker of whether this is a forward
7898 // reference or not. At module finalization we add the empty
7899 // contents for protocols which were referenced but never defined.
7900 llvm::SmallString<64> Protocol;
7901 llvm::raw_svector_ostream(Protocol)
7902 << "_OBJC_PROTOCOL_$_
" << PD->getObjCRuntimeNameAsString();
7904 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
7905 false, llvm::GlobalValue::ExternalLinkage,
7907 if (!CGM.getTriple().isOSBinFormatMachO())
7908 Entry->setComdat(CGM.getModule().getOrInsertComdat(Protocol));
7935CGObjCNonFragileABIMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
7936 llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
7938 // Early exit if a defining object has already been generated.
7939 if (Entry && Entry->hasInitializer())
7942 // Use the protocol definition, if there is one.
7943 assert(PD->hasDefinition() &&
7944 "emitting protocol metadata without definition
");
7945 PD = PD->getDefinition();
7947 auto methodLists = ProtocolMethodLists::get(PD);
7949 ConstantInitBuilder builder(CGM);
7950 auto values = builder.beginStruct(ObjCTypes.ProtocolnfABITy);
7953 values.addNullPointer(ObjCTypes.ObjectPtrTy);
7954 values.add(GetClassName(PD->getObjCRuntimeNameAsString()));
7955 values.add(EmitProtocolList("_OBJC_$_PROTOCOL_REFS_
" +
7956 PD->getObjCRuntimeNameAsString(),
7957 PD->protocol_begin(), PD->protocol_end()));
7958 values.add(methodLists.emitMethodList(
7959 this, PD, ProtocolMethodLists::RequiredInstanceMethods));
7960 values.add(methodLists.emitMethodList(
7961 this, PD, ProtocolMethodLists::RequiredClassMethods));
7962 values.add(methodLists.emitMethodList(
7963 this, PD, ProtocolMethodLists::OptionalInstanceMethods));
7964 values.add(methodLists.emitMethodList(
7965 this, PD, ProtocolMethodLists::OptionalClassMethods));
7967 EmitPropertyList("_OBJC_$_PROP_LIST_
" + PD->getObjCRuntimeNameAsString(),
7968 nullptr, PD, ObjCTypes, false));
7970 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
7971 values.addInt(ObjCTypes.IntTy, Size);
7972 values.addInt(ObjCTypes.IntTy, 0);
7973 values.add(EmitProtocolMethodTypes(
7974 "_OBJC_$_PROTOCOL_METHOD_TYPES_
" + PD->getObjCRuntimeNameAsString(),
7975 methodLists.emitExtendedTypesArray(this), ObjCTypes));
7977 // const char *demangledName;
7978 values.addNullPointer(ObjCTypes.Int8PtrTy);
7980 values.add(EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_
" +
7981 PD->getObjCRuntimeNameAsString(),
7982 nullptr, PD, ObjCTypes, true));
7985 // Already created, fix the linkage and update the initializer.
7986 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
7987 values.finishAndSetAsInitializer(Entry);
7989 llvm::SmallString<64> symbolName;
7990 llvm::raw_svector_ostream(symbolName)
7991 << "_OBJC_PROTOCOL_$_
" << PD->getObjCRuntimeNameAsString();
7993 Entry = values.finishAndCreateGlobal(symbolName, CGM.getPointerAlign(),
7995 llvm::GlobalValue::WeakAnyLinkage);
7996 if (!CGM.getTriple().isOSBinFormatMachO())
7997 Entry->setComdat(CGM.getModule().getOrInsertComdat(symbolName));
7999 Protocols[PD->getIdentifier()] = Entry;
8001 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
8002 CGM.addUsedGlobal(Entry);
8004 // Use this protocol meta-data to build protocol list table in section
8005 // __DATA, __objc_protolist
8006 llvm::SmallString<64> ProtocolRef;
8007 llvm::raw_svector_ostream(ProtocolRef)
8008 << "_OBJC_LABEL_PROTOCOL_$_
" << PD->getObjCRuntimeNameAsString();
8010 llvm::GlobalVariable *PTGV = new llvm::GlobalVariable(
8011 CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy, false,
8012 llvm::GlobalValue::WeakAnyLinkage, Entry, ProtocolRef);
8013 if (!CGM.getTriple().isOSBinFormatMachO())
8014 PTGV->setComdat(CGM.getModule().getOrInsertComdat(ProtocolRef));
8016 CGM.getDataLayout().getABITypeAlign(ObjCTypes.ProtocolnfABIPtrTy));
8018 GetSectionName("__objc_protolist
", "coalesced,no_dead_strip
"));
8019 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
8020 CGM.addUsedGlobal(PTGV);
8032llvm::Constant *CGObjCNonFragileABIMac::EmitProtocolList(
8033 Twine Name, ObjCProtocolDecl::protocol_iterator begin,
8034 ObjCProtocolDecl::protocol_iterator end) {
8035 // Just return null for empty protocol lists
8036 auto Protocols = GetRuntimeProtocolList(begin, end);
8037 if (Protocols.empty())
8038 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
8040 SmallVector<llvm::Constant *, 16> ProtocolRefs;
8041 ProtocolRefs.reserve(Protocols.size());
8043 for (const auto *PD : Protocols)
8044 ProtocolRefs.push_back(GetProtocolRef(PD));
8046 // If all of the protocols in the protocol list are objc_non_runtime_protocol
8048 if (ProtocolRefs.size() == 0)
8049 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
8051 // FIXME: We shouldn't need to do this lookup here, should we?
8052 SmallString<256> TmpName;
8053 Name.toVector(TmpName);
8054 llvm::GlobalVariable *GV =
8055 CGM.getModule().getGlobalVariable(TmpName.str(), true);
8059 ConstantInitBuilder builder(CGM);
8060 auto values = builder.beginStruct();
8061 auto countSlot = values.addPlaceholder();
8063 // A null-terminated array of protocols.
8064 auto array = values.beginArray(ObjCTypes.ProtocolnfABIPtrTy);
8065 for (auto const &proto : ProtocolRefs)
8067 auto count = array.size();
8068 array.addNullPointer(ObjCTypes.ProtocolnfABIPtrTy);
8070 array.finishAndAddTo(values);
8071 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
8073 GV = finishAndCreateGlobal(values, Name, CGM);
8074 CGM.addCompilerUsedGlobal(GV);
8084LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
8085 CodeGen::CodeGenFunction &CGF, QualType ObjectTy, llvm::Value *BaseValue,
8086 const ObjCIvarDecl *Ivar, unsigned CVRQualifiers) {
8087 ObjCInterfaceDecl *ID = ObjectTy->castAs<ObjCObjectType>()->getInterface();
8088 llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
8089 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
8094CGObjCNonFragileABIMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
8095 const ObjCInterfaceDecl *Interface,
8096 const ObjCIvarDecl *Ivar) {
8097 llvm::Value *IvarOffsetValue;
8098 if (isClassLayoutKnownStatically(Interface)) {
8099 IvarOffsetValue = llvm::ConstantInt::get(
8100 ObjCTypes.IvarOffsetVarTy,
8101 ComputeIvarBaseOffset(CGM, Interface->getImplementation(), Ivar));
8103 llvm::GlobalVariable *GV = ObjCIvarOffsetVariable(Interface, Ivar);
8104 IvarOffsetValue = CGF.Builder.CreateAlignedLoad(GV->getValueType(), GV,
8105 CGF.getSizeAlign(), "ivar
");
8106 if (IsIvarOffsetKnownIdempotent(CGF, Ivar))
8107 cast<llvm::LoadInst>(IvarOffsetValue)
8108 ->setMetadata(llvm::LLVMContext::MD_invariant_load,
8109 llvm::MDNode::get(VMContext, {}));
8112 // This could be 32bit int or 64bit integer depending on the architecture.
8113 // Cast it to 64bit integer value, if it is a 32bit integer ivar offset value
8114 // as this is what caller always expects.
8115 if (ObjCTypes.IvarOffsetVarTy == ObjCTypes.IntTy)
8116 IvarOffsetValue = CGF.Builder.CreateIntCast(
8117 IvarOffsetValue, ObjCTypes.LongTy, true, "ivar.conv
");
8118 return IvarOffsetValue;
8121static void appendSelectorForMessageRefTable(std::string &buffer,
8122 Selector selector) {
8123 if (selector.isUnarySelector()) {
8124 buffer += selector.getNameForSlot(0);
8128 for (unsigned i = 0, e = selector.getNumArgs(); i != e; ++i) {
8129 buffer += selector.getNameForSlot(i);
8144RValue CGObjCNonFragileABIMac::EmitVTableMessageSend(
8145 CodeGenFunction &CGF, ReturnValueSlot returnSlot, QualType resultType,
8146 Selector selector, llvm::Value *arg0, QualType arg0Type, bool isSuper,
8147 const CallArgList &formalArgs, const ObjCMethodDecl *method) {
8148 // Compute the actual arguments.
8151 // First argument: the receiver / super-call structure.
8153 arg0 = CGF.Builder.CreateBitCast(arg0, ObjCTypes.ObjectPtrTy);
8154 args.add(RValue::get(arg0), arg0Type);
8156 // Second argument: a pointer to the message ref structure. Leave
8157 // the actual argument value blank for now.
8158 args.add(RValue::get(nullptr), ObjCTypes.MessageRefCPtrTy);
8160 llvm::append_range(args, formalArgs);
8162 MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);
8164 NullReturnState nullReturn;
8166 // Find the function to call and the mangled name for the message
8167 // ref structure. Using a different mangled name wouldn't actually
8168 // be a problem; it would just be a waste.
8170 // The runtime currently never uses vtable dispatch for anything
8171 // except normal, non-super message-sends.
8172 // FIXME: don't use this for that.
8173 llvm::FunctionCallee fn = nullptr;
8174 std::string messageRefName("_
");
8175 if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
8177 fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
8178 messageRefName += "objc_msgSendSuper2_stret_fixup
";
8180 nullReturn.init(CGF, arg0);
8181 fn = ObjCTypes.getMessageSendStretFixupFn();
8182 messageRefName += "objc_msgSend_stret_fixup
";
8184 } else if (!isSuper && CGM.ReturnTypeUsesFPRet(resultType)) {
8185 fn = ObjCTypes.getMessageSendFpretFixupFn();
8186 messageRefName += "objc_msgSend_fpret_fixup
";
8189 fn = ObjCTypes.getMessageSendSuper2FixupFn();
8190 messageRefName += "objc_msgSendSuper2_fixup
";
8192 fn = ObjCTypes.getMessageSendFixupFn();
8193 messageRefName += "objc_msgSend_fixup
";
8196 assert(fn && "CGObjCNonFragileABIMac::EmitMessageSend
");
8197 messageRefName += '_';
8199 // Append the selector name, except use underscores anywhere we
8200 // would have used colons.
8201 appendSelectorForMessageRefTable(messageRefName, selector);
8203 llvm::GlobalVariable *messageRef =
8204 CGM.getModule().getGlobalVariable(messageRefName);
8206 // Build the message ref structure.
8207 ConstantInitBuilder builder(CGM);
8208 auto values = builder.beginStruct();
8209 values.add(cast<llvm::Constant>(fn.getCallee()));
8210 values.add(GetMethodVarName(selector));
8211 messageRef = values.finishAndCreateGlobal(
8212 messageRefName, CharUnits::fromQuantity(16),
8213 /*constant*/ false, llvm::GlobalValue::WeakAnyLinkage);
8214 messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility);
8215 messageRef->setSection(GetSectionName("__objc_msgrefs
", "coalesced
"));
8218 bool requiresnullCheck = false;
8219 if (CGM.getLangOpts().ObjCAutoRefCount && method)
8220 for (const auto *ParamDecl : method->parameters()) {
8221 if (ParamDecl->isDestroyedInCallee()) {
8222 if (!nullReturn.NullBB)
8223 nullReturn.init(CGF, arg0);
8224 requiresnullCheck = true;
8230 Address(CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy),
8231 ObjCTypes.MessageRefTy, CGF.getPointerAlign());
8233 // Update the message ref argument.
8234 args[1].setRValue(RValue::get(mref, CGF));
8236 // Load the function to call from the message ref table.
8237 Address calleeAddr = CGF.Builder.CreateStructGEP(mref, 0);
8238 llvm::Value *calleePtr = CGF.Builder.CreateLoad(calleeAddr, "msgSend_fn
");
8240 calleePtr = CGF.Builder.CreateBitCast(calleePtr, MSI.MessengerType);
8241 CGCallee callee(CGCalleeInfo(), calleePtr);
8243 RValue result = CGF.EmitCall(MSI.CallInfo, callee, returnSlot, args);
8244 return nullReturn.complete(CGF, returnSlot, result, resultType, formalArgs,
8245 requiresnullCheck ? method : nullptr);
8249CodeGen::RValue CGObjCNonFragileABIMac::GenerateMessageSend(
8250 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
8251 Selector Sel, llvm::Value *Receiver, const CallArgList &CallArgs,
8252 const ObjCInterfaceDecl *Class, const ObjCMethodDecl *Method) {
8253 return isVTableDispatchedSelector(Sel)
8254 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel, Receiver,
8255 CGF.getContext().getObjCIdType(), false,
8257 : EmitMessageSend(CGF, Return, ResultType, Sel, Receiver,
8258 CGF.getContext().getObjCIdType(), false,
8259 CallArgs, Method, Class, ObjCTypes);
8263CGObjCNonFragileABIMac::GetClassGlobal(const ObjCInterfaceDecl *ID,
8265 ForDefinition_t isForDefinition) {
8267 (metaclass ? getMetaclassSymbolPrefix() : getClassSymbolPrefix());
8268 return GetClassGlobal((prefix + ID->getObjCRuntimeNameAsString()).str(),
8269 isForDefinition, ID->isWeakImported(),
8271 CGM.getTriple().isOSBinFormatCOFF() &&
8272 ID->hasAttr<DLLImportAttr>());
8276CGObjCNonFragileABIMac::GetClassGlobal(StringRef Name,
8277 ForDefinition_t IsForDefinition,
8278 bool Weak, bool DLLImport) {
8279 llvm::GlobalValue::LinkageTypes L =
8280 Weak ? llvm::GlobalValue::ExternalWeakLinkage
8281 : llvm::GlobalValue::ExternalLinkage;
8283 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
8284 if (!GV || GV->getValueType() != ObjCTypes.ClassnfABITy) {
8285 auto *NewGV = new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, L,
8289 NewGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
8292 GV->replaceAllUsesWith(NewGV);
8293 GV->eraseFromParent();
8296 CGM.getModule().insertGlobalVariable(GV);
8299 assert(GV->getLinkage() == L);
8304CGObjCNonFragileABIMac::GetClassGlobalForClassRef(const ObjCInterfaceDecl *ID) {
8305 llvm::Constant *ClassGV =
8306 GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition);
8308 if (!ID->hasAttr<ObjCClassStubAttr>())
8311 ClassGV = llvm::ConstantExpr::getPointerCast(ClassGV, ObjCTypes.Int8PtrTy);
8313 // Stub classes are pointer-aligned. Classrefs pointing at stub classes
8314 // must set the least significant bit set to 1.
8315 auto *Idx = llvm::ConstantInt::get(CGM.Int32Ty, 1);
8316 return llvm::ConstantExpr::getPtrAdd(ClassGV, Idx);
8320CGObjCNonFragileABIMac::EmitLoadOfClassRef(CodeGenFunction &CGF,
8321 const ObjCInterfaceDecl *ID,
8322 llvm::GlobalVariable *Entry) {
8323 if (ID && ID->hasAttr<ObjCClassStubAttr>()) {
8324 // Classrefs pointing at Objective-C stub classes must be loaded by calling
8325 // a special runtime function.
8326 return CGF.EmitRuntimeCall(ObjCTypes.getLoadClassrefFn(), Entry,
8327 "load_classref_result
");
8330 CharUnits Align = CGF.getPointerAlign();
8331 return CGF.Builder.CreateAlignedLoad(Entry->getValueType(), Entry, Align);
8334llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(
8335 CodeGenFunction &CGF, IdentifierInfo *II, const ObjCInterfaceDecl *ID) {
8336 llvm::GlobalVariable *&Entry = ClassReferences[II];
8339 llvm::Constant *ClassGV;
8341 ClassGV = GetClassGlobalForClassRef(ID);
8343 ClassGV = GetClassGlobal((getClassSymbolPrefix() + II->getName()).str(),
8345 assert(ClassGV->getType() == ObjCTypes.ClassnfABIPtrTy &&
8346 "classref was emitted with the wrong
type?
");
8349 std::string SectionName =
8350 GetSectionName("__objc_classrefs
", "regular,no_dead_strip
");
8351 Entry = new llvm::GlobalVariable(
8352 CGM.getModule(), ClassGV->getType(), false,
8353 getLinkageTypeForObjCMetadata(CGM, SectionName), ClassGV,
8354 "OBJC_CLASSLIST_REFERENCES_$_
");
8355 Entry->setAlignment(CGF.getPointerAlign().getAsAlign());
8356 if (!ID || !ID->hasAttr<ObjCClassStubAttr>())
8357 Entry->setSection(SectionName);
8359 CGM.addCompilerUsedGlobal(Entry);
8362 return EmitLoadOfClassRef(CGF, ID, Entry);
8365llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CodeGenFunction &CGF,
8366 const ObjCInterfaceDecl *ID) {
8367 // If the class has the objc_runtime_visible attribute, we need to
8368 // use the Objective-C runtime to get the class.
8369 if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
8370 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
8372 return EmitClassRefFromId(CGF, ID->getIdentifier(), ID);
8376CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
8377 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool
");
8378 return EmitClassRefFromId(CGF, II, nullptr);
8382CGObjCNonFragileABIMac::EmitSuperClassRef(CodeGenFunction &CGF,
8383 const ObjCInterfaceDecl *ID) {
8384 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
8387 llvm::Constant *ClassGV = GetClassGlobalForClassRef(ID);
8388 std::string SectionName =
8389 GetSectionName("__objc_superrefs
", "regular,no_dead_strip
");
8390 Entry = new llvm::GlobalVariable(CGM.getModule(), ClassGV->getType(), false,
8391 llvm::GlobalValue::PrivateLinkage, ClassGV,
8392 "OBJC_CLASSLIST_SUP_REFS_$_
");
8393 Entry->setAlignment(CGF.getPointerAlign().getAsAlign());
8394 Entry->setSection(SectionName);
8395 CGM.addCompilerUsedGlobal(Entry);
8398 return EmitLoadOfClassRef(CGF, ID, Entry);
8404llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(
8405 CodeGenFunction &CGF, const ObjCInterfaceDecl *ID, bool Weak) {
8406 CharUnits Align = CGF.getPointerAlign();
8407 llvm::GlobalVariable *&Entry = MetaClassReferences[ID->getIdentifier()];
8409 auto MetaClassGV = GetClassGlobal(ID, /*metaclass*/ true, NotForDefinition);
8410 std::string SectionName =
8411 GetSectionName("__objc_superrefs
", "regular,no_dead_strip
");
8412 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
8413 false, llvm::GlobalValue::PrivateLinkage,
8414 MetaClassGV, "OBJC_CLASSLIST_SUP_REFS_$_
");
8415 Entry->setAlignment(Align.getAsAlign());
8416 Entry->setSection(SectionName);
8417 CGM.addCompilerUsedGlobal(Entry);
8420 return CGF.Builder.CreateAlignedLoad(ObjCTypes.ClassnfABIPtrTy, Entry, Align);
8425llvm::Value *CGObjCNonFragileABIMac::GetClass(CodeGenFunction &CGF,
8426 const ObjCInterfaceDecl *ID) {
8427 if (ID->isWeakImported()) {
8428 auto ClassGV = GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition);
8430 assert(!isa<llvm::GlobalVariable>(ClassGV) ||
8431 cast<llvm::GlobalVariable>(ClassGV)->hasExternalWeakLinkage());
8434 return EmitClassRef(CGF, ID);
8440CodeGen::RValue CGObjCNonFragileABIMac::GenerateMessageSendSuper(
8441 CodeGen::CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
8442 Selector Sel, const ObjCInterfaceDecl *Class, bool isCategoryImpl,
8443 llvm::Value *Receiver, bool IsClassMessage,
8444 const CodeGen::CallArgList &CallArgs, const ObjCMethodDecl *Method) {
8446 // Create and init a super structure; this is a (receiver, class)
8447 // pair we will pass to objc_msgSendSuper.
8448 RawAddress ObjCSuper = CGF.CreateTempAlloca(
8449 ObjCTypes.SuperTy, CGF.getPointerAlign(), "objc_super
");
8451 llvm::Value *ReceiverAsObject =
8452 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
8453 CGF.Builder.CreateStore(ReceiverAsObject,
8454 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
8456 // If this is a class message the metaclass is passed as the target.
8457 llvm::Value *Target;
8459 Target = EmitMetaClassRef(CGF, Class, Class->isWeakImported());
8461 Target = EmitSuperClassRef(CGF, Class);
8463 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
8465 llvm::Type *ClassTy =
8466 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
8467 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
8468 CGF.Builder.CreateStore(Target, CGF.Builder.CreateStructGEP(ObjCSuper, 1));
8470 return (isVTableDispatchedSelector(Sel))
8471 ? EmitVTableMessageSend(
8472 CGF, Return, ResultType, Sel, ObjCSuper.getPointer(),
8473 ObjCTypes.SuperPtrCTy, true, CallArgs, Method)
8474 : EmitMessageSend(CGF, Return, ResultType, Sel,
8475 ObjCSuper.getPointer(), ObjCTypes.SuperPtrCTy,
8476 true, CallArgs, Method, Class, ObjCTypes);
8479llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CodeGenFunction &CGF,
8481 Address Addr = EmitSelectorAddr(Sel);
8483 llvm::LoadInst *LI = CGF.Builder.CreateLoad(Addr);
8484 LI->setMetadata(llvm::LLVMContext::MD_invariant_load,
8485 llvm::MDNode::get(VMContext, {}));
8489ConstantAddress CGObjCNonFragileABIMac::EmitSelectorAddr(Selector Sel) {
8490 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
8491 CharUnits Align = CGM.getPointerAlign();
8493 std::string SectionName =
8494 GetSectionName("__objc_selrefs
", "literal_pointers,no_dead_strip
");
8495 Entry = new llvm::GlobalVariable(
8496 CGM.getModule(), ObjCTypes.SelectorPtrTy, false,
8497 getLinkageTypeForObjCMetadata(CGM, SectionName), GetMethodVarName(Sel),
8498 "OBJC_SELECTOR_REFERENCES_
");
8499 Entry->setExternallyInitialized(true);
8500 Entry->setSection(SectionName);
8501 Entry->setAlignment(Align.getAsAlign());
8502 CGM.addCompilerUsedGlobal(Entry);
8505 return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align);
8511void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
8512 llvm::Value *src, Address dst,
8513 llvm::Value *ivarOffset) {
8514 llvm::Type *SrcTy = src->getType();
8515 if (!isa<llvm::PointerType>(SrcTy)) {
8516 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
8517 assert(Size <= 8 && "does
not support size > 8
");
8518 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
8519 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
8520 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
8522 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
8523 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
8524 ObjCTypes.PtrObjectPtrTy);
8525 llvm::Value *args[] = {src, dstVal, ivarOffset};
8526 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
8532void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
8533 CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dst) {
8534 llvm::Type *SrcTy = src->getType();
8535 if (!isa<llvm::PointerType>(SrcTy)) {
8536 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
8537 assert(Size <= 8 && "does
not support size > 8
");
8538 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
8539 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
8540 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
8542 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
8543 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
8544 ObjCTypes.PtrObjectPtrTy);
8545 llvm::Value *args[] = {src, dstVal};
8546 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), args,
8550void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
8551 CodeGen::CodeGenFunction &CGF, Address DestPtr, Address SrcPtr,
8552 llvm::Value *Size) {
8553 llvm::Value *args[] = {DestPtr.emitRawPointer(CGF),
8554 SrcPtr.emitRawPointer(CGF), Size};
8555 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
8562CGObjCNonFragileABIMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
8563 Address AddrWeakObj) {
8564 llvm::Type *DestTy = AddrWeakObj.getElementType();
8565 llvm::Value *AddrWeakObjVal = CGF.Builder.CreateBitCast(
8566 AddrWeakObj.emitRawPointer(CGF), ObjCTypes.PtrObjectPtrTy);
8567 llvm::Value *read_weak = CGF.EmitNounwindRuntimeCall(
8568 ObjCTypes.getGcReadWeakFn(), AddrWeakObjVal, "weakread
");
8569 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
8576void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
8577 llvm::Value *src, Address dst) {
8578 llvm::Type *SrcTy = src->getType();
8579 if (!isa<llvm::PointerType>(SrcTy)) {
8580 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
8581 assert(Size <= 8 && "does
not support size > 8
");
8582 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
8583 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
8584 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
8586 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
8587 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
8588 ObjCTypes.PtrObjectPtrTy);
8589 llvm::Value *args[] = {src, dstVal};
8590 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), args,
8597void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
8598 llvm::Value *src, Address dst,
8600 llvm::Type *SrcTy = src->getType();
8601 if (!isa<llvm::PointerType>(SrcTy)) {
8602 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
8603 assert(Size <= 8 && "does
not support size > 8
");
8604 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
8605 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
8606 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
8608 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
8609 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
8610 ObjCTypes.PtrObjectPtrTy);
8611 llvm::Value *args[] = {src, dstVal};
8613 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), args,
8616 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(), args,
8617 "threadlocalassign
");
8620void CGObjCNonFragileABIMac::EmitSynchronizedStmt(
8621 CodeGen::CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S) {
8622 EmitAtSynchronizedStmt(CGF, S, ObjCTypes.getSyncEnterFn(),
8623 ObjCTypes.getSyncExitFn());
8626llvm::Constant *CGObjCNonFragileABIMac::GetEHType(QualType T) {
8627 // There's a particular fixed type info for 'id'.
8628 if (T->isObjCIdType() || T->isObjCQualifiedIdType()) {
8629 auto *IDEHType = CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id
");
8631 IDEHType = new llvm::GlobalVariable(
8632 CGM.getModule(), ObjCTypes.EHTypeTy, false,
8633 llvm::GlobalValue::ExternalLinkage, nullptr, "OBJC_EHTYPE_id
");
8634 if (CGM.getTriple().isOSBinFormatCOFF())
8635 IDEHType->setDLLStorageClass(getStorage(CGM, "OBJC_EHTYPE_id
"));
8640 // All other types should be Objective-C interface pointer types.
8641 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
8644 const ObjCInterfaceType *IT = PT->getInterfaceType();
8645 assert(IT && "Invalid
@catch type.
");
8647 return GetInterfaceEHType(IT->getDecl(), NotForDefinition);
8650void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
8651 const ObjCAtTryStmt &S) {
8652 EmitTryCatchStmt(CGF, S, ObjCTypes.getObjCBeginCatchFn(),
8653 ObjCTypes.getObjCEndCatchFn(),
8654 ObjCTypes.getExceptionRethrowFn());
8658void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
8659 const ObjCAtThrowStmt &S,
8660 bool ClearInsertionPoint) {
8661 if (const Expr *ThrowExpr = S.getThrowExpr()) {
8662 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
8663 Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
8664 llvm::CallBase *Call =
8665 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception);
8666 Call->setDoesNotReturn();
8668 llvm::CallBase *Call =
8669 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionRethrowFn());
8670 Call->setDoesNotReturn();
8673 CGF.Builder.CreateUnreachable();
8674 if (ClearInsertionPoint)
8675 CGF.Builder.ClearInsertionPoint();
8679CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
8680 ForDefinition_t IsForDefinition) {
8681 llvm::GlobalVariable *&Entry = EHTypeReferences[ID->getIdentifier()];
8682 StringRef ClassName = ID->getObjCRuntimeNameAsString();
8684 // If we don't need a definition, return the entry if found or check
8685 // if we use an external reference.
8686 if (!IsForDefinition) {
8690 // If this type (or a super class) has the __objc_exception__
8691 // attribute, emit an external reference.
8692 if (hasObjCExceptionAttribute(CGM.getContext(), ID)) {
8693 std::string EHTypeName = ("OBJC_EHTYPE_$_
" + ClassName).str();
8694 Entry = new llvm::GlobalVariable(
8695 CGM.getModule(), ObjCTypes.EHTypeTy, false,
8696 llvm::GlobalValue::ExternalLinkage, nullptr, EHTypeName);
8697 CGM.setGVProperties(Entry, ID);
8702 // Otherwise we need to either make a new entry or fill in the initializer.
8703 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition
");
8705 std::string VTableName = "objc_ehtype_vtable
";
8706 auto *VTableGV = CGM.getModule().getGlobalVariable(VTableName);
8708 VTableGV = new llvm::GlobalVariable(
8709 CGM.getModule(), ObjCTypes.Int8PtrTy, false,
8710 llvm::GlobalValue::ExternalLinkage, nullptr, VTableName);
8711 if (CGM.getTriple().isOSBinFormatCOFF())
8712 VTableGV->setDLLStorageClass(getStorage(CGM, VTableName));
8715 llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2);
8716 llvm::Constant *VTablePtr = llvm::ConstantExpr::getInBoundsGetElementPtr(
8717 VTableGV->getValueType(), VTableGV, VTableIdx);
8719 ConstantInitBuilder builder(CGM);
8720 auto values = builder.beginStruct(ObjCTypes.EHTypeTy);
8721 const PointerAuthSchema &TypeInfoSchema =
8722 CGM.getCodeGenOpts().PointerAuth.CXXTypeInfoVTablePointer;
8723 values.addSignedPointer(VTablePtr, TypeInfoSchema, GlobalDecl(), QualType());
8725 values.add(GetClassName(ClassName));
8726 values.add(GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition));
8728 llvm::GlobalValue::LinkageTypes L = IsForDefinition
8729 ? llvm::GlobalValue::ExternalLinkage
8730 : llvm::GlobalValue::WeakAnyLinkage;
8732 values.finishAndSetAsInitializer(Entry);
8733 Entry->setAlignment(CGM.getPointerAlign().getAsAlign());
8735 Entry = values.finishAndCreateGlobal("OBJC_EHTYPE_$_
" + ClassName,
8736 CGM.getPointerAlign(),
8737 /*constant*/ false, L);
8738 if (hasObjCExceptionAttribute(CGM.getContext(), ID))
8739 CGM.setGVProperties(Entry, ID);
8741 assert(Entry->getLinkage() == L);
8743 if (!CGM.getTriple().isOSBinFormatCOFF())
8744 if (ID->getVisibility() == HiddenVisibility)
8745 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
8747 if (IsForDefinition)
8748 if (CGM.getTriple().isOSBinFormatMachO())
8749 Entry->setSection("__DATA,__objc_const
");
8756CodeGen::CGObjCRuntime *
8757CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
8758 switch (CGM.getLangOpts().ObjCRuntime.getKind()) {
8759 case ObjCRuntime::FragileMacOSX:
8760 return new CGObjCMac(CGM);
8762 case ObjCRuntime::MacOSX:
8763 case ObjCRuntime::iOS:
8764 case ObjCRuntime::WatchOS:
8765 return new CGObjCNonFragileABIMac(CGM);
8767 case ObjCRuntime::GNUstep:
8768 case ObjCRuntime::GCC:
8769 case ObjCRuntime::ObjFW:
8770 llvm_unreachable("these runtimes are
not Mac runtimes
");
8772 llvm_unreachable("bad runtime
");
8775// Public wrapper function for external compilers (e.g., Swift) to access
8776// the Mac runtime's GetDirectMethodCallee functionality.
8777llvm::Function *clang::CodeGen::getObjCDirectMethodCallee(
8778 CodeGenModule &CGM, const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD,
8779 bool ReceiverCanBeNull, bool ClassObjectCanBeUnrealized) {
8780 // This function should only be called when targeting Darwin platforms,
8781 // which always use the Mac runtime.
8782 assert(CGM.getLangOpts().ObjCRuntime.isNeXTFamily() &&
8784 CGObjCCommonMac *MacRuntime =
8785 static_cast<CGObjCCommonMac *>(&CGM.getObjCRuntime());
8786 return MacRuntime->GetDirectMethodCallee(OMD, CD, ReceiverCanBeNull,
8787 ClassObjectCanBeUnrealized);
Defines the clang::ASTContext interface.
@ FragileABI_Class_Meta
Is a meta-class.
@ FragileABI_Class_Hidden
Has hidden visibility.
@ FragileABI_Class_Factory
Apparently: is not a meta-class.
@ FragileABI_Class_HasCXXStructors
Has a non-trivial constructor or destructor.
@ FragileABI_Class_HasMRCWeakIvars
Class implementation was compiled under MRC and has MRC weak ivars.
@ FragileABI_Class_CompiledByARC
Class implementation was compiled under ARC.
static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT, bool pointee=false)
static bool hasWeakMember(QualType type)
static std::string getBlockLayoutInfoString(const SmallVectorImpl< CGObjCCommonMac::RUN_SKIP > &RunSkipBlockVars, bool HasCopyDisposeHelpers)
static llvm::StringMapEntry< llvm::GlobalVariable * > & GetConstantStringEntry(llvm::StringMap< llvm::GlobalVariable * > &Map, const StringLiteral *Literal, unsigned &StringLength)
static llvm::GlobalValue::LinkageTypes getLinkageTypeForObjCMetadata(CodeGenModule &CGM, StringRef Section)
static void addIfPresent(llvm::DenseSet< llvm::Value * > &S, Address V)
@ kCFTaggedObjectID_Integer
static void PushProtocolProperties(llvm::SmallPtrSet< const IdentifierInfo *, 16 > &PropertySet, SmallVectorImpl< const ObjCPropertyDecl * > &Properties, const ObjCProtocolDecl *Proto, bool IsClassProperty)
static llvm::GlobalVariable * finishAndCreateGlobal(ConstantInitBuilder::StructBuilder &Builder, const llvm::Twine &Name, CodeGenModule &CGM)
A helper function to create an internal or private global variable.
static bool hasMRCWeakIvars(CodeGenModule &CGM, const ObjCImplementationDecl *ID)
For compatibility, we only want to set the "HasMRCWeakIvars" flag (and actually fill in a layout stri...
@ NonFragileABI_Class_HasCXXDestructorOnly
Class has non-trivial destructors, but zero-initialization is okay.
@ NonFragileABI_Class_Hidden
Has hidden visibility.
@ NonFragileABI_Class_HasCXXStructors
Has a non-trivial constructor or destructor.
@ NonFragileABI_Class_Exception
Has the exception attribute.
@ NonFragileABI_Class_HasIvarReleaser
(Obsolete) ARC-specific: this class has a .release_ivars method
@ NonFragileABI_Class_Root
Is a root class.
@ NonFragileABI_Class_Meta
Is a meta-class.
@ NonFragileABI_Class_HasMRCWeakIvars
Class implementation was compiled under MRC and has MRC weak ivars.
@ NonFragileABI_Class_CompiledByARC
Class implementation was compiled under ARC.
static llvm::Constant * getConstantGEP(llvm::LLVMContext &VMContext, llvm::GlobalVariable *C, unsigned idx0, unsigned idx1)
getConstantGEP() - Help routine to construct simple GEPs.
static bool hasObjCExceptionAttribute(ASTContext &Context, const ObjCInterfaceDecl *OID)
hasObjCExceptionAttribute - Return true if this class or any super class has the objc_exception attri...
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
Defines the clang::LangOptions interface.
llvm::MachO::Target Target
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
Defines the Objective-C statement AST node classes.
__device__ __2f16 float __ockl_bool s
__SIZE_TYPE__ size_t
The unsigned integer type of the result of the sizeof operator.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CanQualType getCanonicalParamType(QualType T) const
Return the canonical parameter type corresponding to the specific potentially non-canonical one.
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
QualType getObjCClassType() const
Represents the Objective-C Class type.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const LangOptions & getLangOpts() const
SelectorTable & Selectors
CanQualType getCanonicalSizeType() const
const ASTRecordLayout & getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const
Get or compute information about the layout of the specified Objective-C interface.
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
QualType getObjCIdType() const
Represents the Objective-CC id type.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType getObjCClassRedefinitionType() const
Retrieve the type that Class has been defined to, which may be different from the built-in Class if C...
QualType getObjCIdRedefinitionType() const
Retrieve the type that id has been defined to, which may be different from the built-in id if id has ...
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
CanQualType getNSUIntegerType() const
CharUnits getSize() const
getSize - Get the record size in characters.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
QualType withConst() const
Retrieves a version of this type with const applied.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
PointerAuthOptions PointerAuth
Configuration for pointer-signing.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
llvm::Type * getElementType() const
Return the type of the values stored in this address.
unsigned getIndex() const
CharUnits getOffset() const
const BlockDecl * getBlockDecl() const
llvm::StructType * StructureType
CharUnits BlockHeaderForcedGapOffset
bool NeedsCopyDispose
True if the block has captures that would necessitate custom copy or dispose helper functions if the ...
CharUnits BlockHeaderForcedGapSize
const Capture & getCapture(const VarDecl *var) const
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::Value * CreateIsNull(Address Addr, const Twine &Name="")
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
CGFunctionInfo - Class to encapsulate the information about a function definition.
Implements runtime-specific code generation functions.
static void destroyCalleeDestroyedArguments(CodeGenFunction &CGF, const ObjCMethodDecl *method, const CallArgList &callArgs)
Destroy the callee-destroyed arguments of the given method, if it has any.
void add(RValue rvalue, QualType type)
void addFrom(const CallArgList &other)
Add all the arguments from another CallArgList to this one.
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)
The given basic block lies in the current EH scope, but may be a target of a potentially scope-crossi...
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
llvm::Type * ConvertType(QualType T)
bool CurFuncIsThunk
In C++, whether we are code generating a thunk.
void EmitAutoVarDecl(const VarDecl &D)
EmitAutoVarDecl - Emit an auto variable declaration.
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void FinishObjCDirectPreconditionThunk()
Finish an Objective-C direct method thunk.
llvm::Value * EmitObjCThrowOperand(const Expr *expr)
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
void StartObjCDirectPreconditionThunk(const ObjCMethodDecl *OMD, llvm::Function *Fn, const CGFunctionInfo &FI)
Start an Objective-C direct method thunk.
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
JumpDest ReturnBlock
ReturnBlock - Unified return block.
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
RawAddress getNormalCleanupDestSlot()
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})
EmitStmt - Emit the code for the statement.
bool AutoreleaseResult
In ARC, whether we should autorelease the return value.
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
RawAddress NormalCleanupDest
i32s containing the indexes of the cleanup destinations.
SmallVector< llvm::Value *, 8 > ObjCEHValueStack
ObjCEHValueStack - Stack of Objective-C exception values, used for rethrows.
void EmitVarDecl(const VarDecl &D)
EmitVarDecl - Emit a local variable declaration.
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
llvm::Value * EmitFromMemory(llvm::Value *Value, QualType Ty)
EmitFromMemory - Change a scalar value from its memory representation to its value representation.
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
llvm::LLVMContext & getLLVMContext()
void PopCleanupBlock(bool FallThroughIsBranchThrough=false, bool ForDeactivation=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
This class organizes the cross-function state that is used while generating LLVM code.
llvm::Module & getModule() const
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
void addCompilerUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.compiler.used metadata.
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
bool ReturnTypeUsesFPRet(QualType ResultType)
Return true iff the given type uses 'fpret' when used as a return type.
bool isObjCDirectPreconditionThunkEnabled() const
Check if the precondition thunk optimization is enabled.
bool shouldHavePreconditionThunk(const ObjCMethodDecl *OMD) const
Check if a direct method should use precondition thunks at call sites.
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
const llvm::DataLayout & getDataLayout() const
bool ReturnTypeUsesFP2Ret(QualType ResultType)
Return true iff the given type uses 'fp2ret' when used as a return type.
const llvm::Triple & getTriple() const
bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI)
Return true iff the given type uses an argument slot when 'sret' is used as a return type.
llvm::Constant * CreateRuntimeVariable(llvm::Type *Ty, StringRef Name)
Create a new runtime global variable with the specified type and name.
void ConstructAttributeList(StringRef Name, const CGFunctionInfo &Info, CGCalleeInfo CalleeInfo, llvm::AttributeList &Attrs, unsigned &CallingConv, bool AttrOnCallSite, bool IsThunk)
Get the LLVM attributes and calling convention to use for a particular function type.
ConstantAddress GetAddrOfConstantCFString(const StringLiteral *Literal)
Return a pointer to a constant CFString object for the given string.
ASTContext & getContext() const
bool shouldHavePreconditionInline(const ObjCMethodDecl *OMD) const
Check if a direct method should have inline precondition checks at call sites.
bool ReturnTypeUsesSRet(const CGFunctionInfo &FI)
Return true iff the given type uses 'sret' when used as a return type.
const CodeGenOptions & getCodeGenOpts() const
llvm::LLVMContext & getLLVMContext()
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info, llvm::Function *F, bool IsThunk)
Set the LLVM function attributes (sext, zext, etc).
void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F)
Set the LLVM function attributes which only apply to a function definition.
ConstantAddress GetAddrOfConstantCString(const std::string &Str, StringRef GlobalName=".str")
Returns a pointer to a character array containing the literal and a terminating '\0' character.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
const CGFunctionInfo & arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD)
Objective-C methods are C functions with some implicit parameters.
llvm::Constant * getPointer() const
StructBuilder beginStruct(llvm::StructType *ty=nullptr)
FunctionArgList - Type for representing both the decl and type of parameters to a function.
static RValue get(llvm::Value *V)
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
llvm::Value * getPointer() const
SourceLocation getLocation() const
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
GlobalDecl - represents a global declaration.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
clang::ObjCRuntime ObjCRuntime
std::string ObjCConstantIntegerNumberClass
std::string ObjCConstantDoubleNumberClass
std::string ObjCConstantArrayClass
std::string ObjCConstantStringClass
std::string ObjCConstantDictionaryClass
std::string ObjCConstantFloatNumberClass
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
const Expr * getThrowExpr() const
const ObjCAtFinallyStmt * getFinallyStmt() const
Retrieve the @finally statement, if any.
catch_range catch_stmts()
ObjCContainerDecl - Represents a container for method declarations.
method_range methods() const
prop_range properties() const
const ObjCInterfaceDecl * getClassInterface() const
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Represents an ObjC class declaration.
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for class's metadata.
ObjCInterfaceDecl * getSuperClass() const
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...
ObjCIvarDecl - Represents an ObjC instance variable.
ObjCInterfaceDecl * getContainingInterface()
Return the class interface that this ivar is logically contained in; this is either the interface whe...
ObjCIvarDecl * getNextIvar()
ObjCMethodDecl - Represents an instance or class method declaration.
ImplicitParamDecl * getSelfDecl() const
param_const_iterator param_end() const
param_const_iterator param_begin() const
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
ObjCMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Selector getSelector() const
ImplicitParamDecl * getCmdDecl() const
bool isInstanceMethod() const
QualType getReturnType() const
bool isClassMethod() const
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
bool isObjCIdType() const
True if this is equivalent to the 'id' type, i.e.
Represents an Objective-C protocol declaration.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for protocol's metadata.
ObjCProtocolList::iterator protocol_iterator
protocol_iterator protocol_begin() const
protocol_range protocols() const
protocol_iterator protocol_end() const
bool hasConstantEmptyCollections() const
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
bool hasConstantCFBooleans() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
bool isObjCGCStrong() const
true when Type is objc's strong.
bool isObjCGCWeak() const
true when Type is objc's weak.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
field_range fields() const
Selector getSelector(unsigned NumArgs, const IdentifierInfo **IIV)
Can create any sort of selector.
std::string getAsString() const
Derive the full selector name (e.g.
StringLiteral - This represents a string literal expression, e.g.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
unsigned getCharWidth() const
bool isBlockPointerType() const
CanQualType getCanonicalTypeUnqualified() const
bool isObjCQualifiedIdType() const
bool isObjCIdType() const
bool isObjCObjectPointerType() const
bool isObjCQualifiedClassType() const
bool isObjCClassType() const
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
const T * castAsCanonical() const
Return this type's canonical type cast to the specified type.
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
llvm::Function * getObjCDirectMethodCallee(CodeGenModule &CGM, const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD, bool ReceiverCanBeNull, bool ClassObjectCanBeUnrealized)
Get the appropriate callee for an ObjC direct method.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, BlockDecl > blockDecl
Matches block declarations.
bool LT(InterpState &S, CodePtr OpPC)
@ Address
A pointer to a ValueDecl.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
@ Match
This is not an overload because the signature exactly matches an existing declaration.
bool isa(CodeGen::Address addr)
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
Selector GetUnarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing an unary selector.
@ Result
The result type of a method or function.
Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
@ Type
The name was classified as a type.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
U cast(CodeGen::Address addr)
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ HiddenVisibility
Objects with "hidden" visibility are not seen by the dynamic linker.
CLINKAGE int printf(__constant const char *st,...) __attribute__((format(printf
float __ovld __cnfn length(float)
Return the length of vector p, i.e., sqrt(p.x2 + p.y 2 + ...)
A jump destination is an abstract label, branching to which may require a jump out through normal cle...
llvm::BasicBlock * getBlock() const
llvm::IntegerType * Int64Ty
llvm::CallingConv::ID getRuntimeCC() const
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::IntegerType * IntTy
int
llvm::PointerType * Int8PtrTy
CharUnits getPointerAlign() const
llvm::PointerType * DefaultPtrTy
PointerAuthSchema ObjCIsaPointers
The ABI for Objective-C isa pointers.