28 #include "llvm/ADT/DenseSet.h"
29 #include "llvm/ADT/SetVector.h"
30 #include "llvm/ADT/SmallPtrSet.h"
31 #include "llvm/ADT/SmallString.h"
32 #include "llvm/IR/CallSite.h"
33 #include "llvm/IR/DataLayout.h"
34 #include "llvm/IR/InlineAsm.h"
35 #include "llvm/IR/IntrinsicInst.h"
36 #include "llvm/IR/LLVMContext.h"
37 #include "llvm/IR/Module.h"
38 #include "llvm/Support/raw_ostream.h"
41 using namespace clang;
42 using namespace CodeGen;
49 class ObjCCommonTypesHelper {
51 llvm::LLVMContext &VMContext;
61 llvm::Constant *getMessageSendFn()
const {
64 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
66 CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
69 llvm::AttributeSet::get(CGM.getLLVMContext(),
70 llvm::AttributeSet::FunctionIndex,
71 llvm::Attribute::NonLazyBind));
79 llvm::Constant *getMessageSendStretFn()
const {
80 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
81 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy,
83 "objc_msgSend_stret");
92 llvm::Constant *getMessageSendFpretFn()
const {
93 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
94 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.DoubleTy,
96 "objc_msgSend_fpret");
105 llvm::Constant *getMessageSendFp2retFn()
const {
106 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
107 llvm::Type *longDoubleType = llvm::Type::getX86_FP80Ty(VMContext);
108 llvm::Type *resultType =
109 llvm::StructType::get(longDoubleType, longDoubleType,
nullptr);
111 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(resultType,
113 "objc_msgSend_fp2ret");
121 llvm::Constant *getMessageSendSuperFn()
const {
122 llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
123 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
125 "objc_msgSendSuper");
132 llvm::Constant *getMessageSendSuperFn2()
const {
133 llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
134 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
136 "objc_msgSendSuper2");
143 llvm::Constant *getMessageSendSuperStretFn()
const {
144 llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
145 return CGM.CreateRuntimeFunction(
146 llvm::FunctionType::get(CGM.VoidTy, params,
true),
147 "objc_msgSendSuper_stret");
154 llvm::Constant *getMessageSendSuperStretFn2()
const {
155 llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
156 return CGM.CreateRuntimeFunction(
157 llvm::FunctionType::get(CGM.VoidTy, params,
true),
158 "objc_msgSendSuper2_stret");
161 llvm::Constant *getMessageSendSuperFpretFn()
const {
163 return getMessageSendSuperFn();
166 llvm::Constant *getMessageSendSuperFpretFn2()
const {
168 return getMessageSendSuperFn2();
175 llvm::Type *ShortTy, *IntTy, *LongTy, *LongLongTy;
176 llvm::Type *Int8PtrTy, *Int8PtrPtrTy;
177 llvm::Type *IvarOffsetVarTy;
180 llvm::Type *ObjectPtrTy;
183 llvm::Type *PtrObjectPtrTy;
186 llvm::Type *SelectorPtrTy;
191 llvm::Type *ExternalProtocolPtrTy;
194 llvm::Type *getExternalProtocolPtrTy() {
195 if (!ExternalProtocolPtrTy) {
201 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
204 return ExternalProtocolPtrTy;
213 llvm::StructType *SuperTy;
215 llvm::Type *SuperPtrTy;
219 llvm::StructType *PropertyTy;
223 llvm::StructType *PropertyListTy;
225 llvm::Type *PropertyListPtrTy;
228 llvm::StructType *MethodTy;
233 llvm::Type *CachePtrTy;
235 llvm::Constant *getGetPropertyFn() {
242 Params.push_back(IdType);
243 Params.push_back(SelType);
245 Params.push_back(Ctx.
BoolTy);
246 llvm::FunctionType *FTy =
250 return CGM.CreateRuntimeFunction(FTy,
"objc_getProperty");
253 llvm::Constant *getSetPropertyFn() {
260 Params.push_back(IdType);
261 Params.push_back(SelType);
263 Params.push_back(IdType);
264 Params.push_back(Ctx.
BoolTy);
265 Params.push_back(Ctx.
BoolTy);
266 llvm::FunctionType *FTy =
270 return CGM.CreateRuntimeFunction(FTy,
"objc_setProperty");
273 llvm::Constant *getOptimizedSetPropertyFn(
bool atomic,
bool copy) {
288 Params.push_back(IdType);
289 Params.push_back(SelType);
290 Params.push_back(IdType);
292 llvm::FunctionType *FTy =
298 name =
"objc_setProperty_atomic_copy";
299 else if (atomic && !copy)
300 name =
"objc_setProperty_atomic";
301 else if (!atomic && copy)
302 name =
"objc_setProperty_nonatomic_copy";
304 name =
"objc_setProperty_nonatomic";
306 return CGM.CreateRuntimeFunction(FTy, name);
309 llvm::Constant *getCopyStructFn() {
316 Params.push_back(Ctx.
LongTy);
317 Params.push_back(Ctx.
BoolTy);
318 Params.push_back(Ctx.
BoolTy);
319 llvm::FunctionType *FTy =
323 return CGM.CreateRuntimeFunction(FTy,
"objc_copyStruct");
330 llvm::Constant *getCppAtomicObjectFunction() {
338 llvm::FunctionType *FTy =
343 return CGM.CreateRuntimeFunction(FTy,
"objc_copyCppObjectAtomic");
346 llvm::Constant *getEnumerationMutationFn() {
352 llvm::FunctionType *FTy =
356 return CGM.CreateRuntimeFunction(FTy,
"objc_enumerationMutation");
360 llvm::Constant *getGcReadWeakFn() {
362 llvm::Type *args[] = { ObjectPtrTy->getPointerTo() };
363 llvm::FunctionType *FTy =
364 llvm::FunctionType::get(ObjectPtrTy, args,
false);
365 return CGM.CreateRuntimeFunction(FTy,
"objc_read_weak");
369 llvm::Constant *getGcAssignWeakFn() {
371 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
372 llvm::FunctionType *FTy =
373 llvm::FunctionType::get(ObjectPtrTy, args,
false);
374 return CGM.CreateRuntimeFunction(FTy,
"objc_assign_weak");
378 llvm::Constant *getGcAssignGlobalFn() {
380 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
381 llvm::FunctionType *FTy =
382 llvm::FunctionType::get(ObjectPtrTy, args,
false);
383 return CGM.CreateRuntimeFunction(FTy,
"objc_assign_global");
387 llvm::Constant *getGcAssignThreadLocalFn() {
389 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
390 llvm::FunctionType *FTy =
391 llvm::FunctionType::get(ObjectPtrTy, args,
false);
392 return CGM.CreateRuntimeFunction(FTy,
"objc_assign_threadlocal");
396 llvm::Constant *getGcAssignIvarFn() {
398 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo(),
400 llvm::FunctionType *FTy =
401 llvm::FunctionType::get(ObjectPtrTy, args,
false);
402 return CGM.CreateRuntimeFunction(FTy,
"objc_assign_ivar");
406 llvm::Constant *GcMemmoveCollectableFn() {
408 llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, LongTy };
409 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, args,
false);
410 return CGM.CreateRuntimeFunction(FTy,
"objc_memmove_collectable");
414 llvm::Constant *getGcAssignStrongCastFn() {
416 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
417 llvm::FunctionType *FTy =
418 llvm::FunctionType::get(ObjectPtrTy, args,
false);
419 return CGM.CreateRuntimeFunction(FTy,
"objc_assign_strongCast");
423 llvm::Constant *getExceptionThrowFn() {
425 llvm::Type *args[] = { ObjectPtrTy };
426 llvm::FunctionType *FTy =
427 llvm::FunctionType::get(CGM.VoidTy, args,
false);
428 return CGM.CreateRuntimeFunction(FTy,
"objc_exception_throw");
432 llvm::Constant *getExceptionRethrowFn() {
434 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy,
false);
435 return CGM.CreateRuntimeFunction(FTy,
"objc_exception_rethrow");
439 llvm::Constant *getSyncEnterFn() {
441 llvm::Type *args[] = { ObjectPtrTy };
442 llvm::FunctionType *FTy =
443 llvm::FunctionType::get(CGM.IntTy, args,
false);
444 return CGM.CreateRuntimeFunction(FTy,
"objc_sync_enter");
448 llvm::Constant *getSyncExitFn() {
450 llvm::Type *args[] = { ObjectPtrTy };
451 llvm::FunctionType *FTy =
452 llvm::FunctionType::get(CGM.IntTy, args,
false);
453 return CGM.CreateRuntimeFunction(FTy,
"objc_sync_exit");
456 llvm::Constant *getSendFn(
bool IsSuper)
const {
457 return IsSuper ? getMessageSendSuperFn() : getMessageSendFn();
460 llvm::Constant *getSendFn2(
bool IsSuper)
const {
461 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();
464 llvm::Constant *getSendStretFn(
bool IsSuper)
const {
465 return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();
468 llvm::Constant *getSendStretFn2(
bool IsSuper)
const {
469 return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();
472 llvm::Constant *getSendFpretFn(
bool IsSuper)
const {
473 return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();
476 llvm::Constant *getSendFpretFn2(
bool IsSuper)
const {
477 return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();
480 llvm::Constant *getSendFp2retFn(
bool IsSuper)
const {
481 return IsSuper ? getMessageSendSuperFn() : getMessageSendFp2retFn();
484 llvm::Constant *getSendFp2RetFn2(
bool IsSuper)
const {
485 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFp2retFn();
493 class ObjCTypesHelper :
public ObjCCommonTypesHelper {
496 llvm::StructType *SymtabTy;
498 llvm::Type *SymtabPtrTy;
500 llvm::StructType *ModuleTy;
503 llvm::StructType *ProtocolTy;
505 llvm::Type *ProtocolPtrTy;
508 llvm::StructType *ProtocolExtensionTy;
511 llvm::Type *ProtocolExtensionPtrTy;
514 llvm::StructType *MethodDescriptionTy;
517 llvm::StructType *MethodDescriptionListTy;
520 llvm::Type *MethodDescriptionListPtrTy;
522 llvm::StructType *ProtocolListTy;
524 llvm::Type *ProtocolListPtrTy;
526 llvm::StructType *CategoryTy;
528 llvm::StructType *ClassTy;
530 llvm::Type *ClassPtrTy;
532 llvm::StructType *ClassExtensionTy;
534 llvm::Type *ClassExtensionPtrTy;
536 llvm::StructType *IvarTy;
538 llvm::Type *IvarListTy;
540 llvm::Type *IvarListPtrTy;
542 llvm::Type *MethodListTy;
544 llvm::Type *MethodListPtrTy;
547 llvm::Type *ExceptionDataTy;
550 llvm::Constant *getExceptionTryEnterFn() {
551 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
552 return CGM.CreateRuntimeFunction(
553 llvm::FunctionType::get(CGM.VoidTy, params,
false),
554 "objc_exception_try_enter");
558 llvm::Constant *getExceptionTryExitFn() {
559 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
560 return CGM.CreateRuntimeFunction(
561 llvm::FunctionType::get(CGM.VoidTy, params,
false),
562 "objc_exception_try_exit");
566 llvm::Constant *getExceptionExtractFn() {
567 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
568 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
570 "objc_exception_extract");
574 llvm::Constant *getExceptionMatchFn() {
575 llvm::Type *params[] = { ClassPtrTy, ObjectPtrTy };
576 return CGM.CreateRuntimeFunction(
577 llvm::FunctionType::get(CGM.Int32Ty, params,
false),
578 "objc_exception_match");
583 llvm::Constant *getSetJmpFn() {
585 llvm::Type *params[] = { CGM.Int32Ty->getPointerTo() };
587 CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.Int32Ty,
590 llvm::AttributeSet::get(CGM.getLLVMContext(),
591 llvm::AttributeSet::FunctionIndex,
592 llvm::Attribute::NonLazyBind));
601 class ObjCNonFragileABITypesHelper :
public ObjCCommonTypesHelper {
605 llvm::StructType *MethodListnfABITy;
608 llvm::Type *MethodListnfABIPtrTy;
611 llvm::StructType *ProtocolnfABITy;
614 llvm::Type *ProtocolnfABIPtrTy;
617 llvm::StructType *ProtocolListnfABITy;
620 llvm::Type *ProtocolListnfABIPtrTy;
623 llvm::StructType *ClassnfABITy;
626 llvm::Type *ClassnfABIPtrTy;
629 llvm::StructType *IvarnfABITy;
632 llvm::StructType *IvarListnfABITy;
635 llvm::Type *IvarListnfABIPtrTy;
638 llvm::StructType *ClassRonfABITy;
641 llvm::Type *ImpnfABITy;
644 llvm::StructType *CategorynfABITy;
653 llvm::StructType *MessageRefTy;
658 llvm::Type *MessageRefPtrTy;
663 llvm::FunctionType *MessengerTy;
670 llvm::StructType *SuperMessageRefTy;
673 llvm::Type *SuperMessageRefPtrTy;
675 llvm::Constant *getMessageSendFixupFn() {
677 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
678 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
680 "objc_msgSend_fixup");
683 llvm::Constant *getMessageSendFpretFixupFn() {
685 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
686 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
688 "objc_msgSend_fpret_fixup");
691 llvm::Constant *getMessageSendStretFixupFn() {
693 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
694 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
696 "objc_msgSend_stret_fixup");
699 llvm::Constant *getMessageSendSuper2FixupFn() {
702 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
703 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
705 "objc_msgSendSuper2_fixup");
708 llvm::Constant *getMessageSendSuper2StretFixupFn() {
711 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
712 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
714 "objc_msgSendSuper2_stret_fixup");
717 llvm::Constant *getObjCEndCatchFn() {
718 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy,
false),
723 llvm::Constant *getObjCBeginCatchFn() {
724 llvm::Type *params[] = { Int8PtrTy };
725 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(Int8PtrTy,
730 llvm::StructType *EHTypeTy;
731 llvm::Type *EHTypePtrTy;
741 unsigned ivar_bytepos;
743 GC_IVAR(
unsigned bytepos = 0,
unsigned size = 0)
744 : ivar_bytepos(bytepos), ivar_size(size) {}
748 return ivar_bytepos < b.ivar_bytepos;
756 SKIP_SCAN(
unsigned _skip = 0,
unsigned _scan = 0)
757 : skip(_skip), scan(_scan) {}
764 enum BLOCK_LAYOUT_OPCODE {
771 BLOCK_LAYOUT_OPERATOR = 0,
777 BLOCK_LAYOUT_NON_OBJECT_BYTES = 1,
782 BLOCK_LAYOUT_NON_OBJECT_WORDS = 2,
786 BLOCK_LAYOUT_STRONG = 3,
789 BLOCK_LAYOUT_BYREF = 4,
793 BLOCK_LAYOUT_WEAK = 5,
797 BLOCK_LAYOUT_UNRETAINED = 6
814 enum BLOCK_LAYOUT_OPCODE opcode;
817 RUN_SKIP(
enum BLOCK_LAYOUT_OPCODE Opcode = BLOCK_LAYOUT_OPERATOR,
820 : opcode(Opcode), block_var_bytepos(BytePos), block_var_size(Size) {}
823 bool operator<(
const RUN_SKIP &b)
const {
824 return block_var_bytepos < b.block_var_bytepos;
829 llvm::LLVMContext &VMContext;
842 llvm::SetVector<IdentifierInfo*> LazySymbols;
848 llvm::SetVector<IdentifierInfo*> DefinedSymbols;
851 llvm::StringMap<llvm::GlobalVariable*> ClassNames;
854 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
857 llvm::SetVector<std::string> DefinedCategoryNames;
861 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
865 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
868 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
871 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
874 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
879 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
908 llvm::Constant *GetMethodVarName(
Selector Sel);
916 bool Extended =
false);
917 llvm::Constant *GetMethodVarType(
const FieldDecl *D);
925 const Decl *Container);
930 llvm::Constant *GetClassName(StringRef RuntimeName);
938 bool ForStrongLayout);
940 llvm::Constant *BuildIvarLayoutBitmap(std::string &BitMap);
942 void BuildAggrIvarRecordLayout(
const RecordType *RT,
943 unsigned int BytePos,
bool ForStrongLayout,
946 const llvm::StructLayout *Layout,
949 unsigned int BytePos,
bool ForStrongLayout,
954 void UpdateRunSkipBlockVars(
bool IsByref,
959 void BuildRCBlockVarRecordLayout(
const RecordType *RT,
961 bool ByrefLayout=
false);
963 void BuildRCRecordLayout(
const llvm::StructLayout *RecLayout,
971 llvm::Constant *getBitmapBlockLayout(
bool ComputeByrefLayout);
977 const ObjCCommonTypesHelper &ObjCTypes);
981 llvm::Constant *EmitPropertyList(Twine Name,
982 const Decl *Container,
984 const ObjCCommonTypesHelper &ObjCTypes);
988 llvm::Constant *EmitProtocolMethodTypes(Twine Name,
990 const ObjCCommonTypesHelper &ObjCTypes);
993 void PushProtocolProperties(
994 llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet,
996 const Decl *Container,
998 const ObjCCommonTypesHelper &ObjCTypes);
1019 llvm::GlobalVariable *CreateMetadataVar(Twine Name, llvm::Constant *Init,
1020 StringRef Section,
unsigned Align,
1032 const ObjCCommonTypesHelper &ObjCTypes);
1036 void EmitImageInfo();
1042 llvm::Constant *GenerateConstantString(
const StringLiteral *SL)
override;
1058 virtual llvm::Constant *GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD)=0;
1068 class CGObjCMac :
public CGObjCCommonMac {
1070 ObjCTypesHelper ObjCTypes;
1074 void EmitModuleInfo();
1078 llvm::Constant *EmitModuleSymbols();
1082 void FinishModule();
1118 llvm::Constant *Protocols,
1123 llvm::Constant *GetMethodDescriptionConstant(
const ObjCMethodDecl *MD);
1127 llvm::Constant *EmitMethodList(Twine Name,
1128 const char *Section,
1142 llvm::Constant *EmitMethodDescList(Twine Name,
1143 const char *Section,
1169 llvm::Constant *EmitProtocolList(Twine Name,
1181 llvm::Function *ModuleInitFunction()
override;
1203 bool lval =
false)
override;
1210 llvm::Constant *GetEHType(
QualType T)
override;
1221 llvm::Constant *GetPropertyGetFunction()
override;
1222 llvm::Constant *GetPropertySetFunction()
override;
1223 llvm::Constant *GetOptimizedPropertySetFunction(
bool atomic,
1224 bool copy)
override;
1225 llvm::Constant *GetGetStructFunction()
override;
1226 llvm::Constant *GetSetStructFunction()
override;
1227 llvm::Constant *GetCppAtomicObjectGetFunction()
override;
1228 llvm::Constant *GetCppAtomicObjectSetFunction()
override;
1229 llvm::Constant *EnumerationMutationFunction()
override;
1237 bool ClearInsertionPoint=
true)
override;
1244 bool threadlocal =
false)
override;
1256 unsigned CVRQualifiers)
override;
1263 llvm::GlobalVariable *GetClassGlobal(
const std::string &Name,
1264 bool Weak =
false)
override {
1265 llvm_unreachable(
"CGObjCMac::GetClassGlobal");
1269 class CGObjCNonFragileABIMac :
public CGObjCCommonMac {
1271 ObjCNonFragileABITypesHelper ObjCTypes;
1272 llvm::GlobalVariable* ObjCEmptyCacheVar;
1273 llvm::GlobalVariable* ObjCEmptyVtableVar;
1276 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences;
1279 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences;
1282 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences;
1289 std::vector<llvm::GlobalValue*> DefinedMetaClasses;
1293 bool isVTableDispatchedSelector(
Selector Sel);
1297 void FinishNonFragileABIModule();
1302 const char *SymbolName,
1303 const char *SectionName);
1305 llvm::GlobalVariable * BuildClassRoTInitializer(
unsigned flags,
1306 unsigned InstanceStart,
1307 unsigned InstanceSize,
1309 llvm::GlobalVariable * BuildClassMetaData(
const std::string &ClassName,
1310 llvm::Constant *IsAGV,
1311 llvm::Constant *SuperClassGV,
1312 llvm::Constant *ClassRoGV,
1318 llvm::Constant *GetMethodDescriptionConstant(
const ObjCMethodDecl *MD);
1322 llvm::Constant *EmitMethodList(Twine Name,
1323 const char *Section,
1334 unsigned long int offset);
1349 llvm::Constant *EmitProtocolList(Twine Name,
1365 llvm::GlobalVariable *GetClassGlobal(
const std::string &Name,
1366 bool Weak =
false)
override;
1392 llvm::GlobalVariable * ObjCIvarOffsetVariable(
1404 bool ForDefinition);
1406 const char *getMetaclassSymbolPrefix()
const {
1407 return "OBJC_METACLASS_$_";
1410 const char *getClassSymbolPrefix()
const {
1411 return "OBJC_CLASS_$_";
1415 uint32_t &InstanceStart,
1416 uint32_t &InstanceSize);
1421 return CGM.getContext().Selectors.getSelector(0, &II);
1426 return CGM.getContext().Selectors.getSelector(1, &II);
1431 bool ImplementationIsNonLazy(
const ObjCImplDecl *OD)
const;
1446 dyn_cast_or_null<ObjCMethodDecl>(CGF.
CurFuncDecl))
1447 if (MD->isInstanceMethod())
1456 llvm::Function *ModuleInitFunction()
override;
1478 bool lvalue =
false)
override
1479 {
return EmitSelector(CGF, Sel, lvalue); }
1485 {
return EmitSelector(CGF, Method->
getSelector()); }
1496 llvm::Constant *GetEHType(
QualType T)
override;
1498 llvm::Constant *GetPropertyGetFunction()
override {
1499 return ObjCTypes.getGetPropertyFn();
1501 llvm::Constant *GetPropertySetFunction()
override {
1502 return ObjCTypes.getSetPropertyFn();
1505 llvm::Constant *GetOptimizedPropertySetFunction(
bool atomic,
1506 bool copy)
override {
1507 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
1510 llvm::Constant *GetSetStructFunction()
override {
1511 return ObjCTypes.getCopyStructFn();
1513 llvm::Constant *GetGetStructFunction()
override {
1514 return ObjCTypes.getCopyStructFn();
1516 llvm::Constant *GetCppAtomicObjectSetFunction()
override {
1517 return ObjCTypes.getCppAtomicObjectFunction();
1519 llvm::Constant *GetCppAtomicObjectGetFunction()
override {
1520 return ObjCTypes.getCppAtomicObjectFunction();
1523 llvm::Constant *EnumerationMutationFunction()
override {
1524 return ObjCTypes.getEnumerationMutationFn();
1532 bool ClearInsertionPoint=
true)
override;
1539 bool threadlocal =
false)
override;
1550 unsigned CVRQualifiers)
override;
1558 struct NullReturnState {
1559 llvm::BasicBlock *NullBB;
1560 NullReturnState() : NullBB(nullptr) {}
1573 CGF.
Builder.CreateCondBr(isNull, NullBB, callBB);
1585 if (!NullBB)
return result;
1589 llvm::BasicBlock *contBB =
nullptr;
1592 llvm::BasicBlock *callBB = CGF.
Builder.GetInsertBlock();
1603 CallArgList::const_iterator I = CallArgs.begin();
1605 e = Method->
param_end(); i != e; ++i, ++I) {
1607 if (ParamDecl->
hasAttr<NSConsumedAttr>()) {
1610 "NullReturnState::complete - arg not on object");
1617 assert(CGF.
Builder.GetInsertBlock() == NullBB);
1636 llvm::PHINode *phi = CGF.
Builder.CreatePHI(null->getType(), 2);
1638 phi->addIncoming(null, NullBB);
1647 assert(result.
isAggregate() &&
"null init of non-aggregate result?");
1658 llvm::Type *scalarTy = callResult.first->getType();
1659 llvm::Constant *scalarZero = llvm::Constant::getNullValue(scalarTy);
1662 llvm::PHINode *real = CGF.
Builder.CreatePHI(scalarTy, 2);
1663 real->addIncoming(callResult.first, callBB);
1664 real->addIncoming(scalarZero, NullBB);
1665 llvm::PHINode *imag = CGF.
Builder.CreatePHI(scalarTy, 2);
1666 imag->addIncoming(callResult.second, callBB);
1667 imag->addIncoming(scalarZero, NullBB);
1678 llvm::GlobalVariable *
C,
unsigned idx0,
1681 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),
1682 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)
1684 return llvm::ConstantExpr::getGetElementPtr(C->getValueType(),
C, Idxs);
1691 if (OID->
hasAttr<ObjCExceptionAttr>())
1710 return EmitClassRef(CGF, ID);
1716 return EmitSelector(CGF, Sel, lval);
1723 llvm::Constant *CGObjCMac::GetEHType(
QualType T) {
1726 return CGM.GetAddrOfRTTIDescriptor(
1727 CGM.getContext().getObjCIdRedefinitionType(),
true);
1731 return CGM.GetAddrOfRTTIDescriptor(
1732 CGM.getContext().getObjCClassRedefinitionType(),
true);
1735 return CGM.GetAddrOfRTTIDescriptor(T,
true);
1737 llvm_unreachable(
"asking for catch type for ObjC type in fragile runtime");
1759 llvm::Constant *CGObjCCommonMac::GenerateConstantString(
1761 return (CGM.getLangOpts().NoConstantCFStrings == 0 ?
1762 CGM.GetAddrOfConstantCFString(SL) :
1763 CGM.GetAddrOfConstantString(SL));
1779 bool isCategoryImpl,
1781 bool IsClassMessage,
1789 CGF.
Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
1792 CGF.
Builder.CreateStructGEP(ObjCTypes.SuperTy, ObjCSuper, 0));
1796 if (IsClassMessage) {
1797 if (isCategoryImpl) {
1805 Target = CGF.
Builder.CreateStructGEP(ObjCTypes.ClassTy, Target, 0);
1806 Target = CGF.
Builder.CreateLoad(Target);
1808 llvm::Constant *MetaClassPtr = EmitMetaClassRef(Class);
1810 CGF.
Builder.CreateStructGEP(ObjCTypes.ClassTy, MetaClassPtr, 1);
1814 }
else if (isCategoryImpl)
1818 ClassPtr = CGF.
Builder.CreateStructGEP(ObjCTypes.ClassTy, ClassPtr, 1);
1819 Target = CGF.
Builder.CreateLoad(ClassPtr);
1823 llvm::Type *ClassTy =
1825 Target = CGF.
Builder.CreateBitCast(Target, ClassTy);
1827 Target, CGF.
Builder.CreateStructGEP(ObjCTypes.SuperTy, ObjCSuper, 1));
1828 return EmitMessageSend(CGF, Return, ResultType,
1829 EmitSelector(CGF, Sel),
1830 ObjCSuper, ObjCTypes.SuperPtrCTy,
1831 true, CallArgs, Method, ObjCTypes);
1843 return EmitMessageSend(CGF, Return, ResultType,
1844 EmitSelector(CGF, Sel),
1846 false, CallArgs, Method, ObjCTypes);
1859 const ObjCCommonTypesHelper &ObjCTypes) {
1862 Arg0 = CGF.
Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy);
1863 ActualArgs.
add(RValue::get(Arg0), Arg0Ty);
1868 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
1871 assert(CGM.getContext().getCanonicalType(Method->
getReturnType()) ==
1872 CGM.getContext().getCanonicalType(ResultType) &&
1873 "Result type mismatch!");
1875 NullReturnState nullReturn;
1877 llvm::Constant *Fn =
nullptr;
1878 if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
1879 if (!IsSuper) nullReturn.init(CGF, Arg0);
1880 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
1881 : ObjCTypes.getSendStretFn(IsSuper);
1882 }
else if (CGM.ReturnTypeUsesFPRet(ResultType)) {
1883 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
1884 : ObjCTypes.getSendFpretFn(IsSuper);
1885 }
else if (CGM.ReturnTypeUsesFP2Ret(ResultType)) {
1886 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)
1887 : ObjCTypes.getSendFp2retFn(IsSuper);
1891 if (!IsSuper && CGM.ReturnTypeUsesSRet(MSI.CallInfo))
1892 nullReturn.init(CGF, Arg0);
1893 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
1894 : ObjCTypes.getSendFn(IsSuper);
1897 bool requiresnullCheck =
false;
1898 if (CGM.getLangOpts().ObjCAutoRefCount && Method)
1899 for (
const auto *ParamDecl : Method->
params()) {
1900 if (ParamDecl->
hasAttr<NSConsumedAttr>()) {
1901 if (!nullReturn.NullBB)
1902 nullReturn.init(CGF, Arg0);
1903 requiresnullCheck =
true;
1908 Fn = llvm::ConstantExpr::getBitCast(Fn, MSI.MessengerType);
1909 RValue rvalue = CGF.
EmitCall(MSI.CallInfo, Fn, Return, ActualArgs);
1910 return nullReturn.complete(CGF, rvalue, ResultType, CallArgs,
1911 requiresnullCheck ? Method :
nullptr);
1916 return Qualifiers::Strong;
1919 return Qualifiers::Weak;
1923 return Qualifiers::GCNone;
1926 return Qualifiers::Strong;
1931 return Qualifiers::GCNone;
1934 llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(
CodeGenModule &CGM,
1937 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
1938 if (CGM.
getLangOpts().getGC() == LangOptions::NonGC &&
1942 bool hasUnion =
false;
1950 IvarsInfo.push_back(GC_IVAR(0, 1));
1955 const llvm::StructLayout *layout =
1962 for (
const auto &CI : blockDecl->
captures()) {
1963 const VarDecl *variable = CI.getVariable();
1971 uint64_t fieldOffset = layout->getElementOffset(capture.
getIndex());
1975 IvarsInfo.push_back(GC_IVAR(fieldOffset, 1));
1979 assert(!type->
isArrayType() &&
"array variable should not be caught");
1981 BuildAggrIvarRecordLayout(record, fieldOffset,
true, hasUnion);
1988 if (GCAttr == Qualifiers::Strong)
1989 IvarsInfo.push_back(GC_IVAR(fieldOffset,
1990 fieldSize / WordSizeInBits));
1991 else if (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak)
1992 SkipIvars.push_back(GC_IVAR(fieldOffset,
1993 fieldSize / ByteSizeInBits));
1996 if (IvarsInfo.empty())
2001 llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end());
2002 llvm::array_pod_sort(SkipIvars.begin(), SkipIvars.end());
2005 llvm::Constant *
C = BuildIvarLayoutBitmap(BitMap);
2007 printf(
"\n block variable layout for block: ");
2008 const unsigned char *s = (
const unsigned char*)BitMap.c_str();
2009 for (
unsigned i = 0, e = BitMap.size(); i < e; i++)
2011 printf(
"0x0%x%s", s[i], s[i] != 0 ?
", " :
"");
2013 printf(
"0x%x%s", s[i], s[i] != 0 ?
", " :
"");
2030 return ByrefLayout ? Qualifiers::OCL_ExplicitNone : Qualifiers::OCL_Strong;
2032 return Qualifiers::OCL_None;
2035 void CGObjCCommonMac::UpdateRunSkipBlockVars(
bool IsByref,
2041 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset,
2043 else if (LifeTime == Qualifiers::OCL_Strong)
2044 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset,
2046 else if (LifeTime == Qualifiers::OCL_Weak)
2047 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset,
2049 else if (LifeTime == Qualifiers::OCL_ExplicitNone)
2050 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset,
2053 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES,
2058 void CGObjCCommonMac::BuildRCRecordLayout(
const llvm::StructLayout *RecLayout,
2063 bool IsUnion = (RD && RD->
isUnion());
2064 CharUnits MaxUnionSize = CharUnits::Zero();
2066 const FieldDecl *LastFieldBitfieldOrUnnamed =
nullptr;
2067 CharUnits MaxFieldOffset = CharUnits::Zero();
2068 CharUnits LastBitfieldOrUnnamedOffset = CharUnits::Zero();
2070 if (RecFields.empty())
2074 for (
unsigned i = 0, e = RecFields.size(); i != e; ++i) {
2084 LastFieldBitfieldOrUnnamed = Field;
2085 LastBitfieldOrUnnamedOffset = FieldOffset;
2089 LastFieldBitfieldOrUnnamed =
nullptr;
2096 BytePos + FieldOffset, HasUnion);
2102 dyn_cast_or_null<ConstantArrayType>(Array);
2103 uint64_t ElCount = CArray->
getSize().getZExtValue();
2104 assert(CArray &&
"only array with known element size is supported");
2108 dyn_cast_or_null<ConstantArrayType>(Array);
2109 ElCount *= CArray->
getSize().getZExtValue();
2113 int OldIndex = RunSkipBlockVars.size() - 1;
2115 BuildRCBlockVarRecordLayout(RT, BytePos + FieldOffset,
2121 for (
int FirstIndex = RunSkipBlockVars.size() - 1 ;ElIx < ElCount; ElIx++) {
2123 for (
int i = OldIndex+1; i <= FirstIndex; ++i)
2124 RunSkipBlockVars.push_back(
2125 RUN_SKIP(RunSkipBlockVars[i].opcode,
2126 RunSkipBlockVars[i].block_var_bytepos + Size*ElIx,
2127 RunSkipBlockVars[i].block_var_size));
2135 if (UnionIvarSize > MaxUnionSize) {
2136 MaxUnionSize = UnionIvarSize;
2138 MaxFieldOffset = FieldOffset;
2141 UpdateRunSkipBlockVars(
false,
2142 getBlockCaptureLifetime(FQT, ByrefLayout),
2143 BytePos + FieldOffset,
2148 if (LastFieldBitfieldOrUnnamed) {
2149 if (LastFieldBitfieldOrUnnamed->
isBitField()) {
2151 uint64_t BitFieldSize
2153 unsigned UnsSize = (BitFieldSize / ByteSizeInBits) +
2154 ((BitFieldSize % ByteSizeInBits) != 0);
2155 CharUnits Size = CharUnits::fromQuantity(UnsSize);
2156 Size += LastBitfieldOrUnnamedOffset;
2157 UpdateRunSkipBlockVars(
false,
2158 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
2160 BytePos + LastBitfieldOrUnnamedOffset,
2163 assert(!LastFieldBitfieldOrUnnamed->
getIdentifier() &&
"Expected unnamed");
2167 UpdateRunSkipBlockVars(
false,
2168 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
2170 BytePos + LastBitfieldOrUnnamedOffset,
2176 UpdateRunSkipBlockVars(
false,
2177 getBlockCaptureLifetime(MaxField->
getType(), ByrefLayout),
2178 BytePos + MaxFieldOffset,
2182 void CGObjCCommonMac::BuildRCBlockVarRecordLayout(
const RecordType *RT,
2189 const llvm::StructLayout *RecLayout =
2190 CGM.
getDataLayout().getStructLayout(cast<llvm::StructType>(Ty));
2192 BuildRCRecordLayout(RecLayout, RD, Fields, BytePos, HasUnion, ByrefLayout);
2204 uint64_t CGObjCCommonMac::InlineLayoutInstruction(
2207 if (Layout.size() <= 3) {
2208 unsigned size = Layout.size();
2209 unsigned strong_word_count = 0, byref_word_count=0, weak_word_count=0;
2211 enum BLOCK_LAYOUT_OPCODE opcode ;
2215 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2216 if (opcode == BLOCK_LAYOUT_STRONG)
2217 strong_word_count = (inst & 0xF)+1;
2221 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2222 if (opcode == BLOCK_LAYOUT_BYREF)
2223 byref_word_count = (inst & 0xF)+1;
2227 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2228 if (opcode == BLOCK_LAYOUT_WEAK)
2229 weak_word_count = (inst & 0xF)+1;
2236 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2237 if (opcode == BLOCK_LAYOUT_STRONG) {
2238 strong_word_count = (inst & 0xF)+1;
2240 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2241 if (opcode == BLOCK_LAYOUT_BYREF)
2242 byref_word_count = (inst & 0xF)+1;
2243 else if (opcode == BLOCK_LAYOUT_WEAK)
2244 weak_word_count = (inst & 0xF)+1;
2248 else if (opcode == BLOCK_LAYOUT_BYREF) {
2249 byref_word_count = (inst & 0xF)+1;
2251 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2252 if (opcode == BLOCK_LAYOUT_WEAK)
2253 weak_word_count = (inst & 0xF)+1;
2263 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2264 if (opcode == BLOCK_LAYOUT_STRONG)
2265 strong_word_count = (inst & 0xF)+1;
2266 else if (opcode == BLOCK_LAYOUT_BYREF)
2267 byref_word_count = (inst & 0xF)+1;
2268 else if (opcode == BLOCK_LAYOUT_WEAK)
2269 weak_word_count = (inst & 0xF)+1;
2281 if (strong_word_count == 16 || byref_word_count == 16 || weak_word_count == 16)
2285 (strong_word_count != 0) + (byref_word_count != 0) + (weak_word_count != 0);
2287 if (size == count) {
2288 if (strong_word_count)
2289 Result = strong_word_count;
2291 if (byref_word_count)
2292 Result += byref_word_count;
2294 if (weak_word_count)
2295 Result += weak_word_count;
2301 llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(
bool ComputeByrefLayout) {
2302 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2303 if (RunSkipBlockVars.empty())
2307 unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2311 llvm::array_pod_sort(RunSkipBlockVars.begin(), RunSkipBlockVars.end());
2314 unsigned size = RunSkipBlockVars.size();
2315 for (
unsigned i = 0; i < size; i++) {
2316 enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode;
2317 CharUnits start_byte_pos = RunSkipBlockVars[i].block_var_bytepos;
2318 CharUnits end_byte_pos = start_byte_pos;
2321 if (opcode == RunSkipBlockVars[j].opcode) {
2322 end_byte_pos = RunSkipBlockVars[j++].block_var_bytepos;
2329 end_byte_pos - start_byte_pos + RunSkipBlockVars[j-1].block_var_size;
2332 RunSkipBlockVars[j].block_var_bytepos -
2333 RunSkipBlockVars[j-1].block_var_bytepos - RunSkipBlockVars[j-1].block_var_size;
2334 size_in_bytes += gap;
2336 CharUnits residue_in_bytes = CharUnits::Zero();
2337 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) {
2338 residue_in_bytes = size_in_bytes % WordSizeInBytes;
2339 size_in_bytes -= residue_in_bytes;
2340 opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS;
2343 unsigned size_in_words = size_in_bytes.
getQuantity() / WordSizeInBytes;
2344 while (size_in_words >= 16) {
2347 unsigned char inst = (opcode << 4) | 0xf;
2348 Layout.push_back(inst);
2349 size_in_words -= 16;
2351 if (size_in_words > 0) {
2354 unsigned char inst = (opcode << 4) | (size_in_words-1);
2355 Layout.push_back(inst);
2357 if (residue_in_bytes > CharUnits::Zero()) {
2358 unsigned char inst =
2359 (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) | (residue_in_bytes.
getQuantity()-1);
2360 Layout.push_back(inst);
2364 int e = Layout.size()-1;
2366 unsigned char inst = Layout[e--];
2367 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2368 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES || opcode == BLOCK_LAYOUT_NON_OBJECT_WORDS)
2374 uint64_t Result = InlineLayoutInstruction(Layout);
2378 if (ComputeByrefLayout)
2379 printf(
"\n Inline instruction for BYREF variable layout: ");
2381 printf(
"\n Inline instruction for block variable layout: ");
2382 printf(
"0x0%" PRIx64
"\n", Result);
2384 if (WordSizeInBytes == 8) {
2385 const llvm::APInt Instruction(64, Result);
2386 return llvm::Constant::getIntegerValue(CGM.
Int64Ty, Instruction);
2389 const llvm::APInt Instruction(32, Result);
2390 return llvm::Constant::getIntegerValue(CGM.
Int32Ty, Instruction);
2394 unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0;
2395 Layout.push_back(inst);
2397 for (
unsigned i = 0, e = Layout.size(); i != e; i++)
2398 BitMap += Layout[i];
2401 if (ComputeByrefLayout)
2402 printf(
"\n BYREF variable layout: ");
2404 printf(
"\n block variable layout: ");
2405 for (
unsigned i = 0, e = BitMap.size(); i != e; i++) {
2406 unsigned char inst = BitMap[i];
2407 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2410 case BLOCK_LAYOUT_OPERATOR:
2411 printf(
"BL_OPERATOR:");
2414 case BLOCK_LAYOUT_NON_OBJECT_BYTES:
2415 printf(
"BL_NON_OBJECT_BYTES:");
2417 case BLOCK_LAYOUT_NON_OBJECT_WORDS:
2418 printf(
"BL_NON_OBJECT_WORD:");
2420 case BLOCK_LAYOUT_STRONG:
2421 printf(
"BL_STRONG:");
2423 case BLOCK_LAYOUT_BYREF:
2424 printf(
"BL_BYREF:");
2426 case BLOCK_LAYOUT_WEAK:
2429 case BLOCK_LAYOUT_UNRETAINED:
2430 printf(
"BL_UNRETAINED:");
2435 printf(
"%d", (inst & 0xf) + delta);
2443 llvm::GlobalVariable *Entry = CreateMetadataVar(
2445 llvm::ConstantDataArray::getString(VMContext, BitMap,
false),
2446 "__TEXT,__objc_classname,cstring_literals", 1,
true);
2450 llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(
CodeGenModule &CGM,
2452 assert(CGM.
getLangOpts().getGC() == LangOptions::NonGC);
2454 RunSkipBlockVars.clear();
2455 bool hasUnion =
false;
2459 unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2464 const llvm::StructLayout *layout =
2470 UpdateRunSkipBlockVars(
false, Qualifiers::OCL_None,
2474 for (
const auto &CI : blockDecl->
captures()) {
2475 const VarDecl *variable = CI.getVariable();
2484 CharUnits::fromQuantity(layout->getElementOffset(capture.
getIndex()));
2486 assert(!type->
isArrayType() &&
"array variable should not be caught");
2489 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion);
2494 fieldSize = CharUnits::fromQuantity(WordSizeInBytes);
2497 UpdateRunSkipBlockVars(CI.isByRef(), getBlockCaptureLifetime(type,
false),
2498 fieldOffset, fieldSize);
2500 return getBitmapBlockLayout(
false);
2506 assert(CGM.
getLangOpts().getGC() == LangOptions::NonGC);
2507 assert(!T->
isArrayType() &&
"__block array variable should not be caught");
2509 RunSkipBlockVars.clear();
2510 bool hasUnion =
false;
2512 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion,
true );
2513 llvm::Constant *Result = getBitmapBlockLayout(
true);
2516 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2526 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
2527 ObjCTypes.getExternalProtocolPtrTy());
2539 GetOrEmitProtocol(PD);
2542 llvm::Constant *CGObjCCommonMac::GetProtocolRef(
const ObjCProtocolDecl *PD) {
2544 return GetOrEmitProtocol(PD);
2546 return GetOrEmitProtocolRef(PD);
2562 llvm::GlobalVariable *Entry = Protocols[PD->
getIdentifier()];
2565 if (Entry && Entry->hasInitializer())
2577 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
2578 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
2579 std::vector<llvm::Constant*> MethodTypesExt, OptMethodTypesExt;
2581 llvm::Constant *C = GetMethodDescriptionConstant(MD);
2583 return GetOrEmitProtocolRef(PD);
2585 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
2586 OptInstanceMethods.push_back(C);
2587 OptMethodTypesExt.push_back(GetMethodVarType(MD,
true));
2589 InstanceMethods.push_back(C);
2590 MethodTypesExt.push_back(GetMethodVarType(MD,
true));
2595 llvm::Constant *C = GetMethodDescriptionConstant(MD);
2597 return GetOrEmitProtocolRef(PD);
2599 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
2600 OptClassMethods.push_back(C);
2601 OptMethodTypesExt.push_back(GetMethodVarType(MD,
true));
2603 ClassMethods.push_back(C);
2604 MethodTypesExt.push_back(GetMethodVarType(MD,
true));
2608 MethodTypesExt.insert(MethodTypesExt.end(),
2609 OptMethodTypesExt.begin(), OptMethodTypesExt.end());
2611 llvm::Constant *Values[] = {
2612 EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods,
2615 EmitProtocolList(
"OBJC_PROTOCOL_REFS_" + PD->
getName(),
2617 EmitMethodDescList(
"OBJC_PROTOCOL_INSTANCE_METHODS_" + PD->
getName(),
2618 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
2620 EmitMethodDescList(
"OBJC_PROTOCOL_CLASS_METHODS_" + PD->
getName(),
2621 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2623 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
2628 assert(Entry->hasPrivateLinkage());
2629 Entry->setInitializer(Init);
2631 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolTy,
2632 false, llvm::GlobalValue::PrivateLinkage,
2633 Init,
"OBJC_PROTOCOL_" + PD->
getName());
2634 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
2636 Entry->setAlignment(4);
2645 llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD) {
2646 llvm::GlobalVariable *&Entry = Protocols[PD->
getIdentifier()];
2652 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolTy,
2653 false, llvm::GlobalValue::PrivateLinkage,
2654 nullptr,
"OBJC_PROTOCOL_" + PD->
getName());
2655 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
2657 Entry->setAlignment(4);
2678 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
2679 llvm::Constant *Values[] = {
2680 llvm::ConstantInt::get(ObjCTypes.IntTy, Size),
2681 EmitMethodDescList(
"OBJC_PROTOCOL_INSTANCE_METHODS_OPT_" + PD->
getName(),
2682 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
2683 OptInstanceMethods),
2684 EmitMethodDescList(
"OBJC_PROTOCOL_CLASS_METHODS_OPT_" + PD->
getName(),
2685 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2687 EmitPropertyList(
"OBJC_$_PROP_PROTO_LIST_" + PD->
getName(),
nullptr, PD,
2689 EmitProtocolMethodTypes(
"OBJC_PROTOCOL_METHOD_TYPES_" + PD->
getName(),
2690 MethodTypesExt, ObjCTypes)};
2693 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
2694 Values[3]->isNullValue() && Values[4]->isNullValue())
2695 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
2697 llvm::Constant *Init =
2698 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
2701 return CreateMetadataVar(
"\01l_OBJC_PROTOCOLEXT_" + PD->
getName(), Init,
2702 StringRef(), 0,
true);
2713 CGObjCMac::EmitProtocolList(Twine Name,
2718 for (; begin != end; ++begin)
2719 ProtocolRefs.push_back(GetProtocolRef(*begin));
2722 if (ProtocolRefs.empty())
2723 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
2726 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
2728 llvm::Constant *Values[3];
2730 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
2731 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy,
2732 ProtocolRefs.size() - 1);
2734 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
2735 ProtocolRefs.size()),
2738 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
2739 llvm::GlobalVariable *GV =
2740 CreateMetadataVar(Name, Init,
"__OBJC,__cat_cls_meth,regular,no_dead_strip",
2742 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
2745 void CGObjCCommonMac::
2746 PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*,16> &PropertySet,
2748 const Decl *Container,
2750 const ObjCCommonTypesHelper &ObjCTypes) {
2752 PushProtocolProperties(PropertySet, Properties, Container,
P, ObjCTypes);
2756 llvm::Constant *Prop[] = {
2758 GetPropertyTypeString(PD, Container)
2760 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, Prop));
2776 llvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name,
2777 const Decl *Container,
2779 const ObjCCommonTypesHelper &ObjCTypes) {
2781 llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
2784 llvm::Constant *Prop[] = {
2786 GetPropertyTypeString(PD, Container)
2788 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
2792 for (
const auto *
P : OID->all_referenced_protocols())
2793 PushProtocolProperties(PropertySet, Properties, Container,
P, ObjCTypes);
2796 for (
const auto *
P : CD->protocols())
2797 PushProtocolProperties(PropertySet, Properties, Container,
P, ObjCTypes);
2801 if (Properties.empty())
2802 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
2804 unsigned PropertySize =
2806 llvm::Constant *Values[3];
2807 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
2808 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
2809 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
2811 Values[2] = llvm::ConstantArray::get(AT, Properties);
2812 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
2814 llvm::GlobalVariable *GV =
2815 CreateMetadataVar(Name, Init,
2816 (ObjCABI == 2) ?
"__DATA, __objc_const" :
2817 "__OBJC,__property,regular,no_dead_strip",
2818 (ObjCABI == 2) ? 8 : 4,
2820 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy);
2824 CGObjCCommonMac::EmitProtocolMethodTypes(Twine Name,
2826 const ObjCCommonTypesHelper &ObjCTypes) {
2828 if (MethodTypes.empty())
2829 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy);
2831 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
2832 MethodTypes.size());
2833 llvm::Constant *Init = llvm::ConstantArray::get(AT, MethodTypes);
2835 llvm::GlobalVariable *GV = CreateMetadataVar(
2836 Name, Init, (ObjCABI == 2) ?
"__DATA, __objc_const" : StringRef(),
2837 (ObjCABI == 2) ? 8 : 4,
true);
2838 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.Int8PtrPtrTy);
2848 CGObjCMac::GetMethodDescriptionConstant(
const ObjCMethodDecl *MD) {
2849 llvm::Constant *Desc[] = {
2850 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->
getSelector()),
2851 ObjCTypes.SelectorPtrTy),
2852 GetMethodVarType(MD)
2857 return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
2862 CGObjCMac::EmitMethodDescList(Twine Name,
const char *Section,
2865 if (Methods.empty())
2866 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
2868 llvm::Constant *Values[2];
2869 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
2870 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
2872 Values[1] = llvm::ConstantArray::get(AT, Methods);
2873 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
2875 llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4,
true);
2876 return llvm::ConstantExpr::getBitCast(GV,
2877 ObjCTypes.MethodDescriptionListPtrTy);
2892 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.CategoryTy);
2903 llvm::raw_svector_ostream(ExtName) << Interface->
getName() <<
'_'
2909 InstanceMethods.push_back(GetMethodConstant(I));
2913 ClassMethods.push_back(GetMethodConstant(I));
2915 llvm::Constant *Values[7];
2916 Values[0] = GetClassName(OCD->
getName());
2919 Values[2] = EmitMethodList(
"OBJC_CATEGORY_INSTANCE_METHODS_" + ExtName.str(),
2920 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
2922 Values[3] = EmitMethodList(
"OBJC_CATEGORY_CLASS_METHODS_" + ExtName.str(),
2923 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2927 EmitProtocolList(
"OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
2930 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
2932 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
2936 Values[6] = EmitPropertyList(
"\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
2937 OCD, Category, ObjCTypes);
2939 Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
2942 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
2945 llvm::GlobalVariable *GV =
2946 CreateMetadataVar(
"OBJC_CATEGORY_" + ExtName.str(), Init,
2947 "__OBJC,__category,regular,no_dead_strip", 4,
true);
2948 DefinedCategories.push_back(GV);
2949 DefinedCategoryNames.insert(ExtName.str());
2951 MethodDefinitions.clear();
3013 llvm::Constant *Protocols =
3014 EmitProtocolList(
"OBJC_CLASS_PROTOCOLS_" + ID->
getName(),
3030 InstanceMethods.push_back(GetMethodConstant(I));
3034 ClassMethods.push_back(GetMethodConstant(I));
3037 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
3041 if (llvm::Constant *C = GetMethodConstant(MD))
3042 InstanceMethods.push_back(C);
3044 if (llvm::Constant *C = GetMethodConstant(MD))
3045 InstanceMethods.push_back(C);
3049 llvm::Constant *Values[12];
3050 Values[ 0] = EmitMetaClass(ID, Protocols, ClassMethods);
3053 LazySymbols.insert(Super->getIdentifier());
3056 llvm::ConstantExpr::getBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
3057 ObjCTypes.ClassPtrTy);
3059 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
3063 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
3064 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
3065 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
3066 Values[ 6] = EmitIvarList(ID,
false);
3067 Values[7] = EmitMethodList(
"OBJC_INSTANCE_METHODS_" + ID->
getName(),
3068 "__OBJC,__inst_meth,regular,no_dead_strip",
3071 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
3072 Values[ 9] = Protocols;
3073 Values[10] = BuildIvarLayout(ID,
true);
3074 Values[11] = EmitClassExtension(ID);
3075 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
3077 std::string Name(
"OBJC_CLASS_");
3079 const char *Section =
"__OBJC,__class,regular,no_dead_strip";
3081 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3083 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3084 "Forward metaclass reference has incorrect type.");
3085 GV->setInitializer(Init);
3086 GV->setSection(Section);
3087 GV->setAlignment(4);
3090 GV = CreateMetadataVar(Name, Init, Section, 4,
true);
3091 DefinedClasses.push_back(GV);
3092 ImplementedClasses.push_back(Interface);
3094 MethodDefinitions.clear();
3098 llvm::Constant *Protocols,
3101 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ClassTy);
3106 llvm::Constant *Values[12];
3113 ObjCTypes.ClassPtrTy);
3119 llvm::ConstantExpr::getBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
3120 ObjCTypes.ClassPtrTy);
3122 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
3126 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
3127 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
3128 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
3129 Values[ 6] = EmitIvarList(ID,
true);
3132 "__OBJC,__cls_meth,regular,no_dead_strip", Methods);
3134 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
3135 Values[ 9] = Protocols;
3137 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
3139 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
3140 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
3143 std::string Name(
"OBJC_METACLASS_");
3147 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3149 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3150 "Forward metaclass reference has incorrect type.");
3151 GV->setInitializer(Init);
3153 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
3154 llvm::GlobalValue::PrivateLinkage,
3157 GV->setSection(
"__OBJC,__meta_class,regular,no_dead_strip");
3158 GV->setAlignment(4);
3175 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3177 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
3178 llvm::GlobalValue::PrivateLinkage,
nullptr,
3181 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3182 "Forward metaclass reference has incorrect type.");
3188 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3191 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
3192 llvm::GlobalValue::PrivateLinkage,
nullptr,
3195 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3196 "Forward class metadata reference has incorrect type.");
3210 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
3212 llvm::Constant *Values[3];
3213 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
3214 Values[1] = BuildIvarLayout(ID,
false);
3215 Values[2] = EmitPropertyList(
"\01l_OBJC_$_PROP_LIST_" + ID->
getName(),
3219 if (Values[1]->isNullValue() && Values[2]->isNullValue())
3220 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
3222 llvm::Constant *Init =
3223 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
3224 return CreateMetadataVar(
"OBJC_CLASSEXT_" + ID->
getName(), Init,
3225 "__OBJC,__class_ext,regular,no_dead_strip", 4,
true);
3242 std::vector<llvm::Constant*> Ivars;
3250 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3257 if (!IVD->getDeclName())
3259 llvm::Constant *Ivar[] = {
3260 GetMethodVarName(IVD->getIdentifier()),
3261 GetMethodVarType(IVD),
3262 llvm::ConstantInt::get(ObjCTypes.IntTy,
3263 ComputeIvarBaseOffset(CGM, OID, IVD))
3265 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar));
3270 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3272 llvm::Constant *Values[2];
3273 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
3274 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
3276 Values[1] = llvm::ConstantArray::get(AT, Ivars);
3277 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
3279 llvm::GlobalVariable *GV;
3282 CreateMetadataVar(
"OBJC_CLASS_VARIABLES_" + ID->
getName(), Init,
3283 "__OBJC,__class_vars,regular,no_dead_strip", 4,
true);
3285 GV = CreateMetadataVar(
"OBJC_INSTANCE_VARIABLES_" + ID->
getName(), Init,
3286 "__OBJC,__instance_vars,regular,no_dead_strip", 4,
3288 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy);
3308 llvm::Constant *CGObjCMac::GetMethodConstant(
const ObjCMethodDecl *MD) {
3309 llvm::Function *Fn = GetMethodDefinition(MD);
3313 llvm::Constant *Method[] = {
3314 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->
getSelector()),
3315 ObjCTypes.SelectorPtrTy),
3316 GetMethodVarType(MD),
3317 llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy)
3319 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
3322 llvm::Constant *CGObjCMac::EmitMethodList(Twine Name,
3323 const char *Section,
3326 if (Methods.empty())
3327 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
3329 llvm::Constant *Values[3];
3330 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
3331 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
3332 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
3334 Values[2] = llvm::ConstantArray::get(AT, Methods);
3335 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
3337 llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4,
true);
3338 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListPtrTy);
3341 llvm::Function *CGObjCCommonMac::GenerateMethod(
const ObjCMethodDecl *OMD,
3344 GetNameForMethod(OMD, CD, Name);
3347 llvm::FunctionType *MethodTy =
3349 llvm::Function *Method =
3354 MethodDefinitions.insert(std::make_pair(OMD, Method));
3359 llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
3360 llvm::Constant *Init,
3364 llvm::Type *Ty = Init->getType();
3365 llvm::GlobalVariable *GV =
3366 new llvm::GlobalVariable(CGM.
getModule(), Ty,
false,
3367 llvm::GlobalValue::PrivateLinkage, Init, Name);
3368 if (!Section.empty())
3369 GV->setSection(Section);
3371 GV->setAlignment(Align);
3377 llvm::Function *CGObjCMac::ModuleInitFunction() {
3383 llvm::Constant *CGObjCMac::GetPropertyGetFunction() {
3384 return ObjCTypes.getGetPropertyFn();
3387 llvm::Constant *CGObjCMac::GetPropertySetFunction() {
3388 return ObjCTypes.getSetPropertyFn();
3391 llvm::Constant *CGObjCMac::GetOptimizedPropertySetFunction(
bool atomic,
3393 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
3396 llvm::Constant *CGObjCMac::GetGetStructFunction() {
3397 return ObjCTypes.getCopyStructFn();
3399 llvm::Constant *CGObjCMac::GetSetStructFunction() {
3400 return ObjCTypes.getCopyStructFn();
3403 llvm::Constant *CGObjCMac::GetCppAtomicObjectGetFunction() {
3404 return ObjCTypes.getCppAtomicObjectFunction();
3406 llvm::Constant *CGObjCMac::GetCppAtomicObjectSetFunction() {
3407 return ObjCTypes.getCppAtomicObjectFunction();
3410 llvm::Constant *CGObjCMac::EnumerationMutationFunction() {
3411 return ObjCTypes.getEnumerationMutationFn();
3415 return EmitTryOrSynchronizedStmt(CGF, S);
3420 return EmitTryOrSynchronizedStmt(CGF, S);
3429 ObjCTypesHelper &ObjCTypes;
3430 PerformFragileFinally(
const Stmt *
S,
3434 ObjCTypesHelper *ObjCTypes)
3435 : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
3436 ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
3441 llvm::BasicBlock *FinallyCallExit =
3443 llvm::BasicBlock *FinallyNoCallExit =
3446 FinallyCallExit, FinallyNoCallExit);
3454 if (isa<ObjCAtTryStmt>(
S)) {
3456 cast<ObjCAtTryStmt>(
S).getFinallyStmt()) {
3458 if (flags.isForEHCleanup())
return;
3465 CGF.
EmitStmt(FinallyStmt->getFinallyBody());
3468 CGF.
Builder.CreateStore(CurCleanupDest,
3484 class FragileHazards {
3489 llvm::InlineAsm *ReadHazard;
3490 llvm::InlineAsm *WriteHazard;
3492 llvm::FunctionType *GetAsmFnType();
3494 void collectLocals();
3500 void emitWriteHazard();
3501 void emitHazardsInNewBlocks();
3513 if (Locals.empty())
return;
3516 for (llvm::Function::iterator
3517 I = CGF.
CurFn->begin(), E = CGF.
CurFn->end(); I != E; ++I)
3518 BlocksBeforeTry.insert(&*I);
3520 llvm::FunctionType *AsmFnTy = GetAsmFnType();
3528 std::string Constraint;
3529 for (
unsigned I = 0, E = Locals.size(); I != E; ++I) {
3530 if (I) Constraint +=
',';
3534 ReadHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
3542 std::string Constraint;
3543 for (
unsigned I = 0, E = Locals.size(); I != E; ++I) {
3544 if (I) Constraint +=
',';
3545 Constraint +=
"=*m";
3548 WriteHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
3553 void FragileHazards::emitWriteHazard() {
3554 if (Locals.empty())
return;
3560 assert(!Locals.empty());
3561 llvm::CallInst *call = Builder.CreateCall(ReadHazard, Locals);
3562 call->setDoesNotThrow();
3568 void FragileHazards::emitHazardsInNewBlocks() {
3569 if (Locals.empty())
return;
3574 for (llvm::Function::iterator
3575 FI = CGF.
CurFn->begin(), FE = CGF.
CurFn->end(); FI != FE; ++FI) {
3576 llvm::BasicBlock &BB = *FI;
3577 if (BlocksBeforeTry.count(&BB))
continue;
3580 for (llvm::BasicBlock::iterator
3581 BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) {
3582 llvm::Instruction &I = *BI;
3586 if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I))
continue;
3587 if (isa<llvm::IntrinsicInst>(I))
3592 llvm::CallSite CS(&I);
3593 if (CS.doesNotThrow())
continue;
3600 Builder.SetInsertPoint(&BB, BI);
3601 emitReadHazard(Builder);
3610 void FragileHazards::collectLocals() {
3618 llvm::BasicBlock &Entry = CGF.
CurFn->getEntryBlock();
3619 for (llvm::BasicBlock::iterator
3620 I = Entry.begin(), E = Entry.end(); I != E; ++I)
3621 if (isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I))
3622 Locals.push_back(&*I);
3625 llvm::FunctionType *FragileHazards::GetAsmFnType() {
3627 for (
unsigned i = 0, e = Locals.size(); i != e; ++i)
3628 tys[i] = Locals[i]->getType();
3629 return llvm::FunctionType::get(CGF.
VoidTy, tys,
false);
3746 bool isTry = isa<ObjCAtTryStmt>(
S);
3766 CGF.
EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
3767 SyncArg = CGF.
Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
3771 CGF.
Builder.CreateStore(SyncArg, SyncArgSlot);
3777 "exceptiondata.ptr");
3783 FragileHazards Hazards(CGF);
3814 llvm::Constant *Zero = llvm::ConstantInt::get(CGF.
Builder.getInt32Ty(), 0);
3817 ObjCTypes.ExceptionDataTy, ExceptionData, GEPIndexes,
"setjmp_buffer");
3819 ObjCTypes.getSetJmpFn(), SetJmpBuffer,
"setjmp_result");
3820 SetJmpResult->setCanReturnTwice();
3827 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
3828 CGF.
Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
3833 CGF.
EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
3834 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
3836 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.
Builder.saveAndClearIP();
3842 Hazards.emitWriteHazard();
3846 if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
3855 llvm::CallInst *Caught =
3857 ExceptionData,
"caught");
3867 llvm::BasicBlock *CatchBlock =
nullptr;
3868 llvm::BasicBlock *CatchHandler =
nullptr;
3873 "propagating_exception");
3874 CGF.
Builder.CreateStore(Caught, PropagatingExnVar);
3881 llvm::CallInst *SetJmpResult =
3883 SetJmpBuffer,
"setjmp.result");
3884 SetJmpResult->setCanReturnTwice();
3887 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
3891 CGF.
Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
3896 CGF.
Builder.CreateStore(CGF.
Builder.getInt1(HasFinally), CallTryExitVar);
3901 bool AllMatched =
false;
3937 CatchVarCleanups.ForceCleanup();
3943 assert(OPT &&
"Unexpected non-object pointer type in @catch");
3948 assert(IDecl &&
"Catch parameter must have Objective-C type!");
3954 llvm::CallInst *Match =
3956 matchArgs,
"match");
3961 CGF.
Builder.CreateCondBr(CGF.
Builder.CreateIsNotNull(Match,
"matched"),
3962 MatchedBlock, NextCatchBlock);
3976 CGF.
Builder.CreateBitCast(Caught,
3983 CatchVarCleanups.ForceCleanup();
3994 if (Caught->use_empty())
3995 Caught->eraseFromParent();
4011 assert(PropagatingExnVar);
4012 llvm::CallInst *NewCaught =
4014 ExceptionData,
"caught");
4015 CGF.
Builder.CreateStore(NewCaught, PropagatingExnVar);
4024 Hazards.emitHazardsInNewBlocks();
4027 CGF.
Builder.restoreIP(TryFallthroughIP);
4031 CGF.
EmitBlock(FinallyEnd.getBlock(),
true);
4034 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
4039 if (PropagatingExnVar) {
4040 PropagatingExn = CGF.
Builder.CreateLoad(PropagatingExnVar);
4044 llvm::CallInst *Caught =
4047 PropagatingExn = Caught;
4052 CGF.
Builder.CreateUnreachable();
4055 CGF.
Builder.restoreIP(SavedIP);
4060 bool ClearInsertionPoint) {
4066 CGF.
Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
4069 "Unexpected rethrow outside @catch block.");
4073 CGF.
EmitRuntimeCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
4074 ->setDoesNotReturn();
4075 CGF.
Builder.CreateUnreachable();
4078 if (ClearInsertionPoint)
4079 CGF.
Builder.ClearInsertionPoint();
4087 llvm::Type* DestTy =
4088 cast<llvm::PointerType>(AddrWeakObj->getType())->
getElementType();
4089 AddrWeakObj = CGF.
Builder.CreateBitCast(AddrWeakObj,
4090 ObjCTypes.PtrObjectPtrTy);
4093 AddrWeakObj,
"weakread");
4094 read_weak = CGF.
Builder.CreateBitCast(read_weak, DestTy);
4103 llvm::Type * SrcTy = src->getType();
4104 if (!isa<llvm::PointerType>(SrcTy)) {
4105 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(SrcTy);
4106 assert(Size <= 8 && "does not support size > 8
");
4107 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
4108 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
4109 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4111 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4112 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4113 llvm::Value *args[] = { src, dst };
4114 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(),
4115 args, "weakassign
");
4122 void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
4123 llvm::Value *src, llvm::Value *dst,
4125 llvm::Type * SrcTy = src->getType();
4126 if (!isa<llvm::PointerType>(SrcTy)) {
4127 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4128 assert(Size <= 8 && "does
not support size > 8
");
4129 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
4130 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
4131 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4133 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4134 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4135 llvm::Value *args[] = { src, dst };
4137 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(),
4138 args, "globalassign
");
4140 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(),
4141 args, "threadlocalassign
");
4148 void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
4149 llvm::Value *src, llvm::Value *dst,
4150 llvm::Value *ivarOffset) {
4151 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is
NULL");
4152 llvm::Type * SrcTy = src->getType();
4153 if (!isa<llvm::PointerType>(SrcTy)) {
4154 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4155 assert(Size <= 8 && "does
not support size > 8
");
4156 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
4157 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
4158 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4160 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4161 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4162 llvm::Value *args[] = { src, dst, ivarOffset };
4163 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
4170 void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
4171 llvm::Value *src, llvm::Value *dst) {
4172 llvm::Type * SrcTy = src->getType();
4173 if (!isa<llvm::PointerType>(SrcTy)) {
4174 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4175 assert(Size <= 8 && "does
not support size > 8
");
4176 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
4177 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
4178 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4180 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4181 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4182 llvm::Value *args[] = { src, dst };
4183 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(),
4184 args, "weakassign
");
4188 void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
4189 llvm::Value *DestPtr,
4190 llvm::Value *SrcPtr,
4191 llvm::Value *size) {
4192 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
4193 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
4194 llvm::Value *args[] = { DestPtr, SrcPtr, size };
4195 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
4200 LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
4202 llvm::Value *BaseValue,
4203 const ObjCIvarDecl *Ivar,
4204 unsigned CVRQualifiers) {
4205 const ObjCInterfaceDecl *ID =
4206 ObjectTy->getAs<ObjCObjectType>()->getInterface();
4207 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
4208 EmitIvarOffset(CGF, ID, Ivar));
4211 llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
4212 const ObjCInterfaceDecl *Interface,
4213 const ObjCIvarDecl *Ivar) {
4214 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
4215 return llvm::ConstantInt::get(
4216 CGM.getTypes().ConvertType(CGM.getContext().LongTy),
4220 /* *** Private Interface *** */
4230 enum ImageInfoFlags {
4231 eImageInfo_FixAndContinue = (1 << 0), // This flag is no longer set by clang.
4232 eImageInfo_GarbageCollected = (1 << 1),
4233 eImageInfo_GCOnly = (1 << 2),
4234 eImageInfo_OptimizedByDyld = (1 << 3), // This flag is set by the dyld shared cache.
4236 // A flag indicating that the module has no instances of a @synthesize of a
4237 // superclass variable. <rdar://problem/6803242>
4238 eImageInfo_CorrectedSynthesize = (1 << 4), // This flag is no longer set by clang.
4239 eImageInfo_ImageIsSimulated = (1 << 5)
4242 void CGObjCCommonMac::EmitImageInfo() {
4243 unsigned version = 0; // Version is unused?
4244 const char *Section = (ObjCABI == 1) ?
4245 "__OBJC, __image_info,regular
" :
4246 "__DATA, __objc_imageinfo, regular, no_dead_strip
";
4248 // Generate module-level named metadata to convey this information to the
4249 // linker and code-gen.
4250 llvm::Module &Mod = CGM.getModule();
4252 // Add the ObjC ABI version to the module flags.
4253 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Version
", ObjCABI);
4254 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Version
",
4256 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Section
",
4257 llvm::MDString::get(VMContext,Section));
4259 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
4260 // Non-GC overrides those files which specify GC.
4261 Mod.addModuleFlag(llvm::Module::Override,
4262 "Objective-C Garbage Collection
", (uint32_t)0);
4264 // Add the ObjC garbage collection value.
4265 Mod.addModuleFlag(llvm::Module::Error,
4266 "Objective-C Garbage Collection
",
4267 eImageInfo_GarbageCollected);
4269 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
4270 // Add the ObjC GC Only value.
4271 Mod.addModuleFlag(llvm::Module::Error, "Objective-C GC Only
",
4274 // Require that GC be specified and set to eImageInfo_GarbageCollected.
4275 llvm::Metadata *Ops[2] = {
4276 llvm::MDString::get(VMContext, "Objective-C Garbage Collection
"),
4277 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
4278 llvm::Type::getInt32Ty(VMContext), eImageInfo_GarbageCollected))};
4279 Mod.addModuleFlag(llvm::Module::Require, "Objective-C GC Only
",
4280 llvm::MDNode::get(VMContext, Ops));
4284 // Indicate whether we're compiling this to run on a simulator.
4285 const llvm::Triple &Triple = CGM.getTarget().getTriple();
4286 if (Triple.isiOS() &&
4287 (Triple.getArch() == llvm::Triple::x86 ||
4288 Triple.getArch() == llvm::Triple::x86_64))
4289 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Is Simulated
",
4290 eImageInfo_ImageIsSimulated);
4293 // struct objc_module {
4294 // unsigned long version;
4295 // unsigned long size;
4296 // const char *name;
4300 // FIXME: Get from somewhere
4301 static const int ModuleVersion = 7;
4303 void CGObjCMac::EmitModuleInfo() {
4304 uint64_t Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ModuleTy);
4306 llvm::Constant *Values[] = {
4307 llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion),
4308 llvm::ConstantInt::get(ObjCTypes.LongTy, Size),
4309 // This used to be the filename, now it is unused. <rdr://4327263>
4310 GetClassName(StringRef("")),
4313 CreateMetadataVar("OBJC_MODULES
",
4314 llvm::ConstantStruct::get(ObjCTypes.ModuleTy, Values),
4315 "__OBJC,__module_info,regular,no_dead_strip
", 4, true);
4318 llvm::Constant *CGObjCMac::EmitModuleSymbols() {
4319 unsigned NumClasses = DefinedClasses.size();
4320 unsigned NumCategories = DefinedCategories.size();
4322 // Return null if no symbols were defined.
4323 if (!NumClasses && !NumCategories)
4324 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
4326 llvm::Constant *Values[5];
4327 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
4328 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
4329 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
4330 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
4332 // The runtime expects exactly the list of defined classes followed
4333 // by the list of defined categories, in a single array.
4334 SmallVector<llvm::Constant*, 8> Symbols(NumClasses + NumCategories);
4335 for (unsigned i=0; i<NumClasses; i++) {
4336 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
4338 if (ObjCImplementationDecl *IMP = ID->getImplementation())
4339 // We are implementing a weak imported interface. Give it external linkage
4340 if (ID->isWeakImported() && !IMP->isWeakImported())
4341 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
4343 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
4344 ObjCTypes.Int8PtrTy);
4346 for (unsigned i=0; i<NumCategories; i++)
4347 Symbols[NumClasses + i] =
4348 llvm::ConstantExpr::getBitCast(DefinedCategories[i],
4349 ObjCTypes.Int8PtrTy);
4352 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
4356 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
4358 llvm::GlobalVariable *GV = CreateMetadataVar(
4359 "OBJC_SYMBOLS
", Init, "__OBJC,__symbols,regular,no_dead_strip
", 4, true);
4360 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
4363 llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF,
4364 IdentifierInfo *II) {
4365 LazySymbols.insert(II);
4367 llvm::GlobalVariable *&Entry = ClassReferences[II];
4370 llvm::Constant *Casted =
4371 llvm::ConstantExpr::getBitCast(GetClassName(II->getName()),
4372 ObjCTypes.ClassPtrTy);
4373 Entry = CreateMetadataVar(
4374 "OBJC_CLASS_REFERENCES_
", Casted,
4375 "__OBJC,__cls_refs,literal_pointers,no_dead_strip
", 4, true);
4378 return CGF.Builder.CreateLoad(Entry);
4381 llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF,
4382 const ObjCInterfaceDecl *ID) {
4383 return EmitClassRefFromId(CGF, ID->getIdentifier());
4386 llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
4387 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool
");
4388 return EmitClassRefFromId(CGF, II);
4391 llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel,
4393 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
4396 llvm::Constant *Casted =
4397 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
4398 ObjCTypes.SelectorPtrTy);
4399 Entry = CreateMetadataVar(
4400 "OBJC_SELECTOR_REFERENCES_
", Casted,
4401 "__OBJC,__message_refs,literal_pointers,no_dead_strip
", 4, true);
4402 Entry->setExternallyInitialized(true);
4407 return CGF.Builder.CreateLoad(Entry);
4410 llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) {
4411 llvm::GlobalVariable *&Entry = ClassNames[RuntimeName];
4413 Entry = CreateMetadataVar(
4415 llvm::ConstantDataArray::getString(VMContext, RuntimeName),
4416 ((ObjCABI == 2) ? "__TEXT,__objc_classname,cstring_literals
"
4417 : "__TEXT,__cstring,cstring_literals
"),
4419 return getConstantGEP(VMContext, Entry, 0, 0);
4422 llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
4423 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*>::iterator
4424 I = MethodDefinitions.find(MD);
4425 if (I != MethodDefinitions.end())
4433 llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
4434 const ObjCCommonTypesHelper &ObjCTypes) {
4435 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
4438 void CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT,
4439 unsigned int BytePos,
4440 bool ForStrongLayout,
4442 const RecordDecl *RD = RT->getDecl();
4443 // FIXME - Use iterator.
4444 SmallVector<const FieldDecl*, 16> Fields(RD->fields());
4445 llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
4446 const llvm::StructLayout *RecLayout =
4447 CGM.getDataLayout().getStructLayout(cast<llvm::StructType>(Ty));
4449 BuildAggrIvarLayout(nullptr, RecLayout, RD, Fields, BytePos, ForStrongLayout,
4453 void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
4454 const llvm::StructLayout *Layout,
4455 const RecordDecl *RD,
4456 ArrayRef<const FieldDecl*> RecFields,
4457 unsigned int BytePos, bool ForStrongLayout,
4459 bool IsUnion = (RD && RD->isUnion());
4460 uint64_t MaxUnionIvarSize = 0;
4461 uint64_t MaxSkippedUnionIvarSize = 0;
4462 const FieldDecl *MaxField = nullptr;
4463 const FieldDecl *MaxSkippedField = nullptr;
4464 const FieldDecl *LastFieldBitfieldOrUnnamed = nullptr;
4465 uint64_t MaxFieldOffset = 0;
4466 uint64_t MaxSkippedFieldOffset = 0;
4467 uint64_t LastBitfieldOrUnnamedOffset = 0;
4468 uint64_t FirstFieldDelta = 0;
4470 if (RecFields.empty())
4472 unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(0);
4473 unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
4474 if (!RD && CGM.getLangOpts().ObjCAutoRefCount) {
4475 const FieldDecl *FirstField = RecFields[0];
4477 ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(FirstField));
4480 for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
4481 const FieldDecl *Field = RecFields[i];
4482 uint64_t FieldOffset;
4484 // Note that 'i' here is actually the field index inside RD of Field,
4485 // although this dependency is hidden.
4486 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4487 FieldOffset = (RL.getFieldOffset(i) / ByteSizeInBits) - FirstFieldDelta;
4490 ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(Field)) - FirstFieldDelta;
4492 // Skip over unnamed or bitfields
4493 if (!Field->getIdentifier() || Field->isBitField()) {
4494 LastFieldBitfieldOrUnnamed = Field;
4495 LastBitfieldOrUnnamedOffset = FieldOffset;
4499 LastFieldBitfieldOrUnnamed = nullptr;
4500 QualType FQT = Field->getType();
4501 if (FQT->isRecordType() || FQT->isUnionType()) {
4502 if (FQT->isUnionType())
4505 BuildAggrIvarRecordLayout(FQT->getAs<RecordType>(),
4506 BytePos + FieldOffset,
4507 ForStrongLayout, HasUnion);
4511 if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
4512 const ConstantArrayType *CArray =
4513 dyn_cast_or_null<ConstantArrayType>(Array);
4514 uint64_t ElCount = CArray->getSize().getZExtValue();
4515 assert(CArray && "only array with known element size is supported
");
4516 FQT = CArray->getElementType();
4517 while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
4518 const ConstantArrayType *CArray =
4519 dyn_cast_or_null<ConstantArrayType>(Array);
4520 ElCount *= CArray->getSize().getZExtValue();
4521 FQT = CArray->getElementType();
4523 if (FQT->isRecordType() && ElCount) {
4524 int OldIndex = IvarsInfo.size() - 1;
4525 int OldSkIndex = SkipIvars.size() -1;
4527 const RecordType *RT = FQT->getAs<RecordType>();
4528 BuildAggrIvarRecordLayout(RT, BytePos + FieldOffset,
4529 ForStrongLayout, HasUnion);
4531 // Replicate layout information for each array element. Note that
4532 // one element is already done.
4534 for (int FirstIndex = IvarsInfo.size() - 1,
4535 FirstSkIndex = SkipIvars.size() - 1 ;ElIx < ElCount; ElIx++) {
4536 uint64_t Size = CGM.getContext().getTypeSize(RT)/ByteSizeInBits;
4537 for (int i = OldIndex+1; i <= FirstIndex; ++i)
4538 IvarsInfo.push_back(GC_IVAR(IvarsInfo[i].ivar_bytepos + Size*ElIx,
4539 IvarsInfo[i].ivar_size));
4540 for (int i = OldSkIndex+1; i <= FirstSkIndex; ++i)
4541 SkipIvars.push_back(GC_IVAR(SkipIvars[i].ivar_bytepos + Size*ElIx,
4542 SkipIvars[i].ivar_size));
4547 // At this point, we are done with Record/Union and array there of.
4548 // For other arrays we are down to its element type.
4549 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), FQT);
4551 unsigned FieldSize = CGM.getContext().getTypeSize(Field->getType());
4552 if ((ForStrongLayout && GCAttr == Qualifiers::Strong)
4553 || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
4555 uint64_t UnionIvarSize = FieldSize / WordSizeInBits;
4556 if (UnionIvarSize > MaxUnionIvarSize) {
4557 MaxUnionIvarSize = UnionIvarSize;
4559 MaxFieldOffset = FieldOffset;
4562 IvarsInfo.push_back(GC_IVAR(BytePos + FieldOffset,
4563 FieldSize / WordSizeInBits));
4565 } else if ((ForStrongLayout &&
4566 (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak))
4567 || (!ForStrongLayout && GCAttr != Qualifiers::Weak)) {
4569 // FIXME: Why the asymmetry? We divide by word size in bits on other
4571 uint64_t UnionIvarSize = FieldSize / ByteSizeInBits;
4572 if (UnionIvarSize > MaxSkippedUnionIvarSize) {
4573 MaxSkippedUnionIvarSize = UnionIvarSize;
4574 MaxSkippedField = Field;
4575 MaxSkippedFieldOffset = FieldOffset;
4578 // FIXME: Why the asymmetry, we divide by byte size in bits here?
4579 SkipIvars.push_back(GC_IVAR(BytePos + FieldOffset,
4580 FieldSize / ByteSizeInBits));
4585 if (LastFieldBitfieldOrUnnamed) {
4586 if (LastFieldBitfieldOrUnnamed->isBitField()) {
4587 // Last field was a bitfield. Must update skip info.
4588 uint64_t BitFieldSize
4589 = LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext());
4591 skivar.ivar_bytepos = BytePos + LastBitfieldOrUnnamedOffset;
4592 skivar.ivar_size = (BitFieldSize / ByteSizeInBits)
4593 + ((BitFieldSize % ByteSizeInBits) != 0);
4594 SkipIvars.push_back(skivar);
4596 assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed
");
4597 // Last field was unnamed. Must update skip info.
4599 = CGM.getContext().getTypeSize(LastFieldBitfieldOrUnnamed->getType());
4600 SkipIvars.push_back(GC_IVAR(BytePos + LastBitfieldOrUnnamedOffset,
4601 FieldSize / ByteSizeInBits));
4606 IvarsInfo.push_back(GC_IVAR(BytePos + MaxFieldOffset,
4608 if (MaxSkippedField)
4609 SkipIvars.push_back(GC_IVAR(BytePos + MaxSkippedFieldOffset,
4610 MaxSkippedUnionIvarSize));
4618 llvm::Constant *CGObjCCommonMac::BuildIvarLayoutBitmap(std::string &BitMap) {
4619 unsigned int WordsToScan, WordsToSkip;
4620 llvm::Type *PtrTy = CGM.Int8PtrTy;
4622 // Build the string of skip/scan nibbles
4623 SmallVector<SKIP_SCAN, 32> SkipScanIvars;
4624 unsigned int WordSize =
4625 CGM.getTypes().getDataLayout().getTypeAllocSize(PtrTy);
4626 if (IvarsInfo[0].ivar_bytepos == 0) {
4628 WordsToScan = IvarsInfo[0].ivar_size;
4630 WordsToSkip = IvarsInfo[0].ivar_bytepos/WordSize;
4631 WordsToScan = IvarsInfo[0].ivar_size;
4633 for (unsigned int i=1, Last=IvarsInfo.size(); i != Last; i++) {
4634 unsigned int TailPrevGCObjC =
4635 IvarsInfo[i-1].ivar_bytepos + IvarsInfo[i-1].ivar_size * WordSize;
4636 if (IvarsInfo[i].ivar_bytepos == TailPrevGCObjC) {
4637 // consecutive 'scanned' object pointers.
4638 WordsToScan += IvarsInfo[i].ivar_size;
4640 // Skip over 'gc'able object pointer which lay over each other.
4641 if (TailPrevGCObjC > IvarsInfo[i].ivar_bytepos)
4643 // Must skip over 1 or more words. We save current skip/scan values
4644 // and start a new pair.
4646 SkScan.skip = WordsToSkip;
4647 SkScan.scan = WordsToScan;
4648 SkipScanIvars.push_back(SkScan);
4651 SkScan.skip = (IvarsInfo[i].ivar_bytepos - TailPrevGCObjC) / WordSize;
4653 SkipScanIvars.push_back(SkScan);
4655 WordsToScan = IvarsInfo[i].ivar_size;
4658 if (WordsToScan > 0) {
4660 SkScan.skip = WordsToSkip;
4661 SkScan.scan = WordsToScan;
4662 SkipScanIvars.push_back(SkScan);
4665 if (!SkipIvars.empty()) {
4666 unsigned int LastIndex = SkipIvars.size()-1;
4667 int LastByteSkipped =
4668 SkipIvars[LastIndex].ivar_bytepos + SkipIvars[LastIndex].ivar_size;
4669 LastIndex = IvarsInfo.size()-1;
4670 int LastByteScanned =
4671 IvarsInfo[LastIndex].ivar_bytepos +
4672 IvarsInfo[LastIndex].ivar_size * WordSize;
4673 // Compute number of bytes to skip at the tail end of the last ivar scanned.
4674 if (LastByteSkipped > LastByteScanned) {
4675 unsigned int TotalWords = (LastByteSkipped + (WordSize -1)) / WordSize;
4677 SkScan.skip = TotalWords - (LastByteScanned/WordSize);
4679 SkipScanIvars.push_back(SkScan);
4682 // Mini optimization of nibbles such that an 0xM0 followed by 0x0N is produced
4684 int SkipScan = SkipScanIvars.size()-1;
4685 for (int i = 0; i <= SkipScan; i++) {
4686 if ((i < SkipScan) && SkipScanIvars[i].skip && SkipScanIvars[i].scan == 0
4687 && SkipScanIvars[i+1].skip == 0 && SkipScanIvars[i+1].scan) {
4688 // 0xM0 followed by 0x0N detected.
4689 SkipScanIvars[i].scan = SkipScanIvars[i+1].scan;
4690 for (int j = i+1; j < SkipScan; j++)
4691 SkipScanIvars[j] = SkipScanIvars[j+1];
4696 // Generate the string.
4697 for (int i = 0; i <= SkipScan; i++) {
4699 unsigned int skip_small = SkipScanIvars[i].skip % 0xf;
4700 unsigned int scan_small = SkipScanIvars[i].scan % 0xf;
4701 unsigned int skip_big = SkipScanIvars[i].skip / 0xf;
4702 unsigned int scan_big = SkipScanIvars[i].scan / 0xf;
4705 for (unsigned int ix = 0; ix < skip_big; ix++)
4706 BitMap += (unsigned char)(0xf0);
4708 // next (skip small, scan)
4710 byte = skip_small << 4;
4714 } else if (scan_small) {
4721 for (unsigned int ix = 0; ix < scan_big; ix++)
4722 BitMap += (unsigned char)(0x0f);
4729 // null terminate string.
4730 unsigned char zero = 0;
4733 llvm::GlobalVariable *Entry = CreateMetadataVar(
4735 llvm::ConstantDataArray::getString(VMContext, BitMap, false),
4736 ((ObjCABI == 2) ? "__TEXT,__objc_classname,cstring_literals
"
4737 : "__TEXT,__cstring,cstring_literals
"),
4739 return getConstantGEP(VMContext, Entry, 0, 0);
4758 llvm::Constant *CGObjCCommonMac::BuildIvarLayout(
4759 const ObjCImplementationDecl *OMD,
4760 bool ForStrongLayout) {
4761 bool hasUnion = false;
4763 llvm::Type *PtrTy = CGM.Int8PtrTy;
4764 if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
4765 !CGM.getLangOpts().ObjCAutoRefCount)
4766 return llvm::Constant::getNullValue(PtrTy);
4768 const ObjCInterfaceDecl *OI = OMD->getClassInterface();
4769 SmallVector<const FieldDecl*, 32> RecFields;
4770 if (CGM.getLangOpts().ObjCAutoRefCount) {
4771 for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();
4772 IVD; IVD = IVD->getNextIvar())
4773 RecFields.push_back(cast<FieldDecl>(IVD));
4776 SmallVector<const ObjCIvarDecl*, 32> Ivars;
4777 CGM.getContext().DeepCollectObjCIvars(OI, true, Ivars);
4779 // FIXME: This is not ideal; we shouldn't have to do this copy.
4780 RecFields.append(Ivars.begin(), Ivars.end());
4783 if (RecFields.empty())
4784 return llvm::Constant::getNullValue(PtrTy);
4789 BuildAggrIvarLayout(OMD, nullptr, nullptr, RecFields, 0, ForStrongLayout,
4791 if (IvarsInfo.empty())
4792 return llvm::Constant::getNullValue(PtrTy);
4793 // Sort on byte position in case we encounterred a union nested in
4795 if (hasUnion && !IvarsInfo.empty())
4796 std::sort(IvarsInfo.begin(), IvarsInfo.end());
4797 if (hasUnion && !SkipIvars.empty())
4798 std::sort(SkipIvars.begin(), SkipIvars.end());
4801 llvm::Constant *C = BuildIvarLayoutBitmap(BitMap);
4803 if (CGM.getLangOpts().ObjCGCBitmapPrint) {
4804 printf("\n%s ivar layout
for class '%s':
",
4805 ForStrongLayout ? "strong
" : "weak
",
4806 OMD->getClassInterface()->getName().str().c_str());
4807 const unsigned char *s = (const unsigned char*)BitMap.c_str();
4808 for (unsigned i = 0, e = BitMap.size(); i < e; i++)
4810 printf("0x0%x%s
", s[i], s[i] != 0 ? ",
" : "");
4812 printf("0x%x%s
", s[i], s[i] != 0 ? ",
" : "");
4818 llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
4819 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
4821 // FIXME: Avoid std::string in "Sel.getAsString()
"
4823 Entry = CreateMetadataVar(
4824 "OBJC_METH_VAR_NAME_
",
4825 llvm::ConstantDataArray::getString(VMContext, Sel.getAsString()),
4826 ((ObjCABI == 2) ? "__TEXT,__objc_methname,cstring_literals
"
4827 : "__TEXT,__cstring,cstring_literals
"),
4830 return getConstantGEP(VMContext, Entry, 0, 0);
4833 // FIXME: Merge into a single cstring creation function.
4834 llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
4835 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
4838 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
4839 std::string TypeStr;
4840 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
4842 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
4845 Entry = CreateMetadataVar(
4846 "OBJC_METH_VAR_TYPE_
",
4847 llvm::ConstantDataArray::getString(VMContext, TypeStr),
4848 ((ObjCABI == 2) ? "__TEXT,__objc_methtype,cstring_literals
"
4849 : "__TEXT,__cstring,cstring_literals
"),
4852 return getConstantGEP(VMContext, Entry, 0, 0);
4855 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D,
4857 std::string TypeStr;
4858 if (CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr, Extended))
4861 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
4864 Entry = CreateMetadataVar(
4865 "OBJC_METH_VAR_TYPE_
",
4866 llvm::ConstantDataArray::getString(VMContext, TypeStr),
4867 ((ObjCABI == 2) ? "__TEXT,__objc_methtype,cstring_literals
"
4868 : "__TEXT,__cstring,cstring_literals
"),
4871 return getConstantGEP(VMContext, Entry, 0, 0);
4874 // FIXME: Merge into a single cstring creation function.
4875 llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
4876 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
4879 Entry = CreateMetadataVar(
4880 "OBJC_PROP_NAME_ATTR_
",
4881 llvm::ConstantDataArray::getString(VMContext, Ident->getName()),
4882 "__TEXT,__cstring,cstring_literals
", 1, true);
4884 return getConstantGEP(VMContext, Entry, 0, 0);
4887 // FIXME: Merge into a single cstring creation function.
4888 // FIXME: This Decl should be more precise.
4890 CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
4891 const Decl *Container) {
4892 std::string TypeStr;
4893 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr);
4894 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
4897 void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D,
4898 const ObjCContainerDecl *CD,
4899 SmallVectorImpl<char> &Name) {
4900 llvm::raw_svector_ostream OS(Name);
4901 assert (CD && "Missing container
decl in GetNameForMethod
");
4902 OS << '\01' << (D->isInstanceMethod() ? '-' : '+')
4903 << '[' << CD->getName();
4904 if (const ObjCCategoryImplDecl *CID =
4905 dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
4906 OS << '(' << *CID << ')';
4907 OS << ' ' << D->getSelector().getAsString() << ']';
4910 void CGObjCMac::FinishModule() {
4913 // Emit the dummy bodies for any protocols which were referenced but
4915 for (llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*>::iterator
4916 I = Protocols.begin(), e = Protocols.end(); I != e; ++I) {
4917 if (I->second->hasInitializer())
4920 llvm::Constant *Values[5];
4921 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
4922 Values[1] = GetClassName(I->first->getName());
4923 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
4924 Values[3] = Values[4] =
4925 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
4926 I->second->setInitializer(llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
4928 CGM.addCompilerUsedGlobal(I->second);
4931 // Add assembler directives to add lazy undefined symbol references
4932 // for classes which are referenced but not defined. This is
4933 // important for correct linker interaction.
4935 // FIXME: It would be nice if we had an LLVM construct for this.
4936 if (!LazySymbols.empty() || !DefinedSymbols.empty()) {
4937 SmallString<256> Asm;
4938 Asm += CGM.getModule().getModuleInlineAsm();
4939 if (!Asm.empty() && Asm.back() != '\n')
4942 llvm::raw_svector_ostream OS(Asm);
4943 for (llvm::SetVector<IdentifierInfo*>::iterator I = DefinedSymbols.begin(),
4944 e = DefinedSymbols.end(); I != e; ++I)
4945 OS << "\t.objc_class_name_
" << (*I)->getName() << "=0\n
"
4946 << "\t.globl .objc_class_name_
" << (*I)->getName() << "\n
";
4947 for (llvm::SetVector<IdentifierInfo*>::iterator I = LazySymbols.begin(),
4948 e = LazySymbols.end(); I != e; ++I) {
4949 OS << "\t.lazy_reference .objc_class_name_
" << (*I)->getName() << "\n
";
4952 for (size_t i = 0, e = DefinedCategoryNames.size(); i < e; ++i) {
4953 OS << "\t.objc_category_name_
" << DefinedCategoryNames[i] << "=0\n
"
4954 << "\t.globl .objc_category_name_
" << DefinedCategoryNames[i] << "\n
";
4957 CGM.getModule().setModuleInlineAsm(OS.str());
4961 CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
4962 : CGObjCCommonMac(cgm),
4964 ObjCEmptyCacheVar = ObjCEmptyVtableVar = nullptr;
4970 ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
4971 : VMContext(cgm.getLLVMContext()), CGM(cgm), ExternalProtocolPtrTy(nullptr)
4973 CodeGen::CodeGenTypes &Types = CGM.getTypes();
4974 ASTContext &Ctx = CGM.getContext();
4976 ShortTy = Types.ConvertType(Ctx.ShortTy);
4977 IntTy = Types.ConvertType(Ctx.IntTy);
4978 LongTy = Types.ConvertType(Ctx.LongTy);
4979 LongLongTy = Types.ConvertType(Ctx.LongLongTy);
4980 Int8PtrTy = CGM.Int8PtrTy;
4981 Int8PtrPtrTy = CGM.Int8PtrPtrTy;
4983 // arm64 targets use "int" ivar offset variables. All others,
4984 // including OS X x86_64 and Windows x86_64, use "long" ivar offsets.
4985 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::aarch64)
4986 IvarOffsetVarTy = IntTy;
4988 IvarOffsetVarTy = LongTy;
4990 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
4991 PtrObjectPtrTy = llvm::PointerType::getUnqual(ObjectPtrTy);
4992 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
4994 // I'm not sure I like this. The implicit coordination is a bit
4995 // gross. We should solve this in a reasonable fashion because this
4996 // is a pretty common task (match some runtime data structure with
4997 // an LLVM data structure).
4999 // FIXME: This is leaked.
5000 // FIXME: Merge with rewriter code?
5002 // struct _objc_super {
5006 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
5007 Ctx.getTranslationUnitDecl(),
5008 SourceLocation(), SourceLocation(),
5009 &Ctx.Idents.get("_objc_super
"));
5010 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5011 nullptr, Ctx.getObjCIdType(), nullptr, nullptr,
5012 false, ICIS_NoInit));
5013 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5014 nullptr, Ctx.getObjCClassType(), nullptr,
5015 nullptr, false, ICIS_NoInit));
5016 RD->completeDefinition();
5018 SuperCTy = Ctx.getTagDeclType(RD);
5019 SuperPtrCTy = Ctx.getPointerType(SuperCTy);
5021 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
5022 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
5026 // char *attributes;
5028 PropertyTy = llvm::StructType::create("struct._prop_t
",
5029 Int8PtrTy, Int8PtrTy, nullptr);
5031 // struct _prop_list_t {
5032 // uint32_t entsize; // sizeof(struct _prop_t)
5033 // uint32_t count_of_properties;
5034 // struct _prop_t prop_list[count_of_properties];
5037 llvm::StructType::create("struct._prop_list_t
", IntTy, IntTy,
5038 llvm::ArrayType::get(PropertyTy, 0), nullptr);
5039 // struct _prop_list_t *
5040 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
5042 // struct _objc_method {
5044 // char *method_type;
5047 MethodTy = llvm::StructType::create("struct._objc_method
",
5048 SelectorPtrTy, Int8PtrTy, Int8PtrTy,
5051 // struct _objc_cache *
5052 CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache
");
5053 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
5057 ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
5058 : ObjCCommonTypesHelper(cgm) {
5059 // struct _objc_method_description {
5063 MethodDescriptionTy =
5064 llvm::StructType::create("struct._objc_method_description
",
5065 SelectorPtrTy, Int8PtrTy, nullptr);
5067 // struct _objc_method_description_list {
5069 // struct _objc_method_description[1];
5071 MethodDescriptionListTy = llvm::StructType::create(
5072 "struct._objc_method_description_list
", IntTy,
5073 llvm::ArrayType::get(MethodDescriptionTy, 0), nullptr);
5075 // struct _objc_method_description_list *
5076 MethodDescriptionListPtrTy =
5077 llvm::PointerType::getUnqual(MethodDescriptionListTy);
5079 // Protocol description structures
5081 // struct _objc_protocol_extension {
5082 // uint32_t size; // sizeof(struct _objc_protocol_extension)
5083 // struct _objc_method_description_list *optional_instance_methods;
5084 // struct _objc_method_description_list *optional_class_methods;
5085 // struct _objc_property_list *instance_properties;
5086 // const char ** extendedMethodTypes;
5088 ProtocolExtensionTy =
5089 llvm::StructType::create("struct._objc_protocol_extension
",
5090 IntTy, MethodDescriptionListPtrTy,
5091 MethodDescriptionListPtrTy, PropertyListPtrTy,
5092 Int8PtrPtrTy, nullptr);
5094 // struct _objc_protocol_extension *
5095 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
5097 // Handle recursive construction of Protocol and ProtocolList types
5100 llvm::StructType::create(VMContext, "struct._objc_protocol
");
5103 llvm::StructType::create(VMContext, "struct._objc_protocol_list
");
5104 ProtocolListTy->setBody(llvm::PointerType::getUnqual(ProtocolListTy),
5106 llvm::ArrayType::get(ProtocolTy, 0),
5109 // struct _objc_protocol {
5110 // struct _objc_protocol_extension *isa;
5111 // char *protocol_name;
5112 // struct _objc_protocol **_objc_protocol_list;
5113 // struct _objc_method_description_list *instance_methods;
5114 // struct _objc_method_description_list *class_methods;
5116 ProtocolTy->setBody(ProtocolExtensionPtrTy, Int8PtrTy,
5117 llvm::PointerType::getUnqual(ProtocolListTy),
5118 MethodDescriptionListPtrTy,
5119 MethodDescriptionListPtrTy,
5122 // struct _objc_protocol_list *
5123 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
5125 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
5127 // Class description structures
5129 // struct _objc_ivar {
5134 IvarTy = llvm::StructType::create("struct._objc_ivar
",
5135 Int8PtrTy, Int8PtrTy, IntTy, nullptr);
5137 // struct _objc_ivar_list *
5139 llvm::StructType::create(VMContext, "struct._objc_ivar_list
");
5140 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
5142 // struct _objc_method_list *
5144 llvm::StructType::create(VMContext, "struct._objc_method_list
");
5145 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
5147 // struct _objc_class_extension *
5149 llvm::StructType::create("struct._objc_class_extension
",
5150 IntTy, Int8PtrTy, PropertyListPtrTy, nullptr);
5151 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
5153 ClassTy = llvm::StructType::create(VMContext, "struct._objc_class
");
5155 // struct _objc_class {
5157 // Class super_class;
5161 // long instance_size;
5162 // struct _objc_ivar_list *ivars;
5163 // struct _objc_method_list *methods;
5164 // struct _objc_cache *cache;
5165 // struct _objc_protocol_list *protocols;
5166 // char *ivar_layout;
5167 // struct _objc_class_ext *ext;
5169 ClassTy->setBody(llvm::PointerType::getUnqual(ClassTy),
5170 llvm::PointerType::getUnqual(ClassTy),
5180 ClassExtensionPtrTy,
5183 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
5185 // struct _objc_category {
5186 // char *category_name;
5187 // char *class_name;
5188 // struct _objc_method_list *instance_method;
5189 // struct _objc_method_list *class_method;
5190 // uint32_t size; // sizeof(struct _objc_category)
5191 // struct _objc_property_list *instance_properties;// category's @property
5194 llvm::StructType::create("struct._objc_category
",
5195 Int8PtrTy, Int8PtrTy, MethodListPtrTy,
5196 MethodListPtrTy, ProtocolListPtrTy,
5197 IntTy, PropertyListPtrTy, nullptr);
5199 // Global metadata structures
5201 // struct _objc_symtab {
5202 // long sel_ref_cnt;
5204 // short cls_def_cnt;
5205 // short cat_def_cnt;
5206 // char *defs[cls_def_cnt + cat_def_cnt];
5209 llvm::StructType::create("struct._objc_symtab
",
5210 LongTy, SelectorPtrTy, ShortTy, ShortTy,
5211 llvm::ArrayType::get(Int8PtrTy, 0), nullptr);
5212 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
5214 // struct _objc_module {
5216 // long size; // sizeof(struct _objc_module)
5218 // struct _objc_symtab* symtab;
5221 llvm::StructType::create("struct._objc_module
",
5222 LongTy, LongTy, Int8PtrTy, SymtabPtrTy, nullptr);
5225 // FIXME: This is the size of the setjmp buffer and should be target
5226 // specific. 18 is what's used on 32-bit X86.
5227 uint64_t SetJmpBufferSize = 18;
5230 llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4);
5233 llvm::StructType::create("struct._objc_exception_data
",
5234 llvm::ArrayType::get(CGM.Int32Ty,SetJmpBufferSize),
5235 StackPtrTy, nullptr);
5239 ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm)
5240 : ObjCCommonTypesHelper(cgm) {
5241 // struct _method_list_t {
5242 // uint32_t entsize; // sizeof(struct _objc_method)
5243 // uint32_t method_count;
5244 // struct _objc_method method_list[method_count];
5247 llvm::StructType::create("struct.__method_list_t
", IntTy, IntTy,
5248 llvm::ArrayType::get(MethodTy, 0), nullptr);
5249 // struct method_list_t *
5250 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy);
5252 // struct _protocol_t {
5254 // const char * const protocol_name;
5255 // const struct _protocol_list_t * protocol_list; // super protocols
5256 // const struct method_list_t * const instance_methods;
5257 // const struct method_list_t * const class_methods;
5258 // const struct method_list_t *optionalInstanceMethods;
5259 // const struct method_list_t *optionalClassMethods;
5260 // const struct _prop_list_t * properties;
5261 // const uint32_t size; // sizeof(struct _protocol_t)
5262 // const uint32_t flags; // = 0
5263 // const char ** extendedMethodTypes;
5264 // const char *demangledName;
5267 // Holder for struct _protocol_list_t *
5268 ProtocolListnfABITy =
5269 llvm::StructType::create(VMContext, "struct._objc_protocol_list
");
5272 llvm::StructType::create("struct._protocol_t
", ObjectPtrTy, Int8PtrTy,
5273 llvm::PointerType::getUnqual(ProtocolListnfABITy),
5274 MethodListnfABIPtrTy, MethodListnfABIPtrTy,
5275 MethodListnfABIPtrTy, MethodListnfABIPtrTy,
5276 PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy,
5280 // struct _protocol_t*
5281 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy);
5283 // struct _protocol_list_t {
5284 // long protocol_count; // Note, this is 32/64 bit
5285 // struct _protocol_t *[protocol_count];
5287 ProtocolListnfABITy->setBody(LongTy,
5288 llvm::ArrayType::get(ProtocolnfABIPtrTy, 0),
5291 // struct _objc_protocol_list*
5292 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy);
5295 // unsigned [long] int *offset; // pointer to ivar offset location
5298 // uint32_t alignment;
5301 IvarnfABITy = llvm::StructType::create(
5302 "struct._ivar_t
", llvm::PointerType::getUnqual(IvarOffsetVarTy),
5303 Int8PtrTy, Int8PtrTy, IntTy, IntTy, nullptr);
5305 // struct _ivar_list_t {
5306 // uint32 entsize; // sizeof(struct _ivar_t)
5308 // struct _iver_t list[count];
5311 llvm::StructType::create("struct._ivar_list_t
", IntTy, IntTy,
5312 llvm::ArrayType::get(IvarnfABITy, 0), nullptr);
5314 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy);
5316 // struct _class_ro_t {
5317 // uint32_t const flags;
5318 // uint32_t const instanceStart;
5319 // uint32_t const instanceSize;
5320 // uint32_t const reserved; // only when building for 64bit targets
5321 // const uint8_t * const ivarLayout;
5322 // const char *const name;
5323 // const struct _method_list_t * const baseMethods;
5324 // const struct _objc_protocol_list *const baseProtocols;
5325 // const struct _ivar_list_t *const ivars;
5326 // const uint8_t * const weakIvarLayout;
5327 // const struct _prop_list_t * const properties;
5330 // FIXME. Add 'reserved' field in 64bit abi mode!
5331 ClassRonfABITy = llvm::StructType::create("struct._class_ro_t
",
5332 IntTy, IntTy, IntTy, Int8PtrTy,
5333 Int8PtrTy, MethodListnfABIPtrTy,
5334 ProtocolListnfABIPtrTy,
5336 Int8PtrTy, PropertyListPtrTy,
5339 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
5340 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
5341 ImpnfABITy = llvm::FunctionType::get(ObjectPtrTy, params, false)
5344 // struct _class_t {
5345 // struct _class_t *isa;
5346 // struct _class_t * const superclass;
5349 // struct class_ro_t *ro;
5352 ClassnfABITy = llvm::StructType::create(VMContext, "struct._class_t
");
5353 ClassnfABITy->setBody(llvm::PointerType::getUnqual(ClassnfABITy),
5354 llvm::PointerType::getUnqual(ClassnfABITy),
5356 llvm::PointerType::getUnqual(ImpnfABITy),
5357 llvm::PointerType::getUnqual(ClassRonfABITy),
5360 // LLVM for struct _class_t *
5361 ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy);
5363 // struct _category_t {
5364 // const char * const name;
5365 // struct _class_t *const cls;
5366 // const struct _method_list_t * const instance_methods;
5367 // const struct _method_list_t * const class_methods;
5368 // const struct _protocol_list_t * const protocols;
5369 // const struct _prop_list_t * const properties;
5371 CategorynfABITy = llvm::StructType::create("struct._category_t
",
5372 Int8PtrTy, ClassnfABIPtrTy,
5373 MethodListnfABIPtrTy,
5374 MethodListnfABIPtrTy,
5375 ProtocolListnfABIPtrTy,
5379 // New types for nonfragile abi messaging.
5380 CodeGen::CodeGenTypes &Types = CGM.getTypes();
5381 ASTContext &Ctx = CGM.getContext();
5383 // MessageRefTy - LLVM for:
5384 // struct _message_ref_t {
5389 // First the clang type for struct _message_ref_t
5390 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
5391 Ctx.getTranslationUnitDecl(),
5392 SourceLocation(), SourceLocation(),
5393 &Ctx.Idents.get("_message_ref_t
"));
5394 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5395 nullptr, Ctx.VoidPtrTy, nullptr, nullptr, false,
5397 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5398 nullptr, Ctx.getObjCSelType(), nullptr, nullptr,
5399 false, ICIS_NoInit));
5400 RD->completeDefinition();
5402 MessageRefCTy = Ctx.getTagDeclType(RD);
5403 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy);
5404 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy));
5406 // MessageRefPtrTy - LLVM for struct _message_ref_t*
5407 MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy);
5409 // SuperMessageRefTy - LLVM for:
5410 // struct _super_message_ref_t {
5411 // SUPER_IMP messenger;
5415 llvm::StructType::create("struct._super_message_ref_t
",
5416 ImpnfABITy, SelectorPtrTy, nullptr);
5418 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
5419 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy);
5422 // struct objc_typeinfo {
5423 // const void** vtable; // objc_ehtype_vtable + 2
5424 // const char* name; // c++ typeinfo string
5428 llvm::StructType::create("struct._objc_typeinfo
",
5429 llvm::PointerType::getUnqual(Int8PtrTy),
5430 Int8PtrTy, ClassnfABIPtrTy, nullptr);
5431 EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy);
5434 llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
5435 FinishNonFragileABIModule();
5440 void CGObjCNonFragileABIMac::
5441 AddModuleClassList(ArrayRef<llvm::GlobalValue*> Container,
5442 const char *SymbolName,
5443 const char *SectionName) {
5444 unsigned NumClasses = Container.size();
5449 SmallVector<llvm::Constant*, 8> Symbols(NumClasses);
5450 for (unsigned i=0; i<NumClasses; i++)
5451 Symbols[i] = llvm::ConstantExpr::getBitCast(Container[i],
5452 ObjCTypes.Int8PtrTy);
5453 llvm::Constant *Init =
5454 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
5458 llvm::GlobalVariable *GV =
5459 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
5460 llvm::GlobalValue::PrivateLinkage,
5463 GV->setAlignment(CGM.getDataLayout().getABITypeAlignment(Init->getType()));
5464 GV->setSection(SectionName);
5465 CGM.addCompilerUsedGlobal(GV);
5468 void CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
5469 // nonfragile abi has no module definition.
5471 // Build list of all implemented class addresses in array
5472 // L_OBJC_LABEL_CLASS_$.
5474 for (unsigned i=0, NumClasses=ImplementedClasses.size(); i<NumClasses; i++) {
5475 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
5477 if (ObjCImplementationDecl *IMP = ID->getImplementation())
5478 // We are implementing a weak imported interface. Give it external linkage
5479 if (ID->isWeakImported() && !IMP->isWeakImported()) {
5480 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
5481 DefinedMetaClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
5485 AddModuleClassList(DefinedClasses, "OBJC_LABEL_CLASS_$
",
5486 "__DATA, __objc_classlist, regular, no_dead_strip
");
5488 AddModuleClassList(DefinedNonLazyClasses, "OBJC_LABEL_NONLAZY_CLASS_$
",
5489 "__DATA, __objc_nlclslist, regular, no_dead_strip
");
5491 // Build list of all implemented category addresses in array
5492 // L_OBJC_LABEL_CATEGORY_$.
5493 AddModuleClassList(DefinedCategories, "OBJC_LABEL_CATEGORY_$
",
5494 "__DATA, __objc_catlist, regular, no_dead_strip
");
5495 AddModuleClassList(DefinedNonLazyCategories, "OBJC_LABEL_NONLAZY_CATEGORY_$
",
5496 "__DATA, __objc_nlcatlist, regular, no_dead_strip
");
5505 bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
5506 // At various points we've experimented with using vtable-based
5507 // dispatch for all methods.
5508 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
5509 case CodeGenOptions::Legacy:
5511 case CodeGenOptions::NonLegacy:
5513 case CodeGenOptions::Mixed:
5517 // If so, see whether this selector is in the white-list of things which must
5518 // use the new dispatch convention. We lazily build a dense set for this.
5519 if (VTableDispatchMethods.empty()) {
5520 VTableDispatchMethods.insert(GetNullarySelector("alloc
"));
5521 VTableDispatchMethods.insert(GetNullarySelector("class"));
5522 VTableDispatchMethods.insert(GetNullarySelector("self"));
5523 VTableDispatchMethods.insert(GetNullarySelector("isFlipped
"));
5524 VTableDispatchMethods.insert(GetNullarySelector("length
"));
5525 VTableDispatchMethods.insert(GetNullarySelector("count
"));
5527 // These are vtable-based if GC is disabled.
5528 // Optimistically use vtable dispatch for hybrid compiles.
5529 if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) {
5530 VTableDispatchMethods.insert(GetNullarySelector("retain
"));
5531 VTableDispatchMethods.insert(GetNullarySelector("release
"));
5532 VTableDispatchMethods.insert(GetNullarySelector("autorelease
"));
5535 VTableDispatchMethods.insert(GetUnarySelector("allocWithZone
"));
5536 VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass
"));
5537 VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector
"));
5538 VTableDispatchMethods.insert(GetUnarySelector("objectForKey
"));
5539 VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex
"));
5540 VTableDispatchMethods.insert(GetUnarySelector("isEqualToString
"));
5541 VTableDispatchMethods.insert(GetUnarySelector("isEqual
"));
5543 // These are vtable-based if GC is enabled.
5544 // Optimistically use vtable dispatch for hybrid compiles.
5545 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
5546 VTableDispatchMethods.insert(GetNullarySelector("hash
"));
5547 VTableDispatchMethods.insert(GetUnarySelector("addObject
"));
5549 // "countByEnumeratingWithState:objects:count
"
5550 IdentifierInfo *KeyIdents[] = {
5551 &CGM.getContext().Idents.get("countByEnumeratingWithState
"),
5552 &CGM.getContext().Idents.get("objects
"),
5553 &CGM.getContext().Idents.get("count
")
5555 VTableDispatchMethods.insert(
5556 CGM.getContext().Selectors.getSelector(3, KeyIdents));
5560 return VTableDispatchMethods.count(Sel);
5578 llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
5580 unsigned InstanceStart,
5581 unsigned InstanceSize,
5582 const ObjCImplementationDecl *ID) {
5583 std::string ClassName = ID->getObjCRuntimeNameAsString();
5584 llvm::Constant *Values[10]; // 11 for 64bit targets!
5586 if (CGM.getLangOpts().ObjCAutoRefCount)
5587 flags |= NonFragileABI_Class_CompiledByARC;
5589 Values[ 0] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags);
5590 Values[ 1] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceStart);
5591 Values[ 2] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceSize);
5592 // FIXME. For 64bit targets add 0 here.
5593 Values[ 3] = (flags & NonFragileABI_Class_Meta)
5594 ? GetIvarLayoutName(nullptr, ObjCTypes)
5595 : BuildIvarLayout(ID, true);
5596 Values[ 4] = GetClassName(ID->getObjCRuntimeNameAsString());
5597 // const struct _method_list_t * const baseMethods;
5598 std::vector<llvm::Constant*> Methods;
5599 std::string MethodListName("\01l_OBJC_$_
");
5600 if (flags & NonFragileABI_Class_Meta) {
5601 MethodListName += "CLASS_METHODS_
";
5602 MethodListName += ID->getObjCRuntimeNameAsString();
5603 for (const auto *I : ID->class_methods())
5604 // Class methods should always be defined.
5605 Methods.push_back(GetMethodConstant(I));
5607 MethodListName += "INSTANCE_METHODS_
";
5608 MethodListName += ID->getObjCRuntimeNameAsString();
5609 for (const auto *I : ID->instance_methods())
5610 // Instance methods should always be defined.
5611 Methods.push_back(GetMethodConstant(I));
5613 for (const auto *PID : ID->property_impls()) {
5614 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){
5615 ObjCPropertyDecl *PD = PID->getPropertyDecl();
5617 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
5618 if (llvm::Constant *C = GetMethodConstant(MD))
5619 Methods.push_back(C);
5620 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
5621 if (llvm::Constant *C = GetMethodConstant(MD))
5622 Methods.push_back(C);
5626 Values[ 5] = EmitMethodList(MethodListName,
5627 "__DATA, __objc_const
", Methods);
5629 const ObjCInterfaceDecl *OID = ID->getClassInterface();
5630 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer
");
5631 Values[ 6] = EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_
"
5632 + OID->getObjCRuntimeNameAsString(),
5633 OID->all_referenced_protocol_begin(),
5634 OID->all_referenced_protocol_end());
5636 if (flags & NonFragileABI_Class_Meta) {
5637 Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
5638 Values[ 8] = GetIvarLayoutName(nullptr, ObjCTypes);
5639 Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
5641 Values[ 7] = EmitIvarList(ID);
5642 Values[ 8] = BuildIvarLayout(ID, false);
5643 Values[ 9] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_
" + ID->getObjCRuntimeNameAsString(),
5644 ID, ID->getClassInterface(), ObjCTypes);
5646 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy,
5648 llvm::GlobalVariable *CLASS_RO_GV =
5649 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassRonfABITy, false,
5650 llvm::GlobalValue::PrivateLinkage,
5652 (flags & NonFragileABI_Class_Meta) ?
5653 std::string("\01l_OBJC_METACLASS_RO_$_
")+ClassName :
5654 std::string("\01l_OBJC_CLASS_RO_$_
")+ClassName);
5655 CLASS_RO_GV->setAlignment(
5656 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassRonfABITy));
5657 CLASS_RO_GV->setSection("__DATA, __objc_const
");
5672 llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassMetaData(
5673 const std::string &ClassName, llvm::Constant *IsAGV, llvm::Constant *SuperClassGV,
5674 llvm::Constant *ClassRoGV, bool HiddenVisibility, bool Weak) {
5675 llvm::Constant *Values[] = {
5678 ObjCEmptyCacheVar, // &ObjCEmptyCacheVar
5679 ObjCEmptyVtableVar, // &ObjCEmptyVtableVar
5680 ClassRoGV // &CLASS_RO_GV
5683 Values[1] = llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy);
5685 Values[3] = llvm::Constant::getNullValue(
5686 llvm::PointerType::getUnqual(ObjCTypes.ImpnfABITy));
5687 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy,
5689 llvm::GlobalVariable *GV = GetClassGlobal(ClassName, Weak);
5690 GV->setInitializer(Init);
5691 GV->setSection("__DATA, __objc_data
");
5693 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassnfABITy));
5694 if (HiddenVisibility)
5695 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
5700 CGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
5701 return OD->getClassMethod(GetNullarySelector("load
")) != nullptr;
5704 void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
5705 uint32_t &InstanceStart,
5706 uint32_t &InstanceSize) {
5707 const ASTRecordLayout &RL =
5708 CGM.getContext().getASTObjCImplementationLayout(OID);
5710 // InstanceSize is really instance end.
5711 InstanceSize = RL.getDataSize().getQuantity();
5713 // If there are no fields, the start is the same as the end.
5714 if (!RL.getFieldCount())
5715 InstanceStart = InstanceSize;
5717 InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth();
5720 void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
5721 std::string ClassName = ID->getObjCRuntimeNameAsString();
5722 if (!ObjCEmptyCacheVar) {
5723 ObjCEmptyCacheVar = new llvm::GlobalVariable(
5727 llvm::GlobalValue::ExternalLinkage,
5729 "_objc_empty_cache
");
5731 // Make this entry NULL for any iOS device target, any iOS simulator target,
5732 // OS X with deployment target 10.9 or later.
5733 const llvm::Triple &Triple = CGM.getTarget().getTriple();
5734 if (Triple.isiOS() || (Triple.isMacOSX() && !Triple.isMacOSXVersionLT(10, 9)))
5735 // This entry will be null.
5736 ObjCEmptyVtableVar = nullptr;
5738 ObjCEmptyVtableVar = new llvm::GlobalVariable(
5740 ObjCTypes.ImpnfABITy,
5742 llvm::GlobalValue::ExternalLinkage,
5744 "_objc_empty_vtable
");
5746 assert(ID->getClassInterface() &&
5747 "CGObjCNonFragileABIMac::GenerateClass -
class is 0");
5749 uint32_t InstanceStart =
5750 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy);
5751 uint32_t InstanceSize = InstanceStart;
5757 llvm::GlobalVariable *SuperClassGV, *IsAGV;
5760 bool classIsHidden =
5776 TClassName = ObjCClassName;
5777 TClassName += ClassName;
5778 SuperClassGV = GetClassGlobal(TClassName.str(),
5780 TClassName = ObjCMetaClassName;
5781 TClassName += ClassName;
5782 IsAGV = GetClassGlobal(TClassName.str(),
5789 TClassName = ObjCMetaClassName ;
5791 IsAGV = GetClassGlobal(TClassName.str(),
5795 TClassName = ObjCMetaClassName;
5797 SuperClassGV = GetClassGlobal(
5801 llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags,
5804 TClassName = ObjCMetaClassName;
5805 TClassName += ClassName;
5806 llvm::GlobalVariable *MetaTClass = BuildClassMetaData(
5807 TClassName.str(), IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden,
5809 DefinedMetaClasses.push_back(MetaTClass);
5834 SuperClassGV =
nullptr;
5837 TClassName = ObjCClassName;
5839 SuperClassGV = GetClassGlobal(
5843 GetClassSizeInfo(ID, InstanceStart, InstanceSize);
5844 CLASS_RO_GV = BuildClassRoTInitializer(flags,
5849 TClassName = ObjCClassName;
5850 TClassName += ClassName;
5851 llvm::GlobalVariable *ClassMD =
5852 BuildClassMetaData(TClassName.str(), MetaTClass, SuperClassGV, CLASS_RO_GV,
5855 DefinedClasses.push_back(ClassMD);
5859 if (ImplementationIsNonLazy(ID))
5860 DefinedNonLazyClasses.push_back(ClassMD);
5866 MethodDefinitions.clear();
5883 llvm::Constant *Init =
5884 llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD),
5885 ObjCTypes.getExternalProtocolPtrTy());
5887 std::string ProtocolName(
"\01l_OBJC_PROTOCOL_REFERENCE_$_");
5890 llvm::GlobalVariable *PTGV = CGM.
getModule().getGlobalVariable(ProtocolName);
5892 return CGF.
Builder.CreateLoad(PTGV);
5893 PTGV =
new llvm::GlobalVariable(
5895 Init->getType(),
false,
5896 llvm::GlobalValue::WeakAnyLinkage,
5899 PTGV->setSection(
"__DATA, __objc_protorefs, coalesced, no_dead_strip");
5902 return CGF.
Builder.CreateLoad(PTGV);
5917 const char *Prefix =
"\01l_OBJC_$_CATEGORY_";
5921 ExtCatName +=
"_$_";
5927 llvm::Constant *Values[6];
5930 llvm::GlobalVariable *ClassGV =
5933 Values[1] = ClassGV;
5934 std::vector<llvm::Constant*> Methods;
5937 MethodListName +=
"INSTANCE_METHODS_";
5939 MethodListName +=
"_$_";
5940 MethodListName += OCD->
getName();
5944 Methods.push_back(GetMethodConstant(I));
5946 Values[2] = EmitMethodList(MethodListName.str(),
5947 "__DATA, __objc_const",
5950 MethodListName = Prefix;
5951 MethodListName +=
"CLASS_METHODS_";
5953 MethodListName +=
"_$_";
5959 Methods.push_back(GetMethodConstant(I));
5961 Values[3] = EmitMethodList(MethodListName.str(),
5962 "__DATA, __objc_const",
5970 Values[4] = EmitProtocolList(
"\01l_OBJC_CATEGORY_PROTOCOLS_$_"
5972 + Category->getName(),
5973 Category->protocol_begin(),
5974 Category->protocol_end());
5975 Values[5] = EmitPropertyList(
"\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
5976 OCD, Category, ObjCTypes);
5978 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
5979 Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
5982 llvm::Constant *Init =
5983 llvm::ConstantStruct::get(ObjCTypes.CategorynfABITy,
5985 llvm::GlobalVariable *GCATV
5986 =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.CategorynfABITy,
5988 llvm::GlobalValue::PrivateLinkage,
5991 GCATV->setAlignment(
5992 CGM.
getDataLayout().getABITypeAlignment(ObjCTypes.CategorynfABITy));
5993 GCATV->setSection(
"__DATA, __objc_const");
5995 DefinedCategories.push_back(GCATV);
5998 if (ImplementationIsNonLazy(OCD))
5999 DefinedNonLazyCategories.push_back(GCATV);
6001 MethodDefinitions.clear();
6007 llvm::Constant *CGObjCNonFragileABIMac::GetMethodConstant(
6009 llvm::Function *Fn = GetMethodDefinition(MD);
6013 llvm::Constant *Method[] = {
6014 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->
getSelector()),
6015 ObjCTypes.SelectorPtrTy),
6016 GetMethodVarType(MD),
6017 llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy)
6019 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
6030 CGObjCNonFragileABIMac::EmitMethodList(Twine Name,
6031 const char *Section,
6034 if (Methods.empty())
6035 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
6037 llvm::Constant *Values[3];
6039 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.MethodTy);
6040 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6042 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
6043 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
6045 Values[2] = llvm::ConstantArray::get(AT, Methods);
6046 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
6048 llvm::GlobalVariable *GV =
6049 new llvm::GlobalVariable(CGM.
getModule(), Init->getType(),
false,
6050 llvm::GlobalValue::PrivateLinkage, Init, Name);
6051 GV->setAlignment(CGM.
getDataLayout().getABITypeAlignment(Init->getType()));
6052 GV->setSection(Section);
6054 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListnfABIPtrTy);
6059 llvm::GlobalVariable *
6068 llvm::GlobalVariable *IvarOffsetGV =
6069 CGM.
getModule().getGlobalVariable(Name);
6071 IvarOffsetGV =
new llvm::GlobalVariable(
6072 CGM.
getModule(), ObjCTypes.IvarOffsetVarTy,
false,
6074 return IvarOffsetGV;
6080 unsigned long int Offset) {
6081 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
6082 IvarOffsetGV->setInitializer(
6083 llvm::ConstantInt::get(ObjCTypes.IvarOffsetVarTy, Offset));
6084 IvarOffsetGV->setAlignment(
6085 CGM.
getDataLayout().getABITypeAlignment(ObjCTypes.IvarOffsetVarTy));
6095 IvarOffsetGV->setSection(
"__DATA, __objc_ivar");
6096 return IvarOffsetGV;
6116 llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
6119 std::vector<llvm::Constant*> Ivars;
6122 assert(OID &&
"CGObjCNonFragileABIMac::EmitIvarList - null interface");
6129 if (!IVD->getDeclName())
6131 llvm::Constant *Ivar[5];
6133 ComputeIvarBaseOffset(CGM, ID, IVD));
6134 Ivar[1] = GetMethodVarName(IVD->getIdentifier());
6135 Ivar[2] = GetMethodVarType(IVD);
6136 llvm::Type *FieldTy =
6138 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(FieldTy);
6140 IVD->getType().getTypePtr()) >> 3;
6141 Align = llvm::Log2_32(Align);
6142 Ivar[3] = llvm::ConstantInt::get(ObjCTypes.IntTy, Align);
6148 Ivar[4] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6149 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarnfABITy, Ivar));
6153 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
6155 llvm::Constant *Values[3];
6156 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.IvarnfABITy);
6157 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6158 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
6159 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarnfABITy,
6161 Values[2] = llvm::ConstantArray::get(AT, Ivars);
6162 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
6163 const char *Prefix =
"\01l_OBJC_$_INSTANCE_VARIABLES_";
6164 llvm::GlobalVariable *GV =
6165 new llvm::GlobalVariable(CGM.
getModule(), Init->getType(),
false,
6166 llvm::GlobalValue::PrivateLinkage,
6171 GV->setSection(
"__DATA, __objc_const");
6174 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy);
6177 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(
6179 llvm::GlobalVariable *&Entry = Protocols[PD->
getIdentifier()];
6186 new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolnfABITy,
6190 Entry->setSection(
"__DATA,__datacoal_nt,coalesced");
6215 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
6217 llvm::GlobalVariable *Entry = Protocols[PD->
getIdentifier()];
6220 if (Entry && Entry->hasInitializer())
6228 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
6229 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
6230 std::vector<llvm::Constant*> MethodTypesExt, OptMethodTypesExt;
6232 llvm::Constant *C = GetMethodDescriptionConstant(MD);
6234 return GetOrEmitProtocolRef(PD);
6237 OptInstanceMethods.push_back(C);
6238 OptMethodTypesExt.push_back(GetMethodVarType(MD,
true));
6240 InstanceMethods.push_back(C);
6241 MethodTypesExt.push_back(GetMethodVarType(MD,
true));
6246 llvm::Constant *C = GetMethodDescriptionConstant(MD);
6248 return GetOrEmitProtocolRef(PD);
6251 OptClassMethods.push_back(C);
6252 OptMethodTypesExt.push_back(GetMethodVarType(MD,
true));
6254 ClassMethods.push_back(C);
6255 MethodTypesExt.push_back(GetMethodVarType(MD,
true));
6259 MethodTypesExt.insert(MethodTypesExt.end(),
6260 OptMethodTypesExt.begin(), OptMethodTypesExt.end());
6262 llvm::Constant *Values[12];
6264 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy);
6270 Values[3] = EmitMethodList(
"\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_"
6272 "__DATA, __objc_const",
6274 Values[4] = EmitMethodList(
"\01l_OBJC_$_PROTOCOL_CLASS_METHODS_"
6276 "__DATA, __objc_const",
6278 Values[5] = EmitMethodList(
"\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_"
6280 "__DATA, __objc_const",
6281 OptInstanceMethods);
6282 Values[6] = EmitMethodList(
"\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_"
6284 "__DATA, __objc_const",
6287 nullptr, PD, ObjCTypes);
6289 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
6290 Values[8] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6291 Values[9] = llvm::Constant::getNullValue(ObjCTypes.IntTy);
6292 Values[10] = EmitProtocolMethodTypes(
"\01l_OBJC_$_PROTOCOL_METHOD_TYPES_"
6294 MethodTypesExt, ObjCTypes);
6296 Values[11] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
6298 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolnfABITy,
6303 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
6304 Entry->setInitializer(Init);
6307 new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolnfABITy,
6308 false, llvm::GlobalValue::WeakAnyLinkage, Init,
6310 Entry->setAlignment(
6311 CGM.
getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABITy));
6312 Entry->setSection(
"__DATA,__datacoal_nt,coalesced");
6321 llvm::GlobalVariable *PTGV =
6322 new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolnfABIPtrTy,
6323 false, llvm::GlobalValue::WeakAnyLinkage, Entry,
6326 CGM.
getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy));
6327 PTGV->setSection(
"__DATA, __objc_protolist, coalesced, no_dead_strip");
6342 CGObjCNonFragileABIMac::EmitProtocolList(Twine Name,
6349 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
6353 Name.toVector(TmpName);
6354 llvm::GlobalVariable *GV =
6355 CGM.
getModule().getGlobalVariable(TmpName.str(),
true);
6357 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy);
6359 for (; begin != end; ++begin)
6360 ProtocolRefs.push_back(GetProtocolRef(*begin));
6363 ProtocolRefs.push_back(llvm::Constant::getNullValue(
6364 ObjCTypes.ProtocolnfABIPtrTy));
6366 llvm::Constant *Values[2];
6368 llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
6370 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolnfABIPtrTy,
6371 ProtocolRefs.size()),
6374 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
6375 GV =
new llvm::GlobalVariable(CGM.
getModule(), Init->getType(),
false,
6376 llvm::GlobalValue::PrivateLinkage,
6378 GV->setSection(
"__DATA, __objc_const");
6382 return llvm::ConstantExpr::getBitCast(GV,
6383 ObjCTypes.ProtocolListnfABIPtrTy);
6394 CGObjCNonFragileABIMac::GetMethodDescriptionConstant(
const ObjCMethodDecl *MD) {
6395 llvm::Constant *Desc[3];
6397 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->
getSelector()),
6398 ObjCTypes.SelectorPtrTy);
6399 Desc[1] = GetMethodVarType(MD);
6404 Desc[2] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
6405 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Desc);
6414 LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
6419 unsigned CVRQualifiers) {
6421 llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
6422 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
6426 llvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset(
6430 llvm::Value *IvarOffsetValue = ObjCIvarOffsetVariable(Interface, Ivar);
6431 IvarOffsetValue = CGF.
Builder.CreateLoad(IvarOffsetValue,
"ivar");
6432 if (IsIvarOffsetKnownIdempotent(CGF, Ivar))
6433 cast<llvm::LoadInst>(IvarOffsetValue)
6434 ->setMetadata(CGM.
getModule().getMDKindID(
"invariant.load"),
6435 llvm::MDNode::get(VMContext, None));
6440 if (ObjCTypes.IvarOffsetVarTy == ObjCTypes.IntTy)
6441 IvarOffsetValue = CGF.
Builder.CreateIntCast(
6442 IvarOffsetValue, ObjCTypes.LongTy,
true,
"ivar.conv");
6443 return IvarOffsetValue;
6446 static void appendSelectorForMessageRefTable(std::string &buffer,
6453 for (
unsigned i = 0, e = selector.
getNumArgs(); i != e; ++i) {
6484 arg0 = CGF.
Builder.CreateBitCast(arg0, ObjCTypes.ObjectPtrTy);
6485 args.
add(RValue::get(arg0), arg0Type);
6489 args.
add(RValue::get(
nullptr), ObjCTypes.MessageRefCPtrTy);
6491 args.insert(args.end(), formalArgs.begin(), formalArgs.end());
6493 MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);
6495 NullReturnState nullReturn;
6504 llvm::Constant *fn =
nullptr;
6505 std::string messageRefName(
"\01l_");
6508 fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
6509 messageRefName +=
"objc_msgSendSuper2_stret_fixup";
6511 nullReturn.init(CGF, arg0);
6512 fn = ObjCTypes.getMessageSendStretFixupFn();
6513 messageRefName +=
"objc_msgSend_stret_fixup";
6516 fn = ObjCTypes.getMessageSendFpretFixupFn();
6517 messageRefName +=
"objc_msgSend_fpret_fixup";
6520 fn = ObjCTypes.getMessageSendSuper2FixupFn();
6521 messageRefName +=
"objc_msgSendSuper2_fixup";
6523 fn = ObjCTypes.getMessageSendFixupFn();
6524 messageRefName +=
"objc_msgSend_fixup";
6527 assert(fn &&
"CGObjCNonFragileABIMac::EmitMessageSend");
6528 messageRefName +=
'_';
6532 appendSelectorForMessageRefTable(messageRefName, selector);
6534 llvm::GlobalVariable *messageRef
6535 = CGM.
getModule().getGlobalVariable(messageRefName);
6538 llvm::Constant *values[] = { fn, GetMethodVarName(selector) };
6539 llvm::Constant *init = llvm::ConstantStruct::getAnon(values);
6540 messageRef =
new llvm::GlobalVariable(CGM.
getModule(),
6543 llvm::GlobalValue::WeakAnyLinkage,
6547 messageRef->setAlignment(16);
6548 messageRef->setSection(
"__DATA, __objc_msgrefs, coalesced");
6551 bool requiresnullCheck =
false;
6553 for (
const auto *ParamDecl : method->
params()) {
6554 if (ParamDecl->
hasAttr<NSConsumedAttr>()) {
6555 if (!nullReturn.NullBB)
6556 nullReturn.init(CGF, arg0);
6557 requiresnullCheck =
true;
6563 CGF.
Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy);
6566 args[1].RV = RValue::get(mref);
6570 CGF.
Builder.CreateStructGEP(ObjCTypes.MessageRefTy, mref, 0);
6571 callee = CGF.
Builder.CreateLoad(callee,
"msgSend_fn");
6573 callee = CGF.
Builder.CreateBitCast(callee, MSI.MessengerType);
6575 RValue result = CGF.
EmitCall(MSI.CallInfo, callee, returnSlot, args);
6576 return nullReturn.complete(CGF, result, resultType, formalArgs,
6577 requiresnullCheck ? method :
nullptr);
6590 return isVTableDispatchedSelector(Sel)
6591 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
6593 false, CallArgs, Method)
6594 : EmitMessageSend(CGF, Return, ResultType,
6595 EmitSelector(CGF, Sel),
6597 false, CallArgs, Method, ObjCTypes);
6600 llvm::GlobalVariable *
6601 CGObjCNonFragileABIMac::GetClassGlobal(
const std::string &Name,
bool Weak) {
6602 llvm::GlobalValue::LinkageTypes L =
6603 Weak ? llvm::GlobalValue::ExternalWeakLinkage
6606 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name);
6609 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassnfABITy,
6610 false, L,
nullptr, Name);
6612 assert(GV->getLinkage() == L);
6620 llvm::GlobalVariable *&Entry = ClassReferences[II];
6623 std::string ClassName(
6624 getClassSymbolPrefix() +
6626 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName, Weak);
6627 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassnfABIPtrTy,
6628 false, llvm::GlobalValue::PrivateLinkage,
6629 ClassGV,
"OBJC_CLASSLIST_REFERENCES_$_");
6630 Entry->setAlignment(
6632 ObjCTypes.ClassnfABIPtrTy));
6633 Entry->setSection(
"__DATA, __objc_classrefs, regular, no_dead_strip");
6636 return CGF.
Builder.CreateLoad(Entry);
6644 llvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(
6647 return EmitClassRefFromId(CGF, II,
false, 0);
6653 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->
getIdentifier()];
6658 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName.str(),
6660 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassnfABIPtrTy,
6661 false, llvm::GlobalValue::PrivateLinkage,
6662 ClassGV,
"OBJC_CLASSLIST_SUP_REFS_$_");
6663 Entry->setAlignment(
6665 ObjCTypes.ClassnfABIPtrTy));
6666 Entry->setSection(
"__DATA, __objc_superrefs, regular, no_dead_strip");
6669 return CGF.
Builder.CreateLoad(Entry);
6678 llvm::GlobalVariable * &Entry = MetaClassReferences[ID->
getIdentifier()];
6682 llvm::GlobalVariable *MetaClassGV =
6683 GetClassGlobal(MetaClassName.str(), Weak);
6685 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassnfABIPtrTy,
6686 false, llvm::GlobalValue::PrivateLinkage,
6687 MetaClassGV,
"OBJC_CLASSLIST_SUP_REFS_$_");
6688 Entry->setAlignment(
6689 CGM.
getDataLayout().getABITypeAlignment(ObjCTypes.ClassnfABIPtrTy));
6691 Entry->setSection(
"__DATA, __objc_superrefs, regular, no_dead_strip");
6695 return CGF.
Builder.CreateLoad(Entry);
6705 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName.str(),
true);
6707 assert(ClassGV->hasExternalWeakLinkage());
6710 return EmitClassRef(CGF, ID);
6722 bool isCategoryImpl,
6724 bool IsClassMessage,
6734 CGF.
Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
6737 CGF.
Builder.CreateStructGEP(ObjCTypes.SuperTy, ObjCSuper, 0));
6744 Target = EmitSuperClassRef(CGF, Class);
6748 llvm::Type *ClassTy =
6750 Target = CGF.
Builder.CreateBitCast(Target, ClassTy);
6752 Target, CGF.
Builder.CreateStructGEP(ObjCTypes.SuperTy, ObjCSuper, 1));
6754 return (isVTableDispatchedSelector(Sel))
6755 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
6756 ObjCSuper, ObjCTypes.SuperPtrCTy,
6757 true, CallArgs, Method)
6758 : EmitMessageSend(CGF, Return, ResultType,
6759 EmitSelector(CGF, Sel),
6760 ObjCSuper, ObjCTypes.SuperPtrCTy,
6761 true, CallArgs, Method, ObjCTypes);
6766 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
6769 llvm::Constant *Casted =
6770 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
6771 ObjCTypes.SelectorPtrTy);
6772 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.SelectorPtrTy,
6773 false, llvm::GlobalValue::PrivateLinkage,
6774 Casted,
"OBJC_SELECTOR_REFERENCES_");
6775 Entry->setExternallyInitialized(
true);
6776 Entry->setSection(
"__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
6782 llvm::LoadInst* LI = CGF.
Builder.CreateLoad(Entry);
6784 LI->setMetadata(CGM.
getModule().getMDKindID(
"invariant.load"),
6785 llvm::MDNode::get(VMContext, None));
6795 llvm::Type * SrcTy = src->getType();
6796 if (!isa<llvm::PointerType>(SrcTy)) {
6797 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(SrcTy);
6798 assert(Size <= 8 && "does not support size > 8
");
6799 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
6800 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
6801 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
6803 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
6804 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
6805 llvm::Value *args[] = { src, dst, ivarOffset };
6806 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
6812 void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
6813 CodeGen::CodeGenFunction &CGF,
6814 llvm::Value *src, llvm::Value *dst) {
6815 llvm::Type * SrcTy = src->getType();
6816 if (!isa<llvm::PointerType>(SrcTy)) {
6817 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
6818 assert(Size <= 8 && "does
not support size > 8
");
6819 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
6820 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
6821 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
6823 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
6824 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
6825 llvm::Value *args[] = { src, dst };
6826 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(),
6827 args, "weakassign
");
6830 void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
6831 CodeGen::CodeGenFunction &CGF,
6832 llvm::Value *DestPtr,
6833 llvm::Value *SrcPtr,
6834 llvm::Value *Size) {
6835 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
6836 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
6837 llvm::Value *args[] = { DestPtr, SrcPtr, Size };
6838 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
6844 llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(
6845 CodeGen::CodeGenFunction &CGF,
6846 llvm::Value *AddrWeakObj) {
6847 llvm::Type* DestTy =
6848 cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType();
6849 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy);
6850 llvm::Value *read_weak =
6851 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(),
6852 AddrWeakObj, "weakread
");
6853 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
6860 void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
6861 llvm::Value *src, llvm::Value *dst) {
6862 llvm::Type * SrcTy = src->getType();
6863 if (!isa<llvm::PointerType>(SrcTy)) {
6864 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
6865 assert(Size <= 8 && "does
not support size > 8
");
6866 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
6867 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
6868 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
6870 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
6871 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
6872 llvm::Value *args[] = { src, dst };
6873 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(),
6874 args, "weakassign
");
6880 void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
6881 llvm::Value *src, llvm::Value *dst,
6883 llvm::Type * SrcTy = src->getType();
6884 if (!isa<llvm::PointerType>(SrcTy)) {
6885 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
6886 assert(Size <= 8 && "does
not support size > 8
");
6887 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
6888 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
6889 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
6891 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
6892 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
6893 llvm::Value *args[] = { src, dst };
6895 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(),
6896 args, "globalassign
");
6898 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(),
6899 args, "threadlocalassign
");
6903 CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
6904 const ObjCAtSynchronizedStmt &S) {
6905 EmitAtSynchronizedStmt(CGF, S,
6906 cast<llvm::Function>(ObjCTypes.getSyncEnterFn()),
6907 cast<llvm::Function>(ObjCTypes.getSyncExitFn()));
6911 CGObjCNonFragileABIMac::GetEHType(QualType T) {
6912 // There's a particular fixed type info for 'id'.
6913 if (T->isObjCIdType() ||
6914 T->isObjCQualifiedIdType()) {
6915 llvm::Constant *IDEHType =
6916 CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id
");
6919 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy,
6921 llvm::GlobalValue::ExternalLinkage,
6922 nullptr, "OBJC_EHTYPE_id
");
6926 // All other types should be Objective-C interface pointer types.
6927 const ObjCObjectPointerType *PT =
6928 T->getAs<ObjCObjectPointerType>();
6929 assert(PT && "Invalid
@catch type.
");
6930 const ObjCInterfaceType *IT = PT->getInterfaceType();
6931 assert(IT && "Invalid
@catch type.
");
6932 return GetInterfaceEHType(IT->getDecl(), false);
6935 void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
6936 const ObjCAtTryStmt &S) {
6937 EmitTryCatchStmt(CGF, S,
6938 cast<llvm::Function>(ObjCTypes.getObjCBeginCatchFn()),
6939 cast<llvm::Function>(ObjCTypes.getObjCEndCatchFn()),
6940 cast<llvm::Function>(ObjCTypes.getExceptionRethrowFn()));
6944 void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
6945 const ObjCAtThrowStmt &S,
6946 bool ClearInsertionPoint) {
6947 if (const Expr *ThrowExpr = S.getThrowExpr()) {
6948 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
6949 Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
6950 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception)
6951 .setDoesNotReturn();
6953 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionRethrowFn())
6954 .setDoesNotReturn();
6957 CGF.Builder.CreateUnreachable();
6958 if (ClearInsertionPoint)
6959 CGF.Builder.ClearInsertionPoint();
6963 CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
6964 bool ForDefinition) {
6965 llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
6967 // If we don't need a definition, return the entry if found or check
6968 // if we use an external reference.
6969 if (!ForDefinition) {
6973 // If this type (or a super class) has the __objc_exception__
6974 // attribute, emit an external reference.
6975 if (hasObjCExceptionAttribute(CGM.getContext(), ID))
6977 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
6978 llvm::GlobalValue::ExternalLinkage,
6981 ID->getObjCRuntimeNameAsString()));
6984 // Otherwise we need to either make a new entry or fill in the
6986 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition
");
6987 llvm::SmallString<64> ClassName(getClassSymbolPrefix());
6988 ClassName += ID->getObjCRuntimeNameAsString();
6989 std::string VTableName = "objc_ehtype_vtable
";
6990 llvm::GlobalVariable *VTableGV =
6991 CGM.getModule().getGlobalVariable(VTableName);
6993 VTableGV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy,
6995 llvm::GlobalValue::ExternalLinkage,
6996 nullptr, VTableName);
6998 llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2);
7000 llvm::Constant *Values[] = {
7001 llvm::ConstantExpr::getGetElementPtr(VTableGV->getValueType(), VTableGV,
7003 GetClassName(ID->getObjCRuntimeNameAsString()),
7004 GetClassGlobal(ClassName.str())};
7005 llvm::Constant *Init =
7006 llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values);
7008 llvm::GlobalValue::LinkageTypes L = ForDefinition
7009 ? llvm::GlobalValue::ExternalLinkage
7010 : llvm::GlobalValue::WeakAnyLinkage;
7012 Entry->setInitializer(Init);
7014 llvm::SmallString<64> EHTYPEName("OBJC_EHTYPE_$_
");
7015 EHTYPEName += ID->getObjCRuntimeNameAsString();
7016 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
7021 assert(Entry->getLinkage() == L);
7023 if (ID->getVisibility() == HiddenVisibility)
7024 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
7025 Entry->setAlignment(CGM.getDataLayout().getABITypeAlignment(
7026 ObjCTypes.EHTypeTy));
7029 Entry->setSection("__DATA,__objc_const
");
7031 Entry->setSection("__DATA,__datacoal_nt,coalesced
");
7038 CodeGen::CGObjCRuntime *
7039 CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
7040 switch (CGM.getLangOpts().ObjCRuntime.getKind()) {
7041 case ObjCRuntime::FragileMacOSX:
7042 return new CGObjCMac(CGM);
7044 case ObjCRuntime::MacOSX:
7045 case ObjCRuntime::iOS:
7046 return new CGObjCNonFragileABIMac(CGM);
7048 case ObjCRuntime::GNUstep:
7049 case ObjCRuntime::GCC:
7050 case ObjCRuntime::ObjFW:
7051 llvm_unreachable("these runtimes are
not Mac runtimes
");
7053 llvm_unreachable("bad runtime
");
StringRef getObjCRuntimeNameAsString() const
param_const_iterator param_begin() const
Defines the clang::ASTContext interface.
static Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
External linkage, which indicates that the entity can be referred to from other translation units...
IdentifierInfo * getIdentifier() const
StringRef getName() const
protocol_range protocols() const
CharUnits BlockHeaderForcedGapOffset
Smart pointer class that efficiently represents Objective-C method names.
Class implementation was compiled under ARC.
const ObjCAtFinallyStmt * getFinallyStmt() const
Retrieve the @finally statement, if any.
ImplementationControl getImplementationControl() const
CodeGenTypes & getTypes()
bool isBitField() const
Determines whether this field is a bitfield.
static Selector GetUnarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing an unary selector.
llvm::Module & getModule() const
protocol_iterator protocol_end() const
IdentifierInfo * getIdentifier() const
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
Implements runtime-specific code generation functions.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
bool isRecordType() const
llvm::CallingConv::ID getRuntimeCC() const
void EmitAutoVarDecl(const VarDecl &D)
const llvm::DataLayout & getDataLayout() const
bool isObjCQualifiedClassType() const
Represents Objective-C's @throw statement.
const ObjCObjectType * getObjectType() const
static bool hasObjCExceptionAttribute(ASTContext &Context, const ObjCInterfaceDecl *OID)
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
bool isBlockPointerType() const
ObjCProtocolList::iterator protocol_iterator
const llvm::APInt & getSize() const
const ASTRecordLayout & getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const
Get or compute information about the layout of the specified Objective-C implementation.
QualType getObjCClassType() const
Represents the Objective-C Class type.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
Visibility getVisibility() const
Determines the visibility of this entity.
llvm::Value * ReturnValue
Defines the Objective-C statement AST node classes.
llvm::Type * ConvertTypeForMem(QualType T)
ParmVarDecl - Represents a parameter to a function.
static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT)
IdentifierInfo * getIdentifier() const
llvm::Value * getNormalCleanupDestSlot()
llvm::Value * EmitObjCThrowOperand(const Expr *expr)
const ObjCInterfaceDecl * getContainingInterface() const
Return the class interface that this ivar is logically contained in; this is either the interface whe...
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
llvm::IntegerType * Int64Ty
static void addIfPresent(llvm::DenseSet< llvm::Value * > &S, llvm::Value *V)
protocol_iterator protocol_begin() const
Class has non-trivial destructors, but zero-initialization is okay.
std::string getNameAsString() const
Get the name of the class associated with this interface.
llvm::CallInst * EmitRuntimeCall(llvm::Value *callee, const Twine &name="")
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
const CGFunctionInfo & arrangeLLVMFunctionInfo(CanQualType returnType, bool instanceMethod, bool chainCall, ArrayRef< CanQualType > argTypes, FunctionType::ExtInfo info, RequiredArgs args)
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Has the exception attribute.
const VarDecl * getCatchParamDecl() const
Represents Objective-C's @catch statement.
const Capture & getCapture(const VarDecl *var) const
RValue EmitCall(const CGFunctionInfo &FnInfo, llvm::Value *Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, const Decl *TargetDecl=nullptr, llvm::Instruction **callOrInvoke=nullptr)
protocol_iterator protocol_end() const
field_range fields() const
const ArrayType * getAsArrayType(QualType T) const
RecordDecl * getDecl() const
llvm::Value * getAggregateAddr() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
ObjCInterfaceDecl * getInterface() const
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep)
Creates clause with a list of variables VL and a linear step Step.
std::string getNameAsString() const
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
const Stmt * getCatchBody() const
void EmitStmt(const Stmt *S)
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
uint64_t getFieldOffset(unsigned FieldNo) const
void addCompilerUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.compiler.used metadata.
Represents an Objective-C protocol declaration.
const ObjCAtCatchStmt * getCatchStmt(unsigned I) const
Retrieve a @catch statement.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
Represents an ObjC class declaration.
propimpl_range property_impls() const
unsigned getPreferredTypeAlign(const Type *T) const
Return the "preferred" alignment of the specified type T for the current target, in bits...
const ParmVarDecl *const * param_const_iterator
CanQualType getCanonicalTypeUnqualified() const
void addFrom(const CallArgList &other)
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
Qualifiers::ObjCLifetime getObjCLifetime() const
getObjCLifetime - Returns lifetime attribute of this type.
CGBlockInfo - Information to generate a block literal.
const TargetInfo & getTarget() const
ID
Defines the set of possible language-specific address spaces.
bool isUnarySelector() const
bool hasDestructors() const
unsigned getIndex() const
Defines the clang::LangOptions interface.
StringRef getName() const
Return the actual identifier string.
StringRef getObjCRuntimeNameAsString() const
unsigned getNumArgs() const
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
bool isObjCClassType() const
StringRef getObjCRuntimeNameAsString() const
llvm::Value * GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
bool isObjCGCWeak() const
isObjCGCWeak true when Type is objc's weak.
llvm::AllocaInst * NormalCleanupDest
i32s containing the indexes of the cleanup destinations.
ASTContext & getContext() const
llvm::BasicBlock * getBlock() const
Represents Objective-C's @synchronized statement.
protocol_iterator protocol_begin() const
void add(RValue rvalue, QualType type, bool needscopy=false)
bool isObjCIdType() const
llvm::LLVMContext & getLLVMContext()
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI)
llvm::IntegerType * Int32Ty
bool isObjCQualifiedIdType() const
QualType getObjCIdType() const
Represents the Objective-CC id type.
static llvm::Constant * getConstantGEP(llvm::LLVMContext &VMContext, llvm::GlobalVariable *C, unsigned idx0, unsigned idx1)
getConstantGEP() - Help routine to construct simple GEPs.
The result type of a method or function.
llvm::IRBuilder< PreserveNames, llvm::ConstantFolder, CGBuilderInserterTy > CGBuilderTy
(Obsolete) ARC-specific: this class has a .release_ivars method
param_const_iterator param_end() const
bool HaveInsertPoint() const
bool ReturnTypeUsesFPRet(QualType ResultType)
Return true iff the given type uses 'fpret' when used as a return type.
ASTContext & getContext() const
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
void EmitARCRelease(llvm::Value *value, ARCPreciseLifetime_t precise)
CharUnits getSize() const
getSize - Get the record size in characters.
unsigned getBitWidthValue(const ASTContext &Ctx) const
StringRef getName() const
llvm::StructType * StructureType
SmallVector< llvm::Value *, 8 > ObjCEHValueStack
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
const CGFunctionInfo & arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD)
CanQualType getCanonicalParamType(QualType T) const
Return the canonical parameter type corresponding to the specific potentially non-canonical one...
void EmitNullInitialization(llvm::Value *DestPtr, QualType Ty)
all_protocol_iterator all_referenced_protocol_end() const
const ObjCInterfaceDecl * getClassInterface() const
const LangOptions & getLangOpts() const
Represents one property declaration in an Objective-C interface.
QualType getReturnType() const
bool operator<(DeclarationName LHS, DeclarationName RHS)
JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)
virtual void Emit(CodeGenFunction &CGF, Flags flags)=0
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
ObjCIvarDecl * getNextIvar()
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
instmeth_range instance_methods() const
ObjCCategoryDecl * FindCategoryDeclaration(IdentifierInfo *CategoryId) const
static const Type * getElementType(const Expr *BaseExpr)
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
prop_range properties() const
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
std::string getNameAsString() const
Get the name of the class associated with this interface.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
unsigned getCharWidth() const
QualType getObjCProtoType() const
Retrieve the type of the Objective-C Protocol class.
llvm::Constant * EmitNullConstant(QualType T)
Selector getSelector() const
ObjCMethodDecl * getGetterMethodDecl() const
bool hasNonZeroConstructors() const
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>. Pointer - pointer requires t...
ObjCMethodDecl * getSetterMethodDecl() const
bool isObjCQualifiedIdType() const
llvm::PointerType * Int8PtrTy
Represents Objective-C's @finally statement.
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
unsigned getNumCatchStmts() const
Retrieve the number of @catch statements in this try-catch-finally block.
uint64_t getPointerWidth(unsigned AddrSpace) const
Return the width of pointers on this target, for the specified address space.
bool isObjCGCStrong() const
isObjCGCStrong true when Type is objc's strong.
AccessControl getAccessControl() const
classmeth_range class_methods() const
BoundNodesTreeBuilder *const Builder
StringRef getName() const
bool isObjCObjectPointerType() const
llvm::Type * ConvertType(QualType T)
all_protocol_iterator all_referenced_protocol_begin() const
const BlockDecl * getBlockDecl() const
CharUnits BlockHeaderForcedGapSize
Has a C++ constructor and destructor.
Represents Objective-C's @try ... @catch ... @finally statement.
const Expr * getThrowExpr() const
ObjCInterfaceDecl * getSuperClass() const
static RValue get(llvm::Value *V)
QualType getElementType() const
void EmitBranchThroughCleanup(JumpDest Dest)
ObjCIvarDecl * all_declared_ivar_begin()
bool isObjCIdType() const
void PopCleanupBlock(bool FallThroughIsBranchThrough=false)
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.