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);
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;
195 if (!ExternalProtocolPtrTy) {
201 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
204 return ExternalProtocolPtrTy;
213 llvm::StructType *SuperTy;
219 llvm::StructType *PropertyTy;
223 llvm::StructType *PropertyListTy;
228 llvm::StructType *MethodTy;
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() {
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() {
442 llvm::FunctionType *FTy =
443 llvm::FunctionType::get(CGM.IntTy, args,
false);
444 return CGM.CreateRuntimeFunction(FTy,
"objc_sync_enter");
448 llvm::Constant *getSyncExitFn() {
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;
500 llvm::StructType *ModuleTy;
503 llvm::StructType *ProtocolTy;
508 llvm::StructType *ProtocolExtensionTy;
514 llvm::StructType *MethodDescriptionTy;
517 llvm::StructType *MethodDescriptionListTy;
522 llvm::StructType *ProtocolListTy;
526 llvm::StructType *CategoryTy;
528 llvm::StructType *ClassTy;
532 llvm::StructType *ClassExtensionTy;
536 llvm::StructType *IvarTy;
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;
611 llvm::StructType *ProtocolnfABITy;
617 llvm::StructType *ProtocolListnfABITy;
623 llvm::StructType *ClassnfABITy;
629 llvm::StructType *IvarnfABITy;
632 llvm::StructType *IvarListnfABITy;
638 llvm::StructType *ClassRonfABITy;
644 llvm::StructType *CategorynfABITy;
653 llvm::StructType *MessageRefTy;
667 llvm::StructType *SuperMessageRefTy;
672 llvm::Constant *getMessageSendFixupFn() {
674 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
675 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
677 "objc_msgSend_fixup");
680 llvm::Constant *getMessageSendFpretFixupFn() {
682 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
683 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
685 "objc_msgSend_fpret_fixup");
688 llvm::Constant *getMessageSendStretFixupFn() {
690 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
691 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
693 "objc_msgSend_stret_fixup");
696 llvm::Constant *getMessageSendSuper2FixupFn() {
699 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
700 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
702 "objc_msgSendSuper2_fixup");
705 llvm::Constant *getMessageSendSuper2StretFixupFn() {
708 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
709 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
711 "objc_msgSendSuper2_stret_fixup");
714 llvm::Constant *getObjCEndCatchFn() {
715 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy,
false),
720 llvm::Constant *getObjCBeginCatchFn() {
722 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(Int8PtrTy,
727 llvm::StructType *EHTypeTy;
739 SKIP_SCAN(
unsigned _skip = 0,
unsigned _scan = 0)
740 : skip(_skip), scan(_scan) {}
747 enum BLOCK_LAYOUT_OPCODE {
754 BLOCK_LAYOUT_OPERATOR = 0,
760 BLOCK_LAYOUT_NON_OBJECT_BYTES = 1,
765 BLOCK_LAYOUT_NON_OBJECT_WORDS = 2,
769 BLOCK_LAYOUT_STRONG = 3,
772 BLOCK_LAYOUT_BYREF = 4,
776 BLOCK_LAYOUT_WEAK = 5,
780 BLOCK_LAYOUT_UNRETAINED = 6
797 enum BLOCK_LAYOUT_OPCODE opcode;
800 RUN_SKIP(
enum BLOCK_LAYOUT_OPCODE Opcode = BLOCK_LAYOUT_OPERATOR,
803 : opcode(Opcode), block_var_bytepos(BytePos), block_var_size(Size) {}
806 bool operator<(
const RUN_SKIP &b)
const {
807 return block_var_bytepos < b.block_var_bytepos;
812 llvm::LLVMContext &VMContext;
821 llvm::SetVector<IdentifierInfo*> LazySymbols;
827 llvm::SetVector<IdentifierInfo*> DefinedSymbols;
830 llvm::StringMap<llvm::GlobalVariable*> ClassNames;
833 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
840 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
844 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
847 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
850 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
853 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
858 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
887 llvm::Constant *GetMethodVarName(
Selector Sel);
895 bool Extended =
false);
896 llvm::Constant *GetMethodVarType(
const FieldDecl *D);
904 const Decl *Container);
909 llvm::Constant *GetClassName(StringRef RuntimeName);
923 bool forStrongLayout,
929 return BuildIvarLayout(OI, beginOffset, endOffset,
true,
false);
936 return BuildIvarLayout(OI, beginOffset, endOffset,
false, hasMRCWeakIvars);
941 void UpdateRunSkipBlockVars(
bool IsByref,
946 void BuildRCBlockVarRecordLayout(
const RecordType *RT,
948 bool ByrefLayout=
false);
950 void BuildRCRecordLayout(
const llvm::StructLayout *RecLayout,
958 llvm::Constant *getBitmapBlockLayout(
bool ComputeByrefLayout);
963 const ObjCCommonTypesHelper &ObjCTypes);
967 llvm::Constant *EmitPropertyList(Twine
Name,
968 const Decl *Container,
970 const ObjCCommonTypesHelper &ObjCTypes);
974 llvm::Constant *EmitProtocolMethodTypes(Twine
Name,
976 const ObjCCommonTypesHelper &ObjCTypes);
979 void PushProtocolProperties(
980 llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet,
982 const Decl *Container,
984 const ObjCCommonTypesHelper &ObjCTypes);
1006 llvm::GlobalVariable *CreateMetadataVar(Twine
Name, llvm::Constant *Init,
1021 const ObjCCommonTypesHelper &ObjCTypes);
1025 void EmitImageInfo();
1031 bool isNonFragileABI()
const {
1032 return ObjCABI == 2;
1051 virtual llvm::Constant *GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD)=0;
1061 class CGObjCMac :
public CGObjCCommonMac {
1063 ObjCTypesHelper ObjCTypes;
1067 void EmitModuleInfo();
1071 llvm::Constant *EmitModuleSymbols();
1075 void FinishModule();
1113 llvm::Constant *Protocols,
1118 llvm::Constant *GetMethodDescriptionConstant(
const ObjCMethodDecl *MD);
1122 llvm::Constant *EmitMethodList(Twine
Name,
1123 const char *Section,
1137 llvm::Constant *EmitMethodDescList(Twine
Name,
1138 const char *Section,
1164 llvm::Constant *EmitProtocolList(Twine
Name,
1176 llvm::Function *ModuleInitFunction()
override;
1205 llvm::Constant *GetEHType(
QualType T)
override;
1216 llvm::Constant *GetPropertyGetFunction()
override;
1217 llvm::Constant *GetPropertySetFunction()
override;
1218 llvm::Constant *GetOptimizedPropertySetFunction(
bool atomic,
1219 bool copy)
override;
1220 llvm::Constant *GetGetStructFunction()
override;
1221 llvm::Constant *GetSetStructFunction()
override;
1222 llvm::Constant *GetCppAtomicObjectGetFunction()
override;
1223 llvm::Constant *GetCppAtomicObjectSetFunction()
override;
1224 llvm::Constant *EnumerationMutationFunction()
override;
1232 bool ClearInsertionPoint=
true)
override;
1234 Address AddrWeakObj)
override;
1239 bool threadlocal =
false)
override;
1251 unsigned CVRQualifiers)
override;
1258 llvm::GlobalVariable *GetClassGlobal(
const std::string &
Name,
1259 bool Weak =
false)
override {
1260 llvm_unreachable(
"CGObjCMac::GetClassGlobal");
1264 class CGObjCNonFragileABIMac :
public CGObjCCommonMac {
1266 ObjCNonFragileABITypesHelper ObjCTypes;
1267 llvm::GlobalVariable* ObjCEmptyCacheVar;
1268 llvm::GlobalVariable* ObjCEmptyVtableVar;
1271 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences;
1274 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences;
1277 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences;
1284 std::vector<llvm::GlobalValue*> DefinedMetaClasses;
1288 bool isVTableDispatchedSelector(
Selector Sel);
1292 void FinishNonFragileABIModule();
1297 const char *SymbolName,
1298 const char *SectionName);
1300 llvm::GlobalVariable * BuildClassRoTInitializer(
unsigned flags,
1301 unsigned InstanceStart,
1302 unsigned InstanceSize,
1304 llvm::GlobalVariable * BuildClassMetaData(
const std::string &ClassName,
1305 llvm::Constant *IsAGV,
1306 llvm::Constant *SuperClassGV,
1307 llvm::Constant *ClassRoGV,
1313 llvm::Constant *GetMethodDescriptionConstant(
const ObjCMethodDecl *MD);
1317 llvm::Constant *EmitMethodList(Twine
Name,
1318 const char *Section,
1329 unsigned long int offset);
1344 llvm::Constant *EmitProtocolList(Twine
Name,
1360 llvm::GlobalVariable *GetClassGlobal(
const std::string &
Name,
1361 bool Weak =
false)
override;
1387 llvm::GlobalVariable * ObjCIvarOffsetVariable(
1399 bool ForDefinition);
1401 const char *getMetaclassSymbolPrefix()
const {
1402 return "OBJC_METACLASS_$_";
1405 const char *getClassSymbolPrefix()
const {
1406 return "OBJC_CLASS_$_";
1410 uint32_t &InstanceStart,
1411 uint32_t &InstanceSize);
1416 return CGM.getContext().Selectors.getSelector(0, &II);
1421 return CGM.getContext().Selectors.getSelector(1, &II);
1426 bool ImplementationIsNonLazy(
const ObjCImplDecl *OD)
const;
1441 dyn_cast_or_null<ObjCMethodDecl>(CGF.
CurFuncDecl))
1442 if (MD->isInstanceMethod())
1451 llvm::Function *ModuleInitFunction()
override;
1473 {
return EmitSelector(CGF, Sel); }
1475 {
return EmitSelectorAddr(CGF, Sel); }
1481 {
return EmitSelector(CGF, Method->
getSelector()); }
1492 llvm::Constant *GetEHType(
QualType T)
override;
1494 llvm::Constant *GetPropertyGetFunction()
override {
1495 return ObjCTypes.getGetPropertyFn();
1497 llvm::Constant *GetPropertySetFunction()
override {
1498 return ObjCTypes.getSetPropertyFn();
1501 llvm::Constant *GetOptimizedPropertySetFunction(
bool atomic,
1502 bool copy)
override {
1503 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
1506 llvm::Constant *GetSetStructFunction()
override {
1507 return ObjCTypes.getCopyStructFn();
1509 llvm::Constant *GetGetStructFunction()
override {
1510 return ObjCTypes.getCopyStructFn();
1512 llvm::Constant *GetCppAtomicObjectSetFunction()
override {
1513 return ObjCTypes.getCppAtomicObjectFunction();
1515 llvm::Constant *GetCppAtomicObjectGetFunction()
override {
1516 return ObjCTypes.getCppAtomicObjectFunction();
1519 llvm::Constant *EnumerationMutationFunction()
override {
1520 return ObjCTypes.getEnumerationMutationFn();
1528 bool ClearInsertionPoint=
true)
override;
1530 Address AddrWeakObj)
override;
1535 bool threadlocal =
false)
override;
1546 unsigned CVRQualifiers)
override;
1554 struct NullReturnState {
1555 llvm::BasicBlock *NullBB;
1556 NullReturnState() : NullBB(nullptr) {}
1569 CGF.
Builder.CreateCondBr(isNull, NullBB, callBB);
1581 if (!NullBB)
return result;
1585 llvm::BasicBlock *contBB =
nullptr;
1588 llvm::BasicBlock *callBB = CGF.
Builder.GetInsertBlock();
1599 CallArgList::const_iterator
I = CallArgs.begin();
1603 if (ParamDecl->
hasAttr<NSConsumedAttr>()) {
1606 "NullReturnState::complete - arg not on object");
1613 assert(CGF.
Builder.GetInsertBlock() == NullBB);
1632 llvm::PHINode *phi = CGF.
Builder.CreatePHI(null->getType(), 2);
1634 phi->addIncoming(null, NullBB);
1643 assert(result.
isAggregate() &&
"null init of non-aggregate result?");
1654 llvm::Type *scalarTy = callResult.first->getType();
1655 llvm::Constant *scalarZero = llvm::Constant::getNullValue(scalarTy);
1658 llvm::PHINode *real = CGF.
Builder.CreatePHI(scalarTy, 2);
1659 real->addIncoming(callResult.first, callBB);
1660 real->addIncoming(scalarZero, NullBB);
1661 llvm::PHINode *imag = CGF.
Builder.CreatePHI(scalarTy, 2);
1662 imag->addIncoming(callResult.second, callBB);
1663 imag->addIncoming(scalarZero, NullBB);
1674 llvm::GlobalVariable *
C,
unsigned idx0,
1677 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),
1678 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)
1680 return llvm::ConstantExpr::getGetElementPtr(C->getValueType(),
C, Idxs);
1687 if (OID->
hasAttr<ObjCExceptionAttr>())
1706 return EmitClassRef(CGF, ID);
1711 return EmitSelector(CGF, Sel);
1714 return EmitSelectorAddr(CGF, Sel);
1721 llvm::Constant *CGObjCMac::GetEHType(
QualType T) {
1724 return CGM.GetAddrOfRTTIDescriptor(
1725 CGM.getContext().getObjCIdRedefinitionType(),
true);
1729 return CGM.GetAddrOfRTTIDescriptor(
1730 CGM.getContext().getObjCClassRedefinitionType(),
true);
1733 return CGM.GetAddrOfRTTIDescriptor(T,
true);
1735 llvm_unreachable(
"asking for catch type for ObjC type in fragile runtime");
1759 return (CGM.getLangOpts().NoConstantCFStrings == 0 ?
1760 CGM.GetAddrOfConstantCFString(SL) :
1761 CGM.GetAddrOfConstantString(SL));
1777 bool isCategoryImpl,
1779 bool IsClassMessage,
1795 if (IsClassMessage) {
1796 if (isCategoryImpl) {
1807 llvm::Constant *MetaClassPtr = EmitMetaClassRef(Class);
1814 }
else if (isCategoryImpl)
1823 llvm::Type *ClassTy =
1828 return EmitMessageSend(CGF, Return, ResultType,
1829 EmitSelector(CGF, Sel),
1830 ObjCSuper.
getPointer(), ObjCTypes.SuperPtrCTy,
1831 true, CallArgs, Method, Class, ObjCTypes);
1843 return EmitMessageSend(CGF, Return, ResultType,
1844 EmitSelector(CGF, Sel),
1846 false, CallArgs, Method, Class, ObjCTypes);
1869 const ObjCCommonTypesHelper &ObjCTypes) {
1873 ActualArgs.
add(RValue::get(Arg0), Arg0Ty);
1878 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
1881 assert(CGM.getContext().getCanonicalType(Method->
getReturnType()) ==
1882 CGM.getContext().getCanonicalType(ResultType) &&
1883 "Result type mismatch!");
1885 bool ReceiverCanBeNull =
true;
1890 ReceiverCanBeNull =
false;
1894 }
else if (ClassReceiver && Method && Method->
isClassMethod()) {
1899 }
else if (
auto CurMethod =
1900 dyn_cast_or_null<ObjCMethodDecl>(CGF.
CurCodeDecl)) {
1901 auto Self = CurMethod->getSelfDecl();
1902 if (Self->getType().isConstQualified()) {
1903 if (
auto LI = dyn_cast<llvm::LoadInst>(Arg0->stripPointerCasts())) {
1905 if (SelfAddr == LI->getPointerOperand()) {
1906 ReceiverCanBeNull =
false;
1912 NullReturnState nullReturn;
1914 llvm::Constant *Fn =
nullptr;
1915 if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
1916 if (ReceiverCanBeNull) nullReturn.init(CGF, Arg0);
1917 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
1918 : ObjCTypes.getSendStretFn(IsSuper);
1919 }
else if (CGM.ReturnTypeUsesFPRet(ResultType)) {
1920 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
1921 : ObjCTypes.getSendFpretFn(IsSuper);
1922 }
else if (CGM.ReturnTypeUsesFP2Ret(ResultType)) {
1923 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)
1924 : ObjCTypes.getSendFp2retFn(IsSuper);
1928 if (ReceiverCanBeNull && CGM.ReturnTypeUsesSRet(MSI.CallInfo))
1929 nullReturn.init(CGF, Arg0);
1930 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
1931 : ObjCTypes.getSendFn(IsSuper);
1935 bool RequiresNullCheck =
false;
1936 if (ReceiverCanBeNull && CGM.getLangOpts().ObjCAutoRefCount && Method) {
1937 for (
const auto *ParamDecl : Method->
params()) {
1938 if (ParamDecl->
hasAttr<NSConsumedAttr>()) {
1939 if (!nullReturn.NullBB)
1940 nullReturn.init(CGF, Arg0);
1941 RequiresNullCheck =
true;
1947 llvm::Instruction *CallSite;
1948 Fn = llvm::ConstantExpr::getBitCast(Fn, MSI.MessengerType);
1949 RValue rvalue = CGF.
EmitCall(MSI.CallInfo, Fn, Return, ActualArgs,
1954 if (Method && Method->
hasAttr<NoReturnAttr>() && !ReceiverCanBeNull) {
1955 llvm::CallSite(CallSite).setDoesNotReturn();
1958 return nullReturn.complete(CGF, rvalue, ResultType, CallArgs,
1959 RequiresNullCheck ? Method :
nullptr);
1963 bool pointee =
false) {
1968 return Qualifiers::Strong;
1971 return Qualifiers::Weak;
1975 if (pointee)
return Qualifiers::GCNone;
1976 switch (ownership) {
1977 case Qualifiers::OCL_Weak:
return Qualifiers::Weak;
1978 case Qualifiers::OCL_Strong:
return Qualifiers::Strong;
1979 case Qualifiers::OCL_ExplicitNone:
return Qualifiers::GCNone;
1980 case Qualifiers::OCL_Autoreleasing: llvm_unreachable(
"autoreleasing ivar?");
1981 case Qualifiers::OCL_None: llvm_unreachable(
"known nonzero");
1983 llvm_unreachable(
"bad objc ownership");
1988 return Qualifiers::Strong;
1991 if (Ctx.
getLangOpts().getGC() != LangOptions::NonGC) {
1996 return Qualifiers::GCNone;
2002 uint64_t SizeInWords;
2003 IvarInfo(
CharUnits offset, uint64_t sizeInWords)
2004 :
Offset(offset), SizeInWords(sizeInWords) {}
2007 bool operator<(
const IvarInfo &other)
const {
2008 return Offset < other.Offset;
2013 class IvarLayoutBuilder {
2024 bool ForStrongLayout;
2027 bool IsDisordered =
false;
2032 CharUnits instanceEnd,
bool forStrongLayout)
2033 : CGM(CGM), InstanceBegin(instanceBegin), InstanceEnd(instanceEnd),
2034 ForStrongLayout(forStrongLayout) {
2039 template <
class Iterator,
class GetOffsetFn>
2040 void visitAggregate(Iterator
begin, Iterator
end,
2042 const GetOffsetFn &getOffset);
2050 bool hasBitmapData()
const {
return !IvarsInfo.empty(); }
2052 llvm::Constant *buildBitmap(CGObjCCommonMac &CGObjC,
2056 const unsigned char *s = buffer.data();
2057 for (
unsigned i = 0, e = buffer.size(); i < e; i++)
2059 printf(
"0x0%x%s", s[i], s[i] != 0 ?
", " :
"");
2061 printf(
"0x%x%s", s[i], s[i] != 0 ?
", " :
"");
2067 llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(
CodeGenModule &CGM,
2070 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2071 if (CGM.
getLangOpts().getGC() == LangOptions::NonGC)
2074 IvarLayoutBuilder builder(CGM, CharUnits::Zero(), blockInfo.
BlockSize,
2077 builder.visitBlock(blockInfo);
2079 if (!builder.hasBitmapData())
2083 llvm::Constant *
C = builder.buildBitmap(*
this, buffer);
2084 if (CGM.
getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
2085 printf(
"\n block variable layout for block: ");
2086 builder.dump(buffer);
2092 void IvarLayoutBuilder::visitBlock(
const CGBlockInfo &blockInfo) {
2095 IvarsInfo.push_back(IvarInfo(CharUnits::Zero(), 1));
2105 for (
const auto &CI : blockDecl->
captures()) {
2106 const VarDecl *variable = CI.getVariable();
2118 if (fieldOffset < lastFieldOffset)
2119 IsDisordered =
true;
2120 lastFieldOffset = fieldOffset;
2124 IvarsInfo.push_back(IvarInfo(fieldOffset, 1));
2128 assert(!type->
isArrayType() &&
"array variable should not be caught");
2130 visitRecord(record, fieldOffset);
2136 if (GCAttr == Qualifiers::Strong) {
2139 IvarsInfo.push_back(IvarInfo(fieldOffset, 1));
2156 return Qualifiers::OCL_None;
2160 return ByrefLayout ? Qualifiers::OCL_ExplicitNone : Qualifiers::OCL_Strong;
2162 return Qualifiers::OCL_None;
2165 void CGObjCCommonMac::UpdateRunSkipBlockVars(
bool IsByref,
2171 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset,
2173 else if (LifeTime == Qualifiers::OCL_Strong)
2174 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset,
2176 else if (LifeTime == Qualifiers::OCL_Weak)
2177 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset,
2179 else if (LifeTime == Qualifiers::OCL_ExplicitNone)
2180 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset,
2183 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES,
2188 void CGObjCCommonMac::BuildRCRecordLayout(
const llvm::StructLayout *RecLayout,
2193 bool IsUnion = (RD && RD->
isUnion());
2194 CharUnits MaxUnionSize = CharUnits::Zero();
2196 const FieldDecl *LastFieldBitfieldOrUnnamed =
nullptr;
2197 CharUnits MaxFieldOffset = CharUnits::Zero();
2198 CharUnits LastBitfieldOrUnnamedOffset = CharUnits::Zero();
2200 if (RecFields.empty())
2204 for (
unsigned i = 0, e = RecFields.size(); i != e; ++i) {
2214 LastFieldBitfieldOrUnnamed = Field;
2215 LastBitfieldOrUnnamedOffset = FieldOffset;
2219 LastFieldBitfieldOrUnnamed =
nullptr;
2226 BytePos + FieldOffset, HasUnion);
2232 dyn_cast_or_null<ConstantArrayType>(Array);
2233 uint64_t ElCount = CArray->
getSize().getZExtValue();
2234 assert(CArray &&
"only array with known element size is supported");
2238 dyn_cast_or_null<ConstantArrayType>(Array);
2239 ElCount *= CArray->
getSize().getZExtValue();
2243 int OldIndex = RunSkipBlockVars.size() - 1;
2245 BuildRCBlockVarRecordLayout(RT, BytePos + FieldOffset,
2251 for (
int FirstIndex = RunSkipBlockVars.size() - 1 ;ElIx < ElCount; ElIx++) {
2253 for (
int i = OldIndex+1; i <= FirstIndex; ++i)
2254 RunSkipBlockVars.push_back(
2255 RUN_SKIP(RunSkipBlockVars[i].opcode,
2256 RunSkipBlockVars[i].block_var_bytepos + Size*ElIx,
2257 RunSkipBlockVars[i].block_var_size));
2265 if (UnionIvarSize > MaxUnionSize) {
2266 MaxUnionSize = UnionIvarSize;
2268 MaxFieldOffset = FieldOffset;
2271 UpdateRunSkipBlockVars(
false,
2272 getBlockCaptureLifetime(FQT, ByrefLayout),
2273 BytePos + FieldOffset,
2278 if (LastFieldBitfieldOrUnnamed) {
2279 if (LastFieldBitfieldOrUnnamed->
isBitField()) {
2281 uint64_t BitFieldSize
2283 unsigned UnsSize = (BitFieldSize / ByteSizeInBits) +
2284 ((BitFieldSize % ByteSizeInBits) != 0);
2285 CharUnits Size = CharUnits::fromQuantity(UnsSize);
2286 Size += LastBitfieldOrUnnamedOffset;
2287 UpdateRunSkipBlockVars(
false,
2288 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
2290 BytePos + LastBitfieldOrUnnamedOffset,
2293 assert(!LastFieldBitfieldOrUnnamed->
getIdentifier() &&
"Expected unnamed");
2297 UpdateRunSkipBlockVars(
false,
2298 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
2300 BytePos + LastBitfieldOrUnnamedOffset,
2306 UpdateRunSkipBlockVars(
false,
2307 getBlockCaptureLifetime(MaxField->
getType(), ByrefLayout),
2308 BytePos + MaxFieldOffset,
2312 void CGObjCCommonMac::BuildRCBlockVarRecordLayout(
const RecordType *RT,
2319 const llvm::StructLayout *RecLayout =
2320 CGM.
getDataLayout().getStructLayout(cast<llvm::StructType>(Ty));
2322 BuildRCRecordLayout(RecLayout, RD, Fields, BytePos, HasUnion, ByrefLayout);
2334 uint64_t CGObjCCommonMac::InlineLayoutInstruction(
2337 if (Layout.size() <= 3) {
2338 unsigned size = Layout.size();
2339 unsigned strong_word_count = 0, byref_word_count=0, weak_word_count=0;
2341 enum BLOCK_LAYOUT_OPCODE opcode ;
2345 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2346 if (opcode == BLOCK_LAYOUT_STRONG)
2347 strong_word_count = (inst & 0xF)+1;
2351 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2352 if (opcode == BLOCK_LAYOUT_BYREF)
2353 byref_word_count = (inst & 0xF)+1;
2357 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2358 if (opcode == BLOCK_LAYOUT_WEAK)
2359 weak_word_count = (inst & 0xF)+1;
2366 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2367 if (opcode == BLOCK_LAYOUT_STRONG) {
2368 strong_word_count = (inst & 0xF)+1;
2370 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2371 if (opcode == BLOCK_LAYOUT_BYREF)
2372 byref_word_count = (inst & 0xF)+1;
2373 else if (opcode == BLOCK_LAYOUT_WEAK)
2374 weak_word_count = (inst & 0xF)+1;
2378 else if (opcode == BLOCK_LAYOUT_BYREF) {
2379 byref_word_count = (inst & 0xF)+1;
2381 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2382 if (opcode == BLOCK_LAYOUT_WEAK)
2383 weak_word_count = (inst & 0xF)+1;
2393 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2394 if (opcode == BLOCK_LAYOUT_STRONG)
2395 strong_word_count = (inst & 0xF)+1;
2396 else if (opcode == BLOCK_LAYOUT_BYREF)
2397 byref_word_count = (inst & 0xF)+1;
2398 else if (opcode == BLOCK_LAYOUT_WEAK)
2399 weak_word_count = (inst & 0xF)+1;
2411 if (strong_word_count == 16 || byref_word_count == 16 || weak_word_count == 16)
2415 (strong_word_count != 0) + (byref_word_count != 0) + (weak_word_count != 0);
2417 if (size == count) {
2418 if (strong_word_count)
2419 Result = strong_word_count;
2421 if (byref_word_count)
2422 Result += byref_word_count;
2424 if (weak_word_count)
2425 Result += weak_word_count;
2431 llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(
bool ComputeByrefLayout) {
2432 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2433 if (RunSkipBlockVars.empty())
2437 unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2441 llvm::array_pod_sort(RunSkipBlockVars.begin(), RunSkipBlockVars.end());
2444 unsigned size = RunSkipBlockVars.size();
2445 for (
unsigned i = 0; i < size; i++) {
2446 enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode;
2447 CharUnits start_byte_pos = RunSkipBlockVars[i].block_var_bytepos;
2448 CharUnits end_byte_pos = start_byte_pos;
2451 if (opcode == RunSkipBlockVars[j].opcode) {
2452 end_byte_pos = RunSkipBlockVars[j++].block_var_bytepos;
2459 end_byte_pos - start_byte_pos + RunSkipBlockVars[j-1].block_var_size;
2462 RunSkipBlockVars[j].block_var_bytepos -
2463 RunSkipBlockVars[j-1].block_var_bytepos - RunSkipBlockVars[j-1].block_var_size;
2464 size_in_bytes += gap;
2466 CharUnits residue_in_bytes = CharUnits::Zero();
2467 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) {
2468 residue_in_bytes = size_in_bytes % WordSizeInBytes;
2469 size_in_bytes -= residue_in_bytes;
2470 opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS;
2473 unsigned size_in_words = size_in_bytes.
getQuantity() / WordSizeInBytes;
2474 while (size_in_words >= 16) {
2477 unsigned char inst = (opcode << 4) | 0xf;
2478 Layout.push_back(inst);
2479 size_in_words -= 16;
2481 if (size_in_words > 0) {
2484 unsigned char inst = (opcode << 4) | (size_in_words-1);
2485 Layout.push_back(inst);
2487 if (residue_in_bytes > CharUnits::Zero()) {
2488 unsigned char inst =
2489 (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) | (residue_in_bytes.
getQuantity()-1);
2490 Layout.push_back(inst);
2494 while (!Layout.empty()) {
2495 unsigned char inst = Layout.back();
2496 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2497 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES || opcode == BLOCK_LAYOUT_NON_OBJECT_WORDS)
2503 uint64_t Result = InlineLayoutInstruction(Layout);
2507 if (ComputeByrefLayout)
2508 printf(
"\n Inline BYREF variable layout: ");
2510 printf(
"\n Inline block variable layout: ");
2511 printf(
"0x0%" PRIx64
"", Result);
2512 if (
auto numStrong = (Result & 0xF00) >> 8)
2513 printf(
", BL_STRONG:%d", (
int) numStrong);
2514 if (
auto numByref = (Result & 0x0F0) >> 4)
2515 printf(
", BL_BYREF:%d", (
int) numByref);
2516 if (
auto numWeak = (Result & 0x00F) >> 0)
2517 printf(
", BL_WEAK:%d", (
int) numWeak);
2518 printf(
", BL_OPERATOR:0\n");
2520 return llvm::ConstantInt::get(CGM.
IntPtrTy, Result);
2523 unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0;
2524 Layout.push_back(inst);
2526 for (
unsigned i = 0, e = Layout.size(); i != e; i++)
2527 BitMap += Layout[i];
2530 if (ComputeByrefLayout)
2531 printf(
"\n Byref variable layout: ");
2533 printf(
"\n Block variable layout: ");
2534 for (
unsigned i = 0, e = BitMap.size(); i != e; i++) {
2535 unsigned char inst = BitMap[i];
2536 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2539 case BLOCK_LAYOUT_OPERATOR:
2540 printf(
"BL_OPERATOR:");
2543 case BLOCK_LAYOUT_NON_OBJECT_BYTES:
2544 printf(
"BL_NON_OBJECT_BYTES:");
2546 case BLOCK_LAYOUT_NON_OBJECT_WORDS:
2547 printf(
"BL_NON_OBJECT_WORD:");
2549 case BLOCK_LAYOUT_STRONG:
2550 printf(
"BL_STRONG:");
2552 case BLOCK_LAYOUT_BYREF:
2553 printf(
"BL_BYREF:");
2555 case BLOCK_LAYOUT_WEAK:
2558 case BLOCK_LAYOUT_UNRETAINED:
2559 printf(
"BL_UNRETAINED:");
2564 printf(
"%d", (inst & 0xf) + delta);
2572 llvm::GlobalVariable *Entry = CreateMetadataVar(
2574 llvm::ConstantDataArray::getString(VMContext, BitMap,
false),
2575 "__TEXT,__objc_classname,cstring_literals", CharUnits::One(),
true);
2579 llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(
CodeGenModule &CGM,
2581 assert(CGM.
getLangOpts().getGC() == LangOptions::NonGC);
2583 RunSkipBlockVars.clear();
2584 bool hasUnion =
false;
2588 unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2593 const llvm::StructLayout *layout =
2599 UpdateRunSkipBlockVars(
false, Qualifiers::OCL_None,
2603 for (
const auto &CI : blockDecl->
captures()) {
2604 const VarDecl *variable = CI.getVariable();
2613 CharUnits::fromQuantity(layout->getElementOffset(capture.
getIndex()));
2615 assert(!type->
isArrayType() &&
"array variable should not be caught");
2618 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion);
2623 fieldSize = CharUnits::fromQuantity(WordSizeInBytes);
2626 UpdateRunSkipBlockVars(CI.isByRef(), getBlockCaptureLifetime(type,
false),
2627 fieldOffset, fieldSize);
2629 return getBitmapBlockLayout(
false);
2635 assert(CGM.
getLangOpts().getGC() == LangOptions::NonGC);
2636 assert(!T->
isArrayType() &&
"__block array variable should not be caught");
2638 RunSkipBlockVars.clear();
2639 bool hasUnion =
false;
2641 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion,
true );
2642 llvm::Constant *Result = getBitmapBlockLayout(
true);
2643 if (isa<llvm::ConstantInt>(Result))
2644 Result = llvm::ConstantExpr::getIntToPtr(Result, CGM.
Int8PtrTy);
2647 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2657 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
2658 ObjCTypes.getExternalProtocolPtrTy());
2670 GetOrEmitProtocol(PD);
2673 llvm::Constant *CGObjCCommonMac::GetProtocolRef(
const ObjCProtocolDecl *PD) {
2675 return GetOrEmitProtocol(PD);
2677 return GetOrEmitProtocolRef(PD);
2693 llvm::GlobalVariable *Entry = Protocols[PD->
getIdentifier()];
2696 if (Entry && Entry->hasInitializer())
2708 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
2709 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
2710 std::vector<llvm::Constant*> MethodTypesExt, OptMethodTypesExt;
2712 llvm::Constant *C = GetMethodDescriptionConstant(MD);
2714 return GetOrEmitProtocolRef(PD);
2716 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
2717 OptInstanceMethods.push_back(C);
2718 OptMethodTypesExt.push_back(GetMethodVarType(MD,
true));
2720 InstanceMethods.push_back(C);
2721 MethodTypesExt.push_back(GetMethodVarType(MD,
true));
2726 llvm::Constant *C = GetMethodDescriptionConstant(MD);
2728 return GetOrEmitProtocolRef(PD);
2730 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
2731 OptClassMethods.push_back(C);
2732 OptMethodTypesExt.push_back(GetMethodVarType(MD,
true));
2734 ClassMethods.push_back(C);
2735 MethodTypesExt.push_back(GetMethodVarType(MD,
true));
2739 MethodTypesExt.insert(MethodTypesExt.end(),
2740 OptMethodTypesExt.begin(), OptMethodTypesExt.end());
2742 llvm::Constant *Values[] = {
2743 EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods,
2746 EmitProtocolList(
"OBJC_PROTOCOL_REFS_" + PD->
getName(),
2748 EmitMethodDescList(
"OBJC_PROTOCOL_INSTANCE_METHODS_" + PD->
getName(),
2749 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
2751 EmitMethodDescList(
"OBJC_PROTOCOL_CLASS_METHODS_" + PD->
getName(),
2752 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2754 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
2759 assert(Entry->hasPrivateLinkage());
2760 Entry->setInitializer(Init);
2762 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolTy,
2763 false, llvm::GlobalValue::PrivateLinkage,
2764 Init,
"OBJC_PROTOCOL_" + PD->
getName());
2765 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
2767 Entry->setAlignment(4);
2776 llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD) {
2777 llvm::GlobalVariable *&Entry = Protocols[PD->
getIdentifier()];
2783 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolTy,
2784 false, llvm::GlobalValue::PrivateLinkage,
2785 nullptr,
"OBJC_PROTOCOL_" + PD->
getName());
2786 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
2788 Entry->setAlignment(4);
2809 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
2810 llvm::Constant *Values[] = {
2811 llvm::ConstantInt::get(ObjCTypes.IntTy, Size),
2812 EmitMethodDescList(
"OBJC_PROTOCOL_INSTANCE_METHODS_OPT_" + PD->
getName(),
2813 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
2814 OptInstanceMethods),
2815 EmitMethodDescList(
"OBJC_PROTOCOL_CLASS_METHODS_OPT_" + PD->
getName(),
2816 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2818 EmitPropertyList(
"OBJC_$_PROP_PROTO_LIST_" + PD->
getName(),
nullptr, PD,
2820 EmitProtocolMethodTypes(
"OBJC_PROTOCOL_METHOD_TYPES_" + PD->
getName(),
2821 MethodTypesExt, ObjCTypes)};
2824 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
2825 Values[3]->isNullValue() && Values[4]->isNullValue())
2826 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
2828 llvm::Constant *Init =
2829 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
2832 return CreateMetadataVar(
"\01l_OBJC_PROTOCOLEXT_" + PD->
getName(), Init,
2844 CGObjCMac::EmitProtocolList(Twine
Name,
2850 ProtocolRefs.push_back(GetProtocolRef(*begin));
2853 if (ProtocolRefs.empty())
2854 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
2857 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
2859 llvm::Constant *Values[3];
2861 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
2862 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy,
2863 ProtocolRefs.size() - 1);
2865 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
2866 ProtocolRefs.size()),
2869 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
2870 llvm::GlobalVariable *GV =
2871 CreateMetadataVar(Name, Init,
"__OBJC,__cat_cls_meth,regular,no_dead_strip",
2873 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
2876 void CGObjCCommonMac::
2877 PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*,16> &PropertySet,
2879 const Decl *Container,
2881 const ObjCCommonTypesHelper &ObjCTypes) {
2883 PushProtocolProperties(PropertySet, Properties, Container,
P, ObjCTypes);
2887 llvm::Constant *Prop[] = {
2889 GetPropertyTypeString(PD, Container)
2891 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, Prop));
2907 llvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name,
2908 const Decl *Container,
2910 const ObjCCommonTypesHelper &ObjCTypes) {
2912 llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
2915 llvm::Constant *Prop[] = {GetPropertyName(PD->
getIdentifier()),
2916 GetPropertyTypeString(PD, Container)};
2917 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, Prop));
2934 for (
const auto *
P : OID->all_referenced_protocols())
2935 PushProtocolProperties(PropertySet, Properties, Container,
P, ObjCTypes);
2938 for (
const auto *
P : CD->protocols())
2939 PushProtocolProperties(PropertySet, Properties, Container,
P, ObjCTypes);
2943 if (Properties.empty())
2944 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
2946 unsigned PropertySize =
2948 llvm::Constant *Values[3];
2949 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
2950 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
2951 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
2953 Values[2] = llvm::ConstantArray::get(AT, Properties);
2954 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
2956 llvm::GlobalVariable *GV =
2957 CreateMetadataVar(Name, Init,
2958 (ObjCABI == 2) ?
"__DATA, __objc_const" :
2959 "__OBJC,__property,regular,no_dead_strip",
2962 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy);
2966 CGObjCCommonMac::EmitProtocolMethodTypes(Twine Name,
2968 const ObjCCommonTypesHelper &ObjCTypes) {
2970 if (MethodTypes.empty())
2971 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy);
2973 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
2974 MethodTypes.size());
2975 llvm::Constant *Init = llvm::ConstantArray::get(AT, MethodTypes);
2977 llvm::GlobalVariable *GV = CreateMetadataVar(
2978 Name, Init, (ObjCABI == 2) ?
"__DATA, __objc_const" : StringRef(),
2980 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.Int8PtrPtrTy);
2990 CGObjCMac::GetMethodDescriptionConstant(
const ObjCMethodDecl *MD) {
2991 llvm::Constant *Desc[] = {
2992 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->
getSelector()),
2993 ObjCTypes.SelectorPtrTy),
2994 GetMethodVarType(MD)
2999 return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
3004 CGObjCMac::EmitMethodDescList(Twine Name,
const char *Section,
3007 if (Methods.empty())
3008 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
3010 llvm::Constant *Values[2];
3011 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
3012 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
3014 Values[1] = llvm::ConstantArray::get(AT, Methods);
3015 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
3017 llvm::GlobalVariable *GV =
3019 return llvm::ConstantExpr::getBitCast(GV,
3020 ObjCTypes.MethodDescriptionListPtrTy);
3035 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.CategoryTy);
3046 llvm::raw_svector_ostream(ExtName) << Interface->
getName() <<
'_'
3052 InstanceMethods.push_back(GetMethodConstant(I));
3056 ClassMethods.push_back(GetMethodConstant(I));
3058 llvm::Constant *Values[7];
3059 Values[0] = GetClassName(OCD->
getName());
3062 Values[2] = EmitMethodList(
"OBJC_CATEGORY_INSTANCE_METHODS_" + ExtName.str(),
3063 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
3065 Values[3] = EmitMethodList(
"OBJC_CATEGORY_CLASS_METHODS_" + ExtName.str(),
3066 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
3070 EmitProtocolList(
"OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
3073 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
3075 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
3079 Values[6] = EmitPropertyList(
"\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
3082 Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3085 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
3088 llvm::GlobalVariable *GV =
3089 CreateMetadataVar(
"OBJC_CATEGORY_" + ExtName.str(), Init,
3090 "__OBJC,__category,regular,no_dead_strip",
3092 DefinedCategories.push_back(GV);
3093 DefinedCategoryNames.insert(ExtName.str());
3095 MethodDefinitions.clear();
3155 for (
auto field : recType->getDecl()->fields()) {
3170 assert(CGM.
getLangOpts().getGC() == LangOptions::NonGC);
3208 llvm::Constant *Protocols =
3209 EmitProtocolList(
"OBJC_CLASS_PROTOCOLS_" + ID->
getName(),
3216 bool hasMRCWeak =
false;
3233 InstanceMethods.push_back(GetMethodConstant(I));
3237 ClassMethods.push_back(GetMethodConstant(I));
3240 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
3244 if (llvm::Constant *C = GetMethodConstant(MD))
3245 InstanceMethods.push_back(C);
3247 if (llvm::Constant *C = GetMethodConstant(MD))
3248 InstanceMethods.push_back(C);
3252 llvm::Constant *Values[12];
3253 Values[ 0] = EmitMetaClass(ID, Protocols, ClassMethods);
3256 LazySymbols.insert(Super->getIdentifier());
3259 llvm::ConstantExpr::getBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
3260 ObjCTypes.ClassPtrTy);
3262 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
3266 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
3267 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
3268 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size.
getQuantity());
3269 Values[ 6] = EmitIvarList(ID,
false);
3270 Values[7] = EmitMethodList(
"OBJC_INSTANCE_METHODS_" + ID->
getName(),
3271 "__OBJC,__inst_meth,regular,no_dead_strip",
3274 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
3275 Values[ 9] = Protocols;
3276 Values[10] = BuildStrongIvarLayout(ID, CharUnits::Zero(), Size);
3277 Values[11] = EmitClassExtension(ID, Size, hasMRCWeak);
3278 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
3280 std::string
Name(
"OBJC_CLASS_");
3282 const char *Section =
"__OBJC,__class,regular,no_dead_strip";
3284 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3286 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3287 "Forward metaclass reference has incorrect type.");
3288 GV->setInitializer(Init);
3289 GV->setSection(Section);
3293 GV = CreateMetadataVar(Name, Init, Section, CGM.
getPointerAlign(),
true);
3294 DefinedClasses.push_back(GV);
3295 ImplementedClasses.push_back(Interface);
3297 MethodDefinitions.clear();
3301 llvm::Constant *Protocols,
3304 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ClassTy);
3309 llvm::Constant *Values[12];
3316 ObjCTypes.ClassPtrTy);
3322 llvm::ConstantExpr::getBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
3323 ObjCTypes.ClassPtrTy);
3325 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
3329 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
3330 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
3331 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
3332 Values[ 6] = EmitIvarList(ID,
true);
3335 "__OBJC,__cls_meth,regular,no_dead_strip", Methods);
3337 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
3338 Values[ 9] = Protocols;
3340 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
3342 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
3343 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
3346 std::string
Name(
"OBJC_METACLASS_");
3350 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3352 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3353 "Forward metaclass reference has incorrect type.");
3354 GV->setInitializer(Init);
3356 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
3357 llvm::GlobalValue::PrivateLinkage,
3360 GV->setSection(
"__OBJC,__meta_class,regular,no_dead_strip");
3361 GV->setAlignment(4);
3378 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3380 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
3381 llvm::GlobalValue::PrivateLinkage,
nullptr,
3384 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3385 "Forward metaclass reference has incorrect type.");
3391 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3394 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
3395 llvm::GlobalValue::PrivateLinkage,
nullptr,
3398 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3399 "Forward class metadata reference has incorrect type.");
3418 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
3420 llvm::Constant *Values[3];
3421 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
3422 Values[1] = BuildWeakIvarLayout(ID, CharUnits::Zero(), InstanceSize,
3424 Values[2] = EmitPropertyList(
"\01l_OBJC_$_PROP_LIST_" + ID->
getName(),
3428 if (Values[1]->isNullValue() && Values[2]->isNullValue())
3429 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
3431 llvm::Constant *Init =
3432 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
3433 return CreateMetadataVar(
"OBJC_CLASSEXT_" + ID->
getName(), Init,
3434 "__OBJC,__class_ext,regular,no_dead_strip",
3452 std::vector<llvm::Constant*> Ivars;
3460 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3467 if (!IVD->getDeclName())
3469 llvm::Constant *Ivar[] = {
3470 GetMethodVarName(IVD->getIdentifier()),
3471 GetMethodVarType(IVD),
3472 llvm::ConstantInt::get(ObjCTypes.IntTy,
3473 ComputeIvarBaseOffset(CGM, OID, IVD))
3475 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar));
3480 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3482 llvm::Constant *Values[2];
3483 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
3484 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
3486 Values[1] = llvm::ConstantArray::get(AT, Ivars);
3487 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
3489 llvm::GlobalVariable *GV;
3492 CreateMetadataVar(
"OBJC_CLASS_VARIABLES_" + ID->
getName(), Init,
3493 "__OBJC,__class_vars,regular,no_dead_strip",
3496 GV = CreateMetadataVar(
"OBJC_INSTANCE_VARIABLES_" + ID->
getName(), Init,
3497 "__OBJC,__instance_vars,regular,no_dead_strip",
3499 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy);
3519 llvm::Constant *CGObjCMac::GetMethodConstant(
const ObjCMethodDecl *MD) {
3520 llvm::Function *Fn = GetMethodDefinition(MD);
3524 llvm::Constant *Method[] = {
3525 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->
getSelector()),
3526 ObjCTypes.SelectorPtrTy),
3527 GetMethodVarType(MD),
3528 llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy)
3530 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
3533 llvm::Constant *CGObjCMac::EmitMethodList(Twine Name,
3534 const char *Section,
3537 if (Methods.empty())
3538 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
3540 llvm::Constant *Values[3];
3541 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
3542 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
3543 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
3545 Values[2] = llvm::ConstantArray::get(AT, Methods);
3546 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
3548 llvm::GlobalVariable *GV =
3550 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListPtrTy);
3553 llvm::Function *CGObjCCommonMac::GenerateMethod(
const ObjCMethodDecl *OMD,
3556 GetNameForMethod(OMD, CD, Name);
3559 llvm::FunctionType *MethodTy =
3561 llvm::Function *Method =
3566 MethodDefinitions.insert(std::make_pair(OMD, Method));
3571 llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
3572 llvm::Constant *Init,
3576 llvm::Type *Ty = Init->getType();
3577 llvm::GlobalVariable *GV =
3578 new llvm::GlobalVariable(CGM.
getModule(), Ty,
false,
3579 llvm::GlobalValue::PrivateLinkage, Init,
Name);
3580 if (!Section.empty())
3581 GV->setSection(Section);
3588 llvm::Function *CGObjCMac::ModuleInitFunction() {
3594 llvm::Constant *CGObjCMac::GetPropertyGetFunction() {
3595 return ObjCTypes.getGetPropertyFn();
3598 llvm::Constant *CGObjCMac::GetPropertySetFunction() {
3599 return ObjCTypes.getSetPropertyFn();
3602 llvm::Constant *CGObjCMac::GetOptimizedPropertySetFunction(
bool atomic,
3604 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
3607 llvm::Constant *CGObjCMac::GetGetStructFunction() {
3608 return ObjCTypes.getCopyStructFn();
3610 llvm::Constant *CGObjCMac::GetSetStructFunction() {
3611 return ObjCTypes.getCopyStructFn();
3614 llvm::Constant *CGObjCMac::GetCppAtomicObjectGetFunction() {
3615 return ObjCTypes.getCppAtomicObjectFunction();
3617 llvm::Constant *CGObjCMac::GetCppAtomicObjectSetFunction() {
3618 return ObjCTypes.getCppAtomicObjectFunction();
3621 llvm::Constant *CGObjCMac::EnumerationMutationFunction() {
3622 return ObjCTypes.getEnumerationMutationFn();
3626 return EmitTryOrSynchronizedStmt(CGF, S);
3631 return EmitTryOrSynchronizedStmt(CGF, S);
3640 ObjCTypesHelper &ObjCTypes;
3641 PerformFragileFinally(
const Stmt *
S,
3645 ObjCTypesHelper *ObjCTypes)
3646 : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
3647 ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
3652 llvm::BasicBlock *FinallyCallExit =
3654 llvm::BasicBlock *FinallyNoCallExit =
3657 FinallyCallExit, FinallyNoCallExit);
3661 ExceptionData.getPointer());
3665 if (isa<ObjCAtTryStmt>(
S)) {
3667 cast<ObjCAtTryStmt>(
S).getFinallyStmt()) {
3669 if (flags.isForEHCleanup())
return;
3676 CGF.
EmitStmt(FinallyStmt->getFinallyBody());
3695 class FragileHazards {
3700 llvm::InlineAsm *ReadHazard;
3701 llvm::InlineAsm *WriteHazard;
3703 llvm::FunctionType *GetAsmFnType();
3705 void collectLocals();
3711 void emitWriteHazard();
3712 void emitHazardsInNewBlocks();
3724 if (Locals.empty())
return;
3729 BlocksBeforeTry.insert(&*I);
3731 llvm::FunctionType *AsmFnTy = GetAsmFnType();
3739 std::string Constraint;
3740 for (
unsigned I = 0,
E = Locals.size(); I !=
E; ++
I) {
3741 if (I) Constraint +=
',';
3745 ReadHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
3753 std::string Constraint;
3754 for (
unsigned I = 0,
E = Locals.size(); I !=
E; ++
I) {
3755 if (I) Constraint +=
',';
3756 Constraint +=
"=*m";
3759 WriteHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
3764 void FragileHazards::emitWriteHazard() {
3765 if (Locals.empty())
return;
3771 assert(!Locals.empty());
3772 llvm::CallInst *call = Builder.CreateCall(ReadHazard, Locals);
3773 call->setDoesNotThrow();
3779 void FragileHazards::emitHazardsInNewBlocks() {
3780 if (Locals.empty())
return;
3786 FI = CGF.
CurFn->begin(), FE = CGF.
CurFn->end(); FI != FE; ++FI) {
3787 llvm::BasicBlock &BB = *FI;
3788 if (BlocksBeforeTry.count(&BB))
continue;
3792 BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) {
3793 llvm::Instruction &I = *BI;
3797 if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(
I))
continue;
3798 if (isa<llvm::IntrinsicInst>(I))
3803 llvm::CallSite CS(&I);
3804 if (CS.doesNotThrow())
continue;
3811 Builder.SetInsertPoint(&BB, BI);
3812 emitReadHazard(Builder);
3825 void FragileHazards::collectLocals() {
3833 llvm::BasicBlock &Entry = CGF.
CurFn->getEntryBlock();
3835 I = Entry.begin(),
E = Entry.end(); I !=
E; ++
I)
3836 if (isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I))
3837 Locals.push_back(&*I);
3840 llvm::FunctionType *FragileHazards::GetAsmFnType() {
3842 for (
unsigned i = 0, e = Locals.size(); i != e; ++i)
3843 tys[i] = Locals[i]->getType();
3844 return llvm::FunctionType::get(CGF.
VoidTy, tys,
false);
3961 bool isTry = isa<ObjCAtTryStmt>(
S);
3978 Address SyncArgSlot = Address::invalid();
3981 CGF.
EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
3994 "exceptiondata.ptr");
4000 FragileHazards Hazards(CGF);
4016 Address PropagatingExnVar = Address::invalid();
4029 ExceptionData.getPointer());
4032 llvm::Constant *Zero = llvm::ConstantInt::get(CGF.
Builder.getInt32Ty(), 0);
4035 ObjCTypes.ExceptionDataTy, ExceptionData.getPointer(), GEPIndexes,
4038 ObjCTypes.getSetJmpFn(), SetJmpBuffer,
"setjmp_result");
4039 SetJmpResult->setCanReturnTwice();
4046 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
4047 CGF.
Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
4052 CGF.
EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
4053 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
4055 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.
Builder.saveAndClearIP();
4061 Hazards.emitWriteHazard();
4065 if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
4074 llvm::CallInst *Caught =
4076 ExceptionData.getPointer(),
"caught");
4086 llvm::BasicBlock *CatchBlock =
nullptr;
4087 llvm::BasicBlock *CatchHandler =
nullptr;
4093 "propagating_exception");
4099 ExceptionData.getPointer());
4101 llvm::CallInst *SetJmpResult =
4103 SetJmpBuffer,
"setjmp.result");
4104 SetJmpResult->setCanReturnTwice();
4107 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
4111 CGF.
Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
4121 bool AllMatched =
false;
4151 EmitInitOfCatchParam(CGF, Caught, CatchParam);
4157 CatchVarCleanups.ForceCleanup();
4163 assert(OPT &&
"Unexpected non-object pointer type in @catch");
4168 assert(IDecl &&
"Catch parameter must have Objective-C type!");
4174 llvm::CallInst *Match =
4176 matchArgs,
"match");
4181 CGF.
Builder.CreateCondBr(CGF.
Builder.CreateIsNotNull(Match,
"matched"),
4182 MatchedBlock, NextCatchBlock);
4198 EmitInitOfCatchParam(CGF, Tmp, CatchParam);
4203 CatchVarCleanups.ForceCleanup();
4214 if (Caught->use_empty())
4215 Caught->eraseFromParent();
4231 assert(PropagatingExnVar.
isValid());
4232 llvm::CallInst *NewCaught =
4234 ExceptionData.getPointer(),
"caught");
4244 Hazards.emitHazardsInNewBlocks();
4247 CGF.
Builder.restoreIP(TryFallthroughIP);
4251 CGF.
EmitBlock(FinallyEnd.getBlock(),
true);
4254 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
4259 if (PropagatingExnVar.
isValid()) {
4264 llvm::CallInst *Caught =
4266 ExceptionData.getPointer());
4267 PropagatingExn = Caught;
4272 CGF.
Builder.CreateUnreachable();
4275 CGF.
Builder.restoreIP(SavedIP);
4280 bool ClearInsertionPoint) {
4289 "Unexpected rethrow outside @catch block.");
4293 CGF.
EmitRuntimeCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
4294 ->setDoesNotReturn();
4295 CGF.
Builder.CreateUnreachable();
4298 if (ClearInsertionPoint)
4299 CGF.
Builder.ClearInsertionPoint();
4309 ObjCTypes.PtrObjectPtrTy);
4322 llvm::Type * SrcTy = src->
getType();
4323 if (!isa<llvm::PointerType>(SrcTy)) {
4324 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(SrcTy);
4325 assert(Size <= 8 && "does not support size > 8
");
4326 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
4327 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
4328 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4330 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4331 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4332 llvm::Value *args[] = { src, dst.getPointer() };
4333 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(),
4334 args, "weakassign
");
4341 void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
4342 llvm::Value *src, Address dst,
4344 llvm::Type * SrcTy = src->getType();
4345 if (!isa<llvm::PointerType>(SrcTy)) {
4346 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4347 assert(Size <= 8 && "does
not support size > 8
");
4348 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
4349 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
4350 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4352 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4353 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4354 llvm::Value *args[] = { src, dst.getPointer() };
4356 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(),
4357 args, "globalassign
");
4359 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(),
4360 args, "threadlocalassign
");
4367 void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
4368 llvm::Value *src, Address dst,
4369 llvm::Value *ivarOffset) {
4370 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is
NULL");
4371 llvm::Type * SrcTy = src->getType();
4372 if (!isa<llvm::PointerType>(SrcTy)) {
4373 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4374 assert(Size <= 8 && "does
not support size > 8
");
4375 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
4376 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
4377 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4379 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4380 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4381 llvm::Value *args[] = { src, dst.getPointer(), ivarOffset };
4382 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
4389 void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
4390 llvm::Value *src, Address dst) {
4391 llvm::Type * SrcTy = src->getType();
4392 if (!isa<llvm::PointerType>(SrcTy)) {
4393 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4394 assert(Size <= 8 && "does
not support size > 8
");
4395 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
4396 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
4397 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4399 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4400 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4401 llvm::Value *args[] = { src, dst.getPointer() };
4402 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(),
4403 args, "strongassign
");
4407 void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
4410 llvm::Value *size) {
4411 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
4412 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
4413 llvm::Value *args[] = { DestPtr.getPointer(), SrcPtr.getPointer(), size };
4414 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
4419 LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
4421 llvm::Value *BaseValue,
4422 const ObjCIvarDecl *Ivar,
4423 unsigned CVRQualifiers) {
4424 const ObjCInterfaceDecl *ID =
4425 ObjectTy->getAs<ObjCObjectType>()->getInterface();
4426 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
4427 EmitIvarOffset(CGF, ID, Ivar));
4430 llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
4431 const ObjCInterfaceDecl *Interface,
4432 const ObjCIvarDecl *Ivar) {
4433 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
4434 return llvm::ConstantInt::get(
4435 CGM.getTypes().ConvertType(CGM.getContext().LongTy),
4439 /* *** Private Interface *** */
4449 enum ImageInfoFlags {
4450 eImageInfo_FixAndContinue = (1 << 0), // This flag is no longer set by clang.
4451 eImageInfo_GarbageCollected = (1 << 1),
4452 eImageInfo_GCOnly = (1 << 2),
4453 eImageInfo_OptimizedByDyld = (1 << 3), // This flag is set by the dyld shared cache.
4455 // A flag indicating that the module has no instances of a @synthesize of a
4456 // superclass variable. <rdar://problem/6803242>
4457 eImageInfo_CorrectedSynthesize = (1 << 4), // This flag is no longer set by clang.
4458 eImageInfo_ImageIsSimulated = (1 << 5)
4461 void CGObjCCommonMac::EmitImageInfo() {
4462 unsigned version = 0; // Version is unused?
4463 const char *Section = (ObjCABI == 1) ?
4464 "__OBJC, __image_info,regular
" :
4465 "__DATA, __objc_imageinfo, regular, no_dead_strip
";
4467 // Generate module-level named metadata to convey this information to the
4468 // linker and code-gen.
4469 llvm::Module &Mod = CGM.getModule();
4471 // Add the ObjC ABI version to the module flags.
4472 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Version
", ObjCABI);
4473 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Version
",
4475 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Section
",
4476 llvm::MDString::get(VMContext,Section));
4478 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
4479 // Non-GC overrides those files which specify GC.
4480 Mod.addModuleFlag(llvm::Module::Override,
4481 "Objective-C Garbage Collection
", (uint32_t)0);
4483 // Add the ObjC garbage collection value.
4484 Mod.addModuleFlag(llvm::Module::Error,
4485 "Objective-C Garbage Collection
",
4486 eImageInfo_GarbageCollected);
4488 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
4489 // Add the ObjC GC Only value.
4490 Mod.addModuleFlag(llvm::Module::Error, "Objective-C GC Only
",
4493 // Require that GC be specified and set to eImageInfo_GarbageCollected.
4494 llvm::Metadata *Ops[2] = {
4495 llvm::MDString::get(VMContext, "Objective-C Garbage Collection
"),
4496 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
4497 llvm::Type::getInt32Ty(VMContext), eImageInfo_GarbageCollected))};
4498 Mod.addModuleFlag(llvm::Module::Require, "Objective-C GC Only
",
4499 llvm::MDNode::get(VMContext, Ops));
4503 // Indicate whether we're compiling this to run on a simulator.
4504 const llvm::Triple &Triple = CGM.getTarget().getTriple();
4505 if ((Triple.isiOS() || Triple.isWatchOS()) &&
4506 (Triple.getArch() == llvm::Triple::x86 ||
4507 Triple.getArch() == llvm::Triple::x86_64))
4508 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Is Simulated
",
4509 eImageInfo_ImageIsSimulated);
4512 // struct objc_module {
4513 // unsigned long version;
4514 // unsigned long size;
4515 // const char *name;
4519 // FIXME: Get from somewhere
4520 static const int ModuleVersion = 7;
4522 void CGObjCMac::EmitModuleInfo() {
4523 uint64_t Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ModuleTy);
4525 llvm::Constant *Values[] = {
4526 llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion),
4527 llvm::ConstantInt::get(ObjCTypes.LongTy, Size),
4528 // This used to be the filename, now it is unused. <rdr://4327263>
4529 GetClassName(StringRef("")),
4532 CreateMetadataVar("OBJC_MODULES
",
4533 llvm::ConstantStruct::get(ObjCTypes.ModuleTy, Values),
4534 "__OBJC,__module_info,regular,no_dead_strip
",
4535 CGM.getPointerAlign(), true);
4538 llvm::Constant *CGObjCMac::EmitModuleSymbols() {
4539 unsigned NumClasses = DefinedClasses.size();
4540 unsigned NumCategories = DefinedCategories.size();
4542 // Return null if no symbols were defined.
4543 if (!NumClasses && !NumCategories)
4544 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
4546 llvm::Constant *Values[5];
4547 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
4548 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
4549 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
4550 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
4552 // The runtime expects exactly the list of defined classes followed
4553 // by the list of defined categories, in a single array.
4554 SmallVector<llvm::Constant*, 8> Symbols(NumClasses + NumCategories);
4555 for (unsigned i=0; i<NumClasses; i++) {
4556 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
4558 if (ObjCImplementationDecl *IMP = ID->getImplementation())
4559 // We are implementing a weak imported interface. Give it external linkage
4560 if (ID->isWeakImported() && !IMP->isWeakImported())
4561 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
4563 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
4564 ObjCTypes.Int8PtrTy);
4566 for (unsigned i=0; i<NumCategories; i++)
4567 Symbols[NumClasses + i] =
4568 llvm::ConstantExpr::getBitCast(DefinedCategories[i],
4569 ObjCTypes.Int8PtrTy);
4572 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
4576 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
4578 llvm::GlobalVariable *GV = CreateMetadataVar(
4579 "OBJC_SYMBOLS
", Init, "__OBJC,__symbols,regular,no_dead_strip
",
4580 CGM.getPointerAlign(), true);
4581 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
4584 llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF,
4585 IdentifierInfo *II) {
4586 LazySymbols.insert(II);
4588 llvm::GlobalVariable *&Entry = ClassReferences[II];
4591 llvm::Constant *Casted =
4592 llvm::ConstantExpr::getBitCast(GetClassName(II->getName()),
4593 ObjCTypes.ClassPtrTy);
4594 Entry = CreateMetadataVar(
4595 "OBJC_CLASS_REFERENCES_
", Casted,
4596 "__OBJC,__cls_refs,literal_pointers,no_dead_strip
",
4597 CGM.getPointerAlign(), true);
4600 return CGF.Builder.CreateAlignedLoad(Entry, CGF.getPointerAlign());
4603 llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF,
4604 const ObjCInterfaceDecl *ID) {
4605 return EmitClassRefFromId(CGF, ID->getIdentifier());
4608 llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
4609 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool
");
4610 return EmitClassRefFromId(CGF, II);
4613 llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel) {
4614 return CGF.Builder.CreateLoad(EmitSelectorAddr(CGF, Sel));
4617 Address CGObjCMac::EmitSelectorAddr(CodeGenFunction &CGF, Selector Sel) {
4618 CharUnits Align = CGF.getPointerAlign();
4620 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
4622 llvm::Constant *Casted =
4623 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
4624 ObjCTypes.SelectorPtrTy);
4625 Entry = CreateMetadataVar(
4626 "OBJC_SELECTOR_REFERENCES_
", Casted,
4627 "__OBJC,__message_refs,literal_pointers,no_dead_strip
", Align, true);
4628 Entry->setExternallyInitialized(true);
4631 return Address(Entry, Align);
4634 llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) {
4635 llvm::GlobalVariable *&Entry = ClassNames[RuntimeName];
4637 Entry = CreateMetadataVar(
4639 llvm::ConstantDataArray::getString(VMContext, RuntimeName),
4640 ((ObjCABI == 2) ? "__TEXT,__objc_classname,cstring_literals
"
4641 : "__TEXT,__cstring,cstring_literals
"),
4642 CharUnits::One(), true);
4643 return getConstantGEP(VMContext, Entry, 0, 0);
4646 llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
4647 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*>::iterator
4648 I = MethodDefinitions.find(MD);
4649 if (I != MethodDefinitions.end())
4657 llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
4658 const ObjCCommonTypesHelper &ObjCTypes) {
4659 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
4662 void IvarLayoutBuilder::visitRecord(const RecordType *RT,
4664 const RecordDecl *RD = RT->getDecl();
4666 // If this is a union, remember that we had one, because it might mess
4667 // up the ordering of layout entries.
4669 IsDisordered = true;
4671 const ASTRecordLayout *recLayout = nullptr;
4672 visitAggregate(RD->field_begin(), RD->field_end(), offset,
4673 [&](const FieldDecl *field) -> CharUnits {
4675 recLayout = &CGM.getContext().getASTRecordLayout(RD);
4676 auto offsetInBits = recLayout->getFieldOffset(field->getFieldIndex());
4677 return CGM.getContext().toCharUnitsFromBits(offsetInBits);
4681 template <class Iterator, class GetOffsetFn>
4682 void IvarLayoutBuilder::visitAggregate(Iterator begin, Iterator end,
4683 CharUnits aggregateOffset,
4684 const GetOffsetFn &getOffset) {
4685 for (; begin != end; ++begin) {
4686 auto field = *begin;
4688 // Skip over bitfields.
4689 if (field->isBitField()) {
4693 // Compute the offset of the field within the aggregate.
4694 CharUnits fieldOffset = aggregateOffset + getOffset(field);
4696 visitField(field, fieldOffset);
4701 void IvarLayoutBuilder::visitField(const FieldDecl *field,
4702 CharUnits fieldOffset) {
4703 QualType fieldType = field->getType();
4705 // Drill down into arrays.
4706 uint64_t numElts = 1;
4707 while (auto arrayType = CGM.getContext().getAsConstantArrayType(fieldType)) {
4708 numElts *= arrayType->getSize().getZExtValue();
4709 fieldType = arrayType->getElementType();
4712 assert(!fieldType->isArrayType() && "ivar of non-constant array type?
");
4714 // If we ended up with a zero-sized array, we've done what we can do within
4715 // the limits of this layout encoding.
4716 if (numElts == 0) return;
4718 // Recurse if the base element type is a record type.
4719 if (auto recType = fieldType->getAs<RecordType>()) {
4720 size_t oldEnd = IvarsInfo.size();
4722 visitRecord(recType, fieldOffset);
4724 // If we have an array, replicate the first entry's layout information.
4725 auto numEltEntries = IvarsInfo.size() - oldEnd;
4726 if (numElts != 1 && numEltEntries != 0) {
4727 CharUnits eltSize = CGM.getContext().getTypeSizeInChars(recType);
4728 for (uint64_t eltIndex = 1; eltIndex != numElts; ++eltIndex) {
4729 // Copy the last numEltEntries onto the end of the array, adjusting
4730 // each for the element size.
4731 for (size_t i = 0; i != numEltEntries; ++i) {
4732 auto firstEntry = IvarsInfo[oldEnd + i];
4733 IvarsInfo.push_back(IvarInfo(firstEntry.Offset + eltIndex * eltSize,
4734 firstEntry.SizeInWords));
4742 // Classify the element type.
4743 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), fieldType);
4745 // If it matches what we're looking for, add an entry.
4746 if ((ForStrongLayout && GCAttr == Qualifiers::Strong)
4747 || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
4748 assert(CGM.getContext().getTypeSizeInChars(fieldType)
4749 == CGM.getPointerSize());
4750 IvarsInfo.push_back(IvarInfo(fieldOffset, numElts));
4757 llvm::Constant *IvarLayoutBuilder::buildBitmap(CGObjCCommonMac &CGObjC,
4758 llvm::SmallVectorImpl<unsigned char> &buffer) {
4759 // The bitmap is a series of skip/scan instructions, aligned to word
4760 // boundaries. The skip is performed first.
4761 const unsigned char MaxNibble = 0xF;
4762 const unsigned char SkipMask = 0xF0, SkipShift = 4;
4763 const unsigned char ScanMask = 0x0F, ScanShift = 0;
4765 assert(!IvarsInfo.empty() && "generating bitmap
for no data
");
4767 // Sort the ivar info on byte position in case we encounterred a
4768 // union nested in the ivar list.
4770 // This isn't a stable sort, but our algorithm should handle it fine.
4771 llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end());
4773 assert(std::is_sorted(IvarsInfo.begin(), IvarsInfo.end()));
4775 assert(IvarsInfo.back().Offset < InstanceEnd);
4777 assert(buffer.empty());
4779 // Skip the next N words.
4780 auto skip = [&](unsigned numWords) {
4781 assert(numWords > 0);
4783 // Try to merge into the previous byte. Since scans happen second, we
4784 // can't do this if it includes a scan.
4785 if (!buffer.empty() && !(buffer.back() & ScanMask)) {
4786 unsigned lastSkip = buffer.back() >> SkipShift;
4787 if (lastSkip < MaxNibble) {
4788 unsigned claimed = std::min(MaxNibble - lastSkip, numWords);
4789 numWords -= claimed;
4790 lastSkip += claimed;
4791 buffer.back() = (lastSkip << SkipShift);
4795 while (numWords >= MaxNibble) {
4796 buffer.push_back(MaxNibble << SkipShift);
4797 numWords -= MaxNibble;
4800 buffer.push_back(numWords << SkipShift);
4804 // Scan the next N words.
4805 auto scan = [&](unsigned numWords) {
4806 assert(numWords > 0);
4808 // Try to merge into the previous byte. Since scans happen second, we can
4809 // do this even if it includes a skip.
4810 if (!buffer.empty()) {
4811 unsigned lastScan = (buffer.back() & ScanMask) >> ScanShift;
4812 if (lastScan < MaxNibble) {
4813 unsigned claimed = std::min(MaxNibble - lastScan, numWords);
4814 numWords -= claimed;
4815 lastScan += claimed;
4816 buffer.back() = (buffer.back() & SkipMask) | (lastScan << ScanShift);
4820 while (numWords >= MaxNibble) {
4821 buffer.push_back(MaxNibble << ScanShift);
4822 numWords -= MaxNibble;
4825 buffer.push_back(numWords << ScanShift);
4829 // One past the end of the last scan.
4830 unsigned endOfLastScanInWords = 0;
4831 const CharUnits WordSize = CGM.getPointerSize();
4833 // Consider all the scan requests.
4834 for (auto &request : IvarsInfo) {
4835 CharUnits beginOfScan = request.Offset - InstanceBegin;
4837 // Ignore scan requests that don't start at an even multiple of the
4838 // word size. We can't encode them.
4839 if ((beginOfScan % WordSize) != 0) continue;
4841 // Ignore scan requests that start before the instance start.
4842 // This assumes that scans never span that boundary. The boundary
4843 // isn't the true start of the ivars, because in the fragile-ARC case
4844 // it's rounded up to word alignment, but the test above should leave
4845 // us ignoring that possibility.
4846 if (beginOfScan.isNegative()) {
4847 assert(request.Offset + request.SizeInWords * WordSize <= InstanceBegin);
4851 unsigned beginOfScanInWords = beginOfScan / WordSize;
4852 unsigned endOfScanInWords = beginOfScanInWords + request.SizeInWords;
4854 // If the scan starts some number of words after the last one ended,
4856 if (beginOfScanInWords > endOfLastScanInWords) {
4857 skip(beginOfScanInWords - endOfLastScanInWords);
4859 // Otherwise, start scanning where the last left off.
4861 beginOfScanInWords = endOfLastScanInWords;
4863 // If that leaves us with nothing to scan, ignore this request.
4864 if (beginOfScanInWords >= endOfScanInWords) continue;
4867 // Scan to the end of the request.
4868 assert(beginOfScanInWords < endOfScanInWords);
4869 scan(endOfScanInWords - beginOfScanInWords);
4870 endOfLastScanInWords = endOfScanInWords;
4874 return llvm::ConstantPointerNull::get(CGM.Int8PtrTy);
4876 // For GC layouts, emit a skip to the end of the allocation so that we
4877 // have precise information about the entire thing. This isn't useful
4878 // or necessary for the ARC-style layout strings.
4879 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
4880 unsigned lastOffsetInWords =
4881 (InstanceEnd - InstanceBegin + WordSize - CharUnits::One()) / WordSize;
4882 if (lastOffsetInWords > endOfLastScanInWords) {
4883 skip(lastOffsetInWords - endOfLastScanInWords);
4887 // Null terminate the string.
4888 buffer.push_back(0);
4890 bool isNonFragileABI = CGObjC.isNonFragileABI();
4892 llvm::GlobalVariable *Entry = CGObjC.CreateMetadataVar(
4894 llvm::ConstantDataArray::get(CGM.getLLVMContext(), buffer),
4895 (isNonFragileABI ? "__TEXT,__objc_classname,cstring_literals
"
4896 : "__TEXT,__cstring,cstring_literals
"),
4897 CharUnits::One(), true);
4898 return getConstantGEP(CGM.getLLVMContext(), Entry, 0, 0);
4918 CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD,
4919 CharUnits beginOffset, CharUnits endOffset,
4920 bool ForStrongLayout, bool HasMRCWeakIvars) {
4921 // If this is MRC, and we're either building a strong layout or there
4922 // are no weak ivars, bail out early.
4923 llvm::Type *PtrTy = CGM.Int8PtrTy;
4924 if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
4925 !CGM.getLangOpts().ObjCAutoRefCount &&
4926 (ForStrongLayout || !HasMRCWeakIvars))
4927 return llvm::Constant::getNullValue(PtrTy);
4929 const ObjCInterfaceDecl *OI = OMD->getClassInterface();
4930 SmallVector<const ObjCIvarDecl*, 32> ivars;
4932 // GC layout strings include the complete object layout, possibly
4933 // inaccurately in the non-fragile ABI; the runtime knows how to fix this
4936 // ARC layout strings only include the class's ivars. In non-fragile
4937 // runtimes, that means starting at InstanceStart, rounded up to word
4938 // alignment. In fragile runtimes, there's no InstanceStart, so it means
4939 // starting at the offset of the first ivar, rounded up to word alignment.
4941 // MRC weak layout strings follow the ARC style.
4942 CharUnits baseOffset;
4943 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
4944 for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();
4945 IVD; IVD = IVD->getNextIvar())
4946 ivars.push_back(IVD);
4948 if (isNonFragileABI()) {
4949 baseOffset = beginOffset; // InstanceStart
4950 } else if (!ivars.empty()) {
4952 CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivars[0]));
4954 baseOffset = CharUnits::Zero();
4957 baseOffset = baseOffset.RoundUpToAlignment(CGM.getPointerAlign());
4960 CGM.getContext().DeepCollectObjCIvars(OI, true, ivars);
4962 baseOffset = CharUnits::Zero();
4966 return llvm::Constant::getNullValue(PtrTy);
4968 IvarLayoutBuilder builder(CGM, baseOffset, endOffset, ForStrongLayout);
4970 builder.visitAggregate(ivars.begin(), ivars.end(), CharUnits::Zero(),
4971 [&](const ObjCIvarDecl *ivar) -> CharUnits {
4972 return CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivar));
4975 if (!builder.hasBitmapData())
4976 return llvm::Constant::getNullValue(PtrTy);
4978 llvm::SmallVector<unsigned char, 4> buffer;
4979 llvm::Constant *C = builder.buildBitmap(*this, buffer);
4981 if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
4982 printf("\n%s ivar layout
for class '%s':
",
4983 ForStrongLayout ? "strong
" : "weak
",
4984 OMD->getClassInterface()->getName().str().c_str());
4985 builder.dump(buffer);
4990 llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
4991 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
4993 // FIXME: Avoid std::string in "Sel.
getAsString()
"
4995 Entry = CreateMetadataVar(
4996 "OBJC_METH_VAR_NAME_
",
4997 llvm::ConstantDataArray::getString(VMContext, Sel.getAsString()),
4998 ((ObjCABI == 2) ? "__TEXT,__objc_methname,cstring_literals
"
4999 : "__TEXT,__cstring,cstring_literals
"),
5000 CharUnits::One(), true);
5002 return getConstantGEP(VMContext, Entry, 0, 0);
5005 // FIXME: Merge into a single cstring creation function.
5006 llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
5007 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
5010 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
5011 std::string TypeStr;
5012 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
5014 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
5017 Entry = CreateMetadataVar(
5018 "OBJC_METH_VAR_TYPE_
",
5019 llvm::ConstantDataArray::getString(VMContext, TypeStr),
5020 ((ObjCABI == 2) ? "__TEXT,__objc_methtype,cstring_literals
"
5021 : "__TEXT,__cstring,cstring_literals
"),
5022 CharUnits::One(), true);
5024 return getConstantGEP(VMContext, Entry, 0, 0);
5027 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D,
5029 std::string TypeStr;
5030 if (CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr, Extended))
5033 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
5036 Entry = CreateMetadataVar(
5037 "OBJC_METH_VAR_TYPE_
",
5038 llvm::ConstantDataArray::getString(VMContext, TypeStr),
5039 ((ObjCABI == 2) ? "__TEXT,__objc_methtype,cstring_literals
"
5040 : "__TEXT,__cstring,cstring_literals
"),
5041 CharUnits::One(), true);
5043 return getConstantGEP(VMContext, Entry, 0, 0);
5046 // FIXME: Merge into a single cstring creation function.
5047 llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
5048 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
5051 Entry = CreateMetadataVar(
5052 "OBJC_PROP_NAME_ATTR_
",
5053 llvm::ConstantDataArray::getString(VMContext, Ident->getName()),
5054 "__TEXT,__cstring,cstring_literals
", CharUnits::One(), true);
5056 return getConstantGEP(VMContext, Entry, 0, 0);
5059 // FIXME: Merge into a single cstring creation function.
5060 // FIXME: This Decl should be more precise.
5062 CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
5063 const Decl *Container) {
5064 std::string TypeStr;
5065 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr);
5066 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
5069 void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D,
5070 const ObjCContainerDecl *CD,
5071 SmallVectorImpl<char> &Name) {
5072 llvm::raw_svector_ostream OS(Name);
5073 assert (CD && "Missing container
decl in GetNameForMethod
");
5074 OS << '\01' << (D->isInstanceMethod() ? '-' : '+')
5075 << '[' << CD->getName();
5076 if (const ObjCCategoryImplDecl *CID =
5077 dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
5078 OS << '(' << *CID << ')';
5079 OS << ' ' << D->getSelector().getAsString() << ']';
5082 void CGObjCMac::FinishModule() {
5085 // Emit the dummy bodies for any protocols which were referenced but
5087 for (llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*>::iterator
5088 I = Protocols.begin(), e = Protocols.end(); I != e; ++I) {
5089 if (I->second->hasInitializer())
5092 llvm::Constant *Values[5];
5093 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
5094 Values[1] = GetClassName(I->first->getName());
5095 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
5096 Values[3] = Values[4] =
5097 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
5098 I->second->setInitializer(llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
5100 CGM.addCompilerUsedGlobal(I->second);
5103 // Add assembler directives to add lazy undefined symbol references
5104 // for classes which are referenced but not defined. This is
5105 // important for correct linker interaction.
5107 // FIXME: It would be nice if we had an LLVM construct for this.
5108 if (!LazySymbols.empty() || !DefinedSymbols.empty()) {
5109 SmallString<256> Asm;
5110 Asm += CGM.getModule().getModuleInlineAsm();
5111 if (!Asm.empty() && Asm.back() != '\n')
5114 llvm::raw_svector_ostream OS(Asm);
5115 for (llvm::SetVector<IdentifierInfo*>::iterator I = DefinedSymbols.begin(),
5116 e = DefinedSymbols.end(); I != e; ++I)
5117 OS << "\t.objc_class_name_
" << (*I)->getName() << "=0\n
"
5118 << "\t.globl .objc_class_name_
" << (*I)->getName() << "\n
";
5119 for (llvm::SetVector<IdentifierInfo*>::iterator I = LazySymbols.begin(),
5120 e = LazySymbols.end(); I != e; ++I) {
5121 OS << "\t.lazy_reference .objc_class_name_
" << (*I)->getName() << "\n
";
5124 for (size_t i = 0, e = DefinedCategoryNames.size(); i < e; ++i) {
5125 OS << "\t.objc_category_name_
" << DefinedCategoryNames[i] << "=0\n
"
5126 << "\t.globl .objc_category_name_
" << DefinedCategoryNames[i] << "\n
";
5129 CGM.getModule().setModuleInlineAsm(OS.str());
5133 CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
5134 : CGObjCCommonMac(cgm),
5136 ObjCEmptyCacheVar = ObjCEmptyVtableVar = nullptr;
5142 ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
5143 : VMContext(cgm.getLLVMContext()), CGM(cgm), ExternalProtocolPtrTy(nullptr)
5145 CodeGen::CodeGenTypes &Types = CGM.getTypes();
5146 ASTContext &Ctx = CGM.getContext();
5148 ShortTy = Types.ConvertType(Ctx.ShortTy);
5149 IntTy = Types.ConvertType(Ctx.IntTy);
5150 LongTy = Types.ConvertType(Ctx.LongTy);
5151 LongLongTy = Types.ConvertType(Ctx.LongLongTy);
5152 Int8PtrTy = CGM.Int8PtrTy;
5153 Int8PtrPtrTy = CGM.Int8PtrPtrTy;
5155 // arm64 targets use "int" ivar offset variables. All others,
5156 // including OS X x86_64 and Windows x86_64, use "long" ivar offsets.
5157 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::aarch64)
5158 IvarOffsetVarTy = IntTy;
5160 IvarOffsetVarTy = LongTy;
5162 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
5163 PtrObjectPtrTy = llvm::PointerType::getUnqual(ObjectPtrTy);
5164 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
5166 // I'm not sure I like this. The implicit coordination is a bit
5167 // gross. We should solve this in a reasonable fashion because this
5168 // is a pretty common task (match some runtime data structure with
5169 // an LLVM data structure).
5171 // FIXME: This is leaked.
5172 // FIXME: Merge with rewriter code?
5174 // struct _objc_super {
5178 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
5179 Ctx.getTranslationUnitDecl(),
5180 SourceLocation(), SourceLocation(),
5181 &Ctx.Idents.get("_objc_super
"));
5182 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5183 nullptr, Ctx.getObjCIdType(), nullptr, nullptr,
5184 false, ICIS_NoInit));
5185 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5186 nullptr, Ctx.getObjCClassType(), nullptr,
5187 nullptr, false, ICIS_NoInit));
5188 RD->completeDefinition();
5190 SuperCTy = Ctx.getTagDeclType(RD);
5191 SuperPtrCTy = Ctx.getPointerType(SuperCTy);
5193 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
5194 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
5198 // char *attributes;
5200 PropertyTy = llvm::StructType::create("struct._prop_t
",
5201 Int8PtrTy, Int8PtrTy, nullptr);
5203 // struct _prop_list_t {
5204 // uint32_t entsize; // sizeof(struct _prop_t)
5205 // uint32_t count_of_properties;
5206 // struct _prop_t prop_list[count_of_properties];
5209 llvm::StructType::create("struct._prop_list_t
", IntTy, IntTy,
5210 llvm::ArrayType::get(PropertyTy, 0), nullptr);
5211 // struct _prop_list_t *
5212 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
5214 // struct _objc_method {
5216 // char *method_type;
5219 MethodTy = llvm::StructType::create("struct._objc_method
",
5220 SelectorPtrTy, Int8PtrTy, Int8PtrTy,
5223 // struct _objc_cache *
5224 CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache
");
5225 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
5229 ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
5230 : ObjCCommonTypesHelper(cgm) {
5231 // struct _objc_method_description {
5235 MethodDescriptionTy =
5236 llvm::StructType::create("struct._objc_method_description
",
5237 SelectorPtrTy, Int8PtrTy, nullptr);
5239 // struct _objc_method_description_list {
5241 // struct _objc_method_description[1];
5243 MethodDescriptionListTy = llvm::StructType::create(
5244 "struct._objc_method_description_list
", IntTy,
5245 llvm::ArrayType::get(MethodDescriptionTy, 0), nullptr);
5247 // struct _objc_method_description_list *
5248 MethodDescriptionListPtrTy =
5249 llvm::PointerType::getUnqual(MethodDescriptionListTy);
5251 // Protocol description structures
5253 // struct _objc_protocol_extension {
5254 // uint32_t size; // sizeof(struct _objc_protocol_extension)
5255 // struct _objc_method_description_list *optional_instance_methods;
5256 // struct _objc_method_description_list *optional_class_methods;
5257 // struct _objc_property_list *instance_properties;
5258 // const char ** extendedMethodTypes;
5260 ProtocolExtensionTy =
5261 llvm::StructType::create("struct._objc_protocol_extension
",
5262 IntTy, MethodDescriptionListPtrTy,
5263 MethodDescriptionListPtrTy, PropertyListPtrTy,
5264 Int8PtrPtrTy, nullptr);
5266 // struct _objc_protocol_extension *
5267 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
5269 // Handle recursive construction of Protocol and ProtocolList types
5272 llvm::StructType::create(VMContext, "struct._objc_protocol
");
5275 llvm::StructType::create(VMContext, "struct._objc_protocol_list
");
5276 ProtocolListTy->setBody(llvm::PointerType::getUnqual(ProtocolListTy),
5278 llvm::ArrayType::get(ProtocolTy, 0),
5281 // struct _objc_protocol {
5282 // struct _objc_protocol_extension *isa;
5283 // char *protocol_name;
5284 // struct _objc_protocol **_objc_protocol_list;
5285 // struct _objc_method_description_list *instance_methods;
5286 // struct _objc_method_description_list *class_methods;
5288 ProtocolTy->setBody(ProtocolExtensionPtrTy, Int8PtrTy,
5289 llvm::PointerType::getUnqual(ProtocolListTy),
5290 MethodDescriptionListPtrTy,
5291 MethodDescriptionListPtrTy,
5294 // struct _objc_protocol_list *
5295 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
5297 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
5299 // Class description structures
5301 // struct _objc_ivar {
5306 IvarTy = llvm::StructType::create("struct._objc_ivar
",
5307 Int8PtrTy, Int8PtrTy, IntTy, nullptr);
5309 // struct _objc_ivar_list *
5311 llvm::StructType::create(VMContext, "struct._objc_ivar_list
");
5312 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
5314 // struct _objc_method_list *
5316 llvm::StructType::create(VMContext, "struct._objc_method_list
");
5317 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
5319 // struct _objc_class_extension *
5321 llvm::StructType::create("struct._objc_class_extension
",
5322 IntTy, Int8PtrTy, PropertyListPtrTy, nullptr);
5323 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
5325 ClassTy = llvm::StructType::create(VMContext, "struct._objc_class
");
5327 // struct _objc_class {
5329 // Class super_class;
5333 // long instance_size;
5334 // struct _objc_ivar_list *ivars;
5335 // struct _objc_method_list *methods;
5336 // struct _objc_cache *cache;
5337 // struct _objc_protocol_list *protocols;
5338 // char *ivar_layout;
5339 // struct _objc_class_ext *ext;
5341 ClassTy->setBody(llvm::PointerType::getUnqual(ClassTy),
5342 llvm::PointerType::getUnqual(ClassTy),
5352 ClassExtensionPtrTy,
5355 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
5357 // struct _objc_category {
5358 // char *category_name;
5359 // char *class_name;
5360 // struct _objc_method_list *instance_method;
5361 // struct _objc_method_list *class_method;
5362 // uint32_t size; // sizeof(struct _objc_category)
5363 // struct _objc_property_list *instance_properties;// category's @property
5366 llvm::StructType::create("struct._objc_category
",
5367 Int8PtrTy, Int8PtrTy, MethodListPtrTy,
5368 MethodListPtrTy, ProtocolListPtrTy,
5369 IntTy, PropertyListPtrTy, nullptr);
5371 // Global metadata structures
5373 // struct _objc_symtab {
5374 // long sel_ref_cnt;
5376 // short cls_def_cnt;
5377 // short cat_def_cnt;
5378 // char *defs[cls_def_cnt + cat_def_cnt];
5381 llvm::StructType::create("struct._objc_symtab
",
5382 LongTy, SelectorPtrTy, ShortTy, ShortTy,
5383 llvm::ArrayType::get(Int8PtrTy, 0), nullptr);
5384 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
5386 // struct _objc_module {
5388 // long size; // sizeof(struct _objc_module)
5390 // struct _objc_symtab* symtab;
5393 llvm::StructType::create("struct._objc_module
",
5394 LongTy, LongTy, Int8PtrTy, SymtabPtrTy, nullptr);
5397 // FIXME: This is the size of the setjmp buffer and should be target
5398 // specific. 18 is what's used on 32-bit X86.
5399 uint64_t SetJmpBufferSize = 18;
5402 llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4);
5405 llvm::StructType::create("struct._objc_exception_data
",
5406 llvm::ArrayType::get(CGM.Int32Ty,SetJmpBufferSize),
5407 StackPtrTy, nullptr);
5411 ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm)
5412 : ObjCCommonTypesHelper(cgm) {
5413 // struct _method_list_t {
5414 // uint32_t entsize; // sizeof(struct _objc_method)
5415 // uint32_t method_count;
5416 // struct _objc_method method_list[method_count];
5419 llvm::StructType::create("struct.__method_list_t
", IntTy, IntTy,
5420 llvm::ArrayType::get(MethodTy, 0), nullptr);
5421 // struct method_list_t *
5422 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy);
5424 // struct _protocol_t {
5426 // const char * const protocol_name;
5427 // const struct _protocol_list_t * protocol_list; // super protocols
5428 // const struct method_list_t * const instance_methods;
5429 // const struct method_list_t * const class_methods;
5430 // const struct method_list_t *optionalInstanceMethods;
5431 // const struct method_list_t *optionalClassMethods;
5432 // const struct _prop_list_t * properties;
5433 // const uint32_t size; // sizeof(struct _protocol_t)
5434 // const uint32_t flags; // = 0
5435 // const char ** extendedMethodTypes;
5436 // const char *demangledName;
5439 // Holder for struct _protocol_list_t *
5440 ProtocolListnfABITy =
5441 llvm::StructType::create(VMContext, "struct._objc_protocol_list
");
5444 llvm::StructType::create("struct._protocol_t
", ObjectPtrTy, Int8PtrTy,
5445 llvm::PointerType::getUnqual(ProtocolListnfABITy),
5446 MethodListnfABIPtrTy, MethodListnfABIPtrTy,
5447 MethodListnfABIPtrTy, MethodListnfABIPtrTy,
5448 PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy,
5452 // struct _protocol_t*
5453 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy);
5455 // struct _protocol_list_t {
5456 // long protocol_count; // Note, this is 32/64 bit
5457 // struct _protocol_t *[protocol_count];
5459 ProtocolListnfABITy->setBody(LongTy,
5460 llvm::ArrayType::get(ProtocolnfABIPtrTy, 0),
5463 // struct _objc_protocol_list*
5464 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy);
5467 // unsigned [long] int *offset; // pointer to ivar offset location
5470 // uint32_t alignment;
5473 IvarnfABITy = llvm::StructType::create(
5474 "struct._ivar_t
", llvm::PointerType::getUnqual(IvarOffsetVarTy),
5475 Int8PtrTy, Int8PtrTy, IntTy, IntTy, nullptr);
5477 // struct _ivar_list_t {
5478 // uint32 entsize; // sizeof(struct _ivar_t)
5480 // struct _iver_t list[count];
5483 llvm::StructType::create("struct._ivar_list_t
", IntTy, IntTy,
5484 llvm::ArrayType::get(IvarnfABITy, 0), nullptr);
5486 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy);
5488 // struct _class_ro_t {
5489 // uint32_t const flags;
5490 // uint32_t const instanceStart;
5491 // uint32_t const instanceSize;
5492 // uint32_t const reserved; // only when building for 64bit targets
5493 // const uint8_t * const ivarLayout;
5494 // const char *const name;
5495 // const struct _method_list_t * const baseMethods;
5496 // const struct _objc_protocol_list *const baseProtocols;
5497 // const struct _ivar_list_t *const ivars;
5498 // const uint8_t * const weakIvarLayout;
5499 // const struct _prop_list_t * const properties;
5502 // FIXME. Add 'reserved' field in 64bit abi mode!
5503 ClassRonfABITy = llvm::StructType::create("struct._class_ro_t
",
5504 IntTy, IntTy, IntTy, Int8PtrTy,
5505 Int8PtrTy, MethodListnfABIPtrTy,
5506 ProtocolListnfABIPtrTy,
5508 Int8PtrTy, PropertyListPtrTy,
5511 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
5512 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
5513 ImpnfABITy = llvm::FunctionType::get(ObjectPtrTy, params, false)
5516 // struct _class_t {
5517 // struct _class_t *isa;
5518 // struct _class_t * const superclass;
5521 // struct class_ro_t *ro;
5524 ClassnfABITy = llvm::StructType::create(VMContext, "struct._class_t
");
5525 ClassnfABITy->setBody(llvm::PointerType::getUnqual(ClassnfABITy),
5526 llvm::PointerType::getUnqual(ClassnfABITy),
5528 llvm::PointerType::getUnqual(ImpnfABITy),
5529 llvm::PointerType::getUnqual(ClassRonfABITy),
5532 // LLVM for struct _class_t *
5533 ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy);
5535 // struct _category_t {
5536 // const char * const name;
5537 // struct _class_t *const cls;
5538 // const struct _method_list_t * const instance_methods;
5539 // const struct _method_list_t * const class_methods;
5540 // const struct _protocol_list_t * const protocols;
5541 // const struct _prop_list_t * const properties;
5543 CategorynfABITy = llvm::StructType::create("struct._category_t
",
5544 Int8PtrTy, ClassnfABIPtrTy,
5545 MethodListnfABIPtrTy,
5546 MethodListnfABIPtrTy,
5547 ProtocolListnfABIPtrTy,
5551 // New types for nonfragile abi messaging.
5552 CodeGen::CodeGenTypes &Types = CGM.getTypes();
5553 ASTContext &Ctx = CGM.getContext();
5555 // MessageRefTy - LLVM for:
5556 // struct _message_ref_t {
5561 // First the clang type for struct _message_ref_t
5562 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
5563 Ctx.getTranslationUnitDecl(),
5564 SourceLocation(), SourceLocation(),
5565 &Ctx.Idents.get("_message_ref_t
"));
5566 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5567 nullptr, Ctx.VoidPtrTy, nullptr, nullptr, false,
5569 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5570 nullptr, Ctx.getObjCSelType(), nullptr, nullptr,
5571 false, ICIS_NoInit));
5572 RD->completeDefinition();
5574 MessageRefCTy = Ctx.getTagDeclType(RD);
5575 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy);
5576 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy));
5578 // MessageRefPtrTy - LLVM for struct _message_ref_t*
5579 MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy);
5581 // SuperMessageRefTy - LLVM for:
5582 // struct _super_message_ref_t {
5583 // SUPER_IMP messenger;
5587 llvm::StructType::create("struct._super_message_ref_t
",
5588 ImpnfABITy, SelectorPtrTy, nullptr);
5590 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
5591 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy);
5594 // struct objc_typeinfo {
5595 // const void** vtable; // objc_ehtype_vtable + 2
5596 // const char* name; // c++ typeinfo string
5600 llvm::StructType::create("struct._objc_typeinfo
",
5601 llvm::PointerType::getUnqual(Int8PtrTy),
5602 Int8PtrTy, ClassnfABIPtrTy, nullptr);
5603 EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy);
5606 llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
5607 FinishNonFragileABIModule();
5612 void CGObjCNonFragileABIMac::
5613 AddModuleClassList(ArrayRef<llvm::GlobalValue*> Container,
5614 const char *SymbolName,
5615 const char *SectionName) {
5616 unsigned NumClasses = Container.size();
5621 SmallVector<llvm::Constant*, 8> Symbols(NumClasses);
5622 for (unsigned i=0; i<NumClasses; i++)
5623 Symbols[i] = llvm::ConstantExpr::getBitCast(Container[i],
5624 ObjCTypes.Int8PtrTy);
5625 llvm::Constant *Init =
5626 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
5630 llvm::GlobalVariable *GV =
5631 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
5632 llvm::GlobalValue::PrivateLinkage,
5635 GV->setAlignment(CGM.getDataLayout().getABITypeAlignment(Init->getType()));
5636 GV->setSection(SectionName);
5637 CGM.addCompilerUsedGlobal(GV);
5640 void CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
5641 // nonfragile abi has no module definition.
5643 // Build list of all implemented class addresses in array
5644 // L_OBJC_LABEL_CLASS_$.
5646 for (unsigned i=0, NumClasses=ImplementedClasses.size(); i<NumClasses; i++) {
5647 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
5649 if (ObjCImplementationDecl *IMP = ID->getImplementation())
5650 // We are implementing a weak imported interface. Give it external linkage
5651 if (ID->isWeakImported() && !IMP->isWeakImported()) {
5652 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
5653 DefinedMetaClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
5657 AddModuleClassList(DefinedClasses, "OBJC_LABEL_CLASS_$
",
5658 "__DATA, __objc_classlist, regular, no_dead_strip
");
5660 AddModuleClassList(DefinedNonLazyClasses, "OBJC_LABEL_NONLAZY_CLASS_$
",
5661 "__DATA, __objc_nlclslist, regular, no_dead_strip
");
5663 // Build list of all implemented category addresses in array
5664 // L_OBJC_LABEL_CATEGORY_$.
5665 AddModuleClassList(DefinedCategories, "OBJC_LABEL_CATEGORY_$
",
5666 "__DATA, __objc_catlist, regular, no_dead_strip
");
5667 AddModuleClassList(DefinedNonLazyCategories, "OBJC_LABEL_NONLAZY_CATEGORY_$
",
5668 "__DATA, __objc_nlcatlist, regular, no_dead_strip
");
5677 bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
5678 // At various points we've experimented with using vtable-based
5679 // dispatch for all methods.
5680 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
5681 case CodeGenOptions::Legacy:
5683 case CodeGenOptions::NonLegacy:
5685 case CodeGenOptions::Mixed:
5689 // If so, see whether this selector is in the white-list of things which must
5690 // use the new dispatch convention. We lazily build a dense set for this.
5691 if (VTableDispatchMethods.empty()) {
5692 VTableDispatchMethods.insert(GetNullarySelector("alloc
"));
5693 VTableDispatchMethods.insert(GetNullarySelector("class"));
5694 VTableDispatchMethods.insert(GetNullarySelector("self"));
5695 VTableDispatchMethods.insert(GetNullarySelector("isFlipped
"));
5696 VTableDispatchMethods.insert(GetNullarySelector("length
"));
5697 VTableDispatchMethods.insert(GetNullarySelector("count
"));
5699 // These are vtable-based if GC is disabled.
5700 // Optimistically use vtable dispatch for hybrid compiles.
5701 if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) {
5702 VTableDispatchMethods.insert(GetNullarySelector("retain
"));
5703 VTableDispatchMethods.insert(GetNullarySelector("release
"));
5704 VTableDispatchMethods.insert(GetNullarySelector("autorelease
"));
5707 VTableDispatchMethods.insert(GetUnarySelector("allocWithZone
"));
5708 VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass
"));
5709 VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector
"));
5710 VTableDispatchMethods.insert(GetUnarySelector("objectForKey
"));
5711 VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex
"));
5712 VTableDispatchMethods.insert(GetUnarySelector("isEqualToString
"));
5713 VTableDispatchMethods.insert(GetUnarySelector("isEqual
"));
5715 // These are vtable-based if GC is enabled.
5716 // Optimistically use vtable dispatch for hybrid compiles.
5717 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
5718 VTableDispatchMethods.insert(GetNullarySelector("hash
"));
5719 VTableDispatchMethods.insert(GetUnarySelector("addObject
"));
5721 // "countByEnumeratingWithState:objects:count
"
5722 IdentifierInfo *KeyIdents[] = {
5723 &CGM.getContext().Idents.get("countByEnumeratingWithState
"),
5724 &CGM.getContext().Idents.get("objects
"),
5725 &CGM.getContext().Idents.get("count
")
5727 VTableDispatchMethods.insert(
5728 CGM.getContext().Selectors.getSelector(3, KeyIdents));
5732 return VTableDispatchMethods.count(Sel);
5750 llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
5752 unsigned InstanceStart,
5753 unsigned InstanceSize,
5754 const ObjCImplementationDecl *ID) {
5755 std::string ClassName = ID->getObjCRuntimeNameAsString();
5756 llvm::Constant *Values[10]; // 11 for 64bit targets!
5758 CharUnits beginInstance = CharUnits::fromQuantity(InstanceStart);
5759 CharUnits endInstance = CharUnits::fromQuantity(InstanceSize);
5761 bool hasMRCWeak = false;
5762 if (CGM.getLangOpts().ObjCAutoRefCount)
5763 flags |= NonFragileABI_Class_CompiledByARC;
5764 else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))
5765 flags |= NonFragileABI_Class_HasMRCWeakIvars;
5767 Values[ 0] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags);
5768 Values[ 1] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceStart);
5769 Values[ 2] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceSize);
5770 // FIXME. For 64bit targets add 0 here.
5771 Values[ 3] = (flags & NonFragileABI_Class_Meta)
5772 ? GetIvarLayoutName(nullptr, ObjCTypes)
5773 : BuildStrongIvarLayout(ID, beginInstance, endInstance);
5774 Values[ 4] = GetClassName(ID->getObjCRuntimeNameAsString());
5775 // const struct _method_list_t * const baseMethods;
5776 std::vector<llvm::Constant*> Methods;
5777 std::string MethodListName("\01l_OBJC_$_
");
5778 if (flags & NonFragileABI_Class_Meta) {
5779 MethodListName += "CLASS_METHODS_
";
5780 MethodListName += ID->getObjCRuntimeNameAsString();
5781 for (const auto *I : ID->class_methods())
5782 // Class methods should always be defined.
5783 Methods.push_back(GetMethodConstant(I));
5785 MethodListName += "INSTANCE_METHODS_
";
5786 MethodListName += ID->getObjCRuntimeNameAsString();
5787 for (const auto *I : ID->instance_methods())
5788 // Instance methods should always be defined.
5789 Methods.push_back(GetMethodConstant(I));
5791 for (const auto *PID : ID->property_impls()) {
5792 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){
5793 ObjCPropertyDecl *PD = PID->getPropertyDecl();
5795 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
5796 if (llvm::Constant *C = GetMethodConstant(MD))
5797 Methods.push_back(C);
5798 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
5799 if (llvm::Constant *C = GetMethodConstant(MD))
5800 Methods.push_back(C);
5804 Values[ 5] = EmitMethodList(MethodListName,
5805 "__DATA, __objc_const
", Methods);
5807 const ObjCInterfaceDecl *OID = ID->getClassInterface();
5808 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer
");
5809 Values[ 6] = EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_
"
5810 + OID->getObjCRuntimeNameAsString(),
5811 OID->all_referenced_protocol_begin(),
5812 OID->all_referenced_protocol_end());
5814 if (flags & NonFragileABI_Class_Meta) {
5815 Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
5816 Values[ 8] = GetIvarLayoutName(nullptr, ObjCTypes);
5817 Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
5819 Values[ 7] = EmitIvarList(ID);
5820 Values[ 8] = BuildWeakIvarLayout(ID, beginInstance, endInstance,
5822 Values[ 9] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_
" + ID->getObjCRuntimeNameAsString(),
5823 ID, ID->getClassInterface(), ObjCTypes);
5825 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy,
5827 llvm::GlobalVariable *CLASS_RO_GV =
5828 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassRonfABITy, false,
5829 llvm::GlobalValue::PrivateLinkage,
5831 (flags & NonFragileABI_Class_Meta) ?
5832 std::string("\01l_OBJC_METACLASS_RO_$_
")+ClassName :
5833 std::string("\01l_OBJC_CLASS_RO_$_
")+ClassName);
5834 CLASS_RO_GV->setAlignment(
5835 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassRonfABITy));
5836 CLASS_RO_GV->setSection("__DATA, __objc_const
");
5851 llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassMetaData(
5852 const std::string &ClassName, llvm::Constant *IsAGV, llvm::Constant *SuperClassGV,
5853 llvm::Constant *ClassRoGV, bool HiddenVisibility, bool Weak) {
5854 llvm::Constant *Values[] = {
5857 ObjCEmptyCacheVar, // &ObjCEmptyCacheVar
5858 ObjCEmptyVtableVar, // &ObjCEmptyVtableVar
5859 ClassRoGV // &CLASS_RO_GV
5862 Values[1] = llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy);
5864 Values[3] = llvm::Constant::getNullValue(
5865 llvm::PointerType::getUnqual(ObjCTypes.ImpnfABITy));
5866 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy,
5868 llvm::GlobalVariable *GV = GetClassGlobal(ClassName, Weak);
5869 GV->setInitializer(Init);
5870 GV->setSection("__DATA, __objc_data
");
5872 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassnfABITy));
5873 if (HiddenVisibility)
5874 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
5879 CGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
5880 return OD->getClassMethod(GetNullarySelector("load
")) != nullptr;
5883 void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
5884 uint32_t &InstanceStart,
5885 uint32_t &InstanceSize) {
5886 const ASTRecordLayout &RL =
5887 CGM.getContext().getASTObjCImplementationLayout(OID);
5889 // InstanceSize is really instance end.
5890 InstanceSize = RL.getDataSize().getQuantity();
5892 // If there are no fields, the start is the same as the end.
5893 if (!RL.getFieldCount())
5894 InstanceStart = InstanceSize;
5896 InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth();
5899 void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
5900 std::string ClassName = ID->getObjCRuntimeNameAsString();
5901 if (!ObjCEmptyCacheVar) {
5902 ObjCEmptyCacheVar = new llvm::GlobalVariable(
5906 llvm::GlobalValue::ExternalLinkage,
5908 "_objc_empty_cache
");
5910 // Make this entry NULL for any iOS device target, any iOS simulator target,
5911 // OS X with deployment target 10.9 or later.
5912 const llvm::Triple &Triple = CGM.getTarget().getTriple();
5913 if (Triple.isiOS() || Triple.isWatchOS() ||
5914 (Triple.isMacOSX() && !Triple.isMacOSXVersionLT(10, 9)))
5915 // This entry will be null.
5916 ObjCEmptyVtableVar = nullptr;
5918 ObjCEmptyVtableVar = new llvm::GlobalVariable(
5920 ObjCTypes.ImpnfABITy,
5922 llvm::GlobalValue::ExternalLinkage,
5924 "_objc_empty_vtable
");
5926 assert(ID->getClassInterface() &&
5927 "CGObjCNonFragileABIMac::GenerateClass -
class is 0");
5929 uint32_t InstanceStart =
5930 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy);
5931 uint32_t InstanceSize = InstanceStart;
5937 llvm::GlobalVariable *SuperClassGV, *IsAGV;
5940 bool classIsHidden =
5956 TClassName = ObjCClassName;
5957 TClassName += ClassName;
5958 SuperClassGV = GetClassGlobal(TClassName.str(),
5960 TClassName = ObjCMetaClassName;
5961 TClassName += ClassName;
5962 IsAGV = GetClassGlobal(TClassName.str(),
5969 TClassName = ObjCMetaClassName ;
5971 IsAGV = GetClassGlobal(TClassName.str(),
5975 TClassName = ObjCMetaClassName;
5977 SuperClassGV = GetClassGlobal(
5981 llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags,
5984 TClassName = ObjCMetaClassName;
5985 TClassName += ClassName;
5986 llvm::GlobalVariable *MetaTClass = BuildClassMetaData(
5987 TClassName.str(), IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden,
5989 DefinedMetaClasses.push_back(MetaTClass);
6014 SuperClassGV =
nullptr;
6017 TClassName = ObjCClassName;
6019 SuperClassGV = GetClassGlobal(
6023 GetClassSizeInfo(ID, InstanceStart, InstanceSize);
6024 CLASS_RO_GV = BuildClassRoTInitializer(flags,
6029 TClassName = ObjCClassName;
6030 TClassName += ClassName;
6031 llvm::GlobalVariable *ClassMD =
6032 BuildClassMetaData(TClassName.str(), MetaTClass, SuperClassGV, CLASS_RO_GV,
6035 DefinedClasses.push_back(ClassMD);
6039 if (ImplementationIsNonLazy(ID))
6040 DefinedNonLazyClasses.push_back(ClassMD);
6046 MethodDefinitions.clear();
6063 llvm::Constant *Init =
6064 llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD),
6065 ObjCTypes.getExternalProtocolPtrTy());
6067 std::string ProtocolName(
"\01l_OBJC_PROTOCOL_REFERENCE_$_");
6072 llvm::GlobalVariable *PTGV = CGM.
getModule().getGlobalVariable(ProtocolName);
6075 PTGV =
new llvm::GlobalVariable(
6077 Init->getType(),
false,
6078 llvm::GlobalValue::WeakAnyLinkage,
6081 PTGV->setSection(
"__DATA, __objc_protorefs, coalesced, no_dead_strip");
6100 const char *Prefix =
"\01l_OBJC_$_CATEGORY_";
6104 ExtCatName +=
"_$_";
6110 llvm::Constant *Values[6];
6113 llvm::GlobalVariable *ClassGV =
6116 Values[1] = ClassGV;
6117 std::vector<llvm::Constant*> Methods;
6120 MethodListName +=
"INSTANCE_METHODS_";
6122 MethodListName +=
"_$_";
6123 MethodListName += OCD->
getName();
6127 Methods.push_back(GetMethodConstant(I));
6129 Values[2] = EmitMethodList(MethodListName.str(),
6130 "__DATA, __objc_const",
6133 MethodListName = Prefix;
6134 MethodListName +=
"CLASS_METHODS_";
6136 MethodListName +=
"_$_";
6142 Methods.push_back(GetMethodConstant(I));
6144 Values[3] = EmitMethodList(MethodListName.str(),
6145 "__DATA, __objc_const",
6153 Values[4] = EmitProtocolList(
"\01l_OBJC_CATEGORY_PROTOCOLS_$_"
6155 + Category->getName(),
6156 Category->protocol_begin(),
6157 Category->protocol_end());
6158 Values[5] = EmitPropertyList(
"\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
6161 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
6162 Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
6165 llvm::Constant *Init =
6166 llvm::ConstantStruct::get(ObjCTypes.CategorynfABITy,
6168 llvm::GlobalVariable *GCATV
6169 =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.CategorynfABITy,
6171 llvm::GlobalValue::PrivateLinkage,
6174 GCATV->setAlignment(
6175 CGM.
getDataLayout().getABITypeAlignment(ObjCTypes.CategorynfABITy));
6176 GCATV->setSection(
"__DATA, __objc_const");
6178 DefinedCategories.push_back(GCATV);
6181 if (ImplementationIsNonLazy(OCD))
6182 DefinedNonLazyCategories.push_back(GCATV);
6184 MethodDefinitions.clear();
6190 llvm::Constant *CGObjCNonFragileABIMac::GetMethodConstant(
6192 llvm::Function *Fn = GetMethodDefinition(MD);
6196 llvm::Constant *Method[] = {
6197 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->
getSelector()),
6198 ObjCTypes.SelectorPtrTy),
6199 GetMethodVarType(MD),
6200 llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy)
6202 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
6213 CGObjCNonFragileABIMac::EmitMethodList(Twine Name,
6214 const char *Section,
6217 if (Methods.empty())
6218 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
6220 llvm::Constant *Values[3];
6222 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.MethodTy);
6223 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6225 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
6226 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
6228 Values[2] = llvm::ConstantArray::get(AT, Methods);
6229 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
6231 llvm::GlobalVariable *GV =
6232 new llvm::GlobalVariable(CGM.
getModule(), Init->getType(),
false,
6233 llvm::GlobalValue::PrivateLinkage, Init,
Name);
6234 GV->setAlignment(CGM.
getDataLayout().getABITypeAlignment(Init->getType()));
6235 GV->setSection(Section);
6237 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListnfABIPtrTy);
6242 llvm::GlobalVariable *
6251 llvm::GlobalVariable *IvarOffsetGV =
6252 CGM.
getModule().getGlobalVariable(Name);
6254 IvarOffsetGV =
new llvm::GlobalVariable(
6255 CGM.
getModule(), ObjCTypes.IvarOffsetVarTy,
false,
6257 return IvarOffsetGV;
6263 unsigned long int Offset) {
6264 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
6265 IvarOffsetGV->setInitializer(
6266 llvm::ConstantInt::get(ObjCTypes.IvarOffsetVarTy, Offset));
6267 IvarOffsetGV->setAlignment(
6268 CGM.
getDataLayout().getABITypeAlignment(ObjCTypes.IvarOffsetVarTy));
6278 IvarOffsetGV->setSection(
"__DATA, __objc_ivar");
6279 return IvarOffsetGV;
6299 llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
6302 std::vector<llvm::Constant*> Ivars;
6305 assert(OID &&
"CGObjCNonFragileABIMac::EmitIvarList - null interface");
6312 if (!IVD->getDeclName())
6314 llvm::Constant *Ivar[5];
6316 ComputeIvarBaseOffset(CGM, ID, IVD));
6317 Ivar[1] = GetMethodVarName(IVD->getIdentifier());
6318 Ivar[2] = GetMethodVarType(IVD);
6319 llvm::Type *FieldTy =
6321 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(FieldTy);
6323 IVD->getType().getTypePtr()) >> 3;
6324 Align = llvm::Log2_32(Align);
6325 Ivar[3] = llvm::ConstantInt::get(ObjCTypes.IntTy, Align);
6331 Ivar[4] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6332 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarnfABITy, Ivar));
6336 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
6338 llvm::Constant *Values[3];
6339 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.IvarnfABITy);
6340 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6341 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
6342 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarnfABITy,
6344 Values[2] = llvm::ConstantArray::get(AT, Ivars);
6345 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
6346 const char *Prefix =
"\01l_OBJC_$_INSTANCE_VARIABLES_";
6347 llvm::GlobalVariable *GV =
6348 new llvm::GlobalVariable(CGM.
getModule(), Init->getType(),
false,
6349 llvm::GlobalValue::PrivateLinkage,
6354 GV->setSection(
"__DATA, __objc_const");
6357 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy);
6360 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(
6362 llvm::GlobalVariable *&Entry = Protocols[PD->
getIdentifier()];
6369 new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolnfABITy,
6373 Entry->setSection(
"__DATA,__datacoal_nt,coalesced");
6398 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
6400 llvm::GlobalVariable *Entry = Protocols[PD->
getIdentifier()];
6403 if (Entry && Entry->hasInitializer())
6411 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
6412 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
6413 std::vector<llvm::Constant*> MethodTypesExt, OptMethodTypesExt;
6415 llvm::Constant *C = GetMethodDescriptionConstant(MD);
6417 return GetOrEmitProtocolRef(PD);
6420 OptInstanceMethods.push_back(C);
6421 OptMethodTypesExt.push_back(GetMethodVarType(MD,
true));
6423 InstanceMethods.push_back(C);
6424 MethodTypesExt.push_back(GetMethodVarType(MD,
true));
6429 llvm::Constant *C = GetMethodDescriptionConstant(MD);
6431 return GetOrEmitProtocolRef(PD);
6434 OptClassMethods.push_back(C);
6435 OptMethodTypesExt.push_back(GetMethodVarType(MD,
true));
6437 ClassMethods.push_back(C);
6438 MethodTypesExt.push_back(GetMethodVarType(MD,
true));
6442 MethodTypesExt.insert(MethodTypesExt.end(),
6443 OptMethodTypesExt.begin(), OptMethodTypesExt.end());
6445 llvm::Constant *Values[12];
6447 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy);
6453 Values[3] = EmitMethodList(
"\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_"
6455 "__DATA, __objc_const",
6457 Values[4] = EmitMethodList(
"\01l_OBJC_$_PROTOCOL_CLASS_METHODS_"
6459 "__DATA, __objc_const",
6461 Values[5] = EmitMethodList(
"\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_"
6463 "__DATA, __objc_const",
6464 OptInstanceMethods);
6465 Values[6] = EmitMethodList(
"\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_"
6467 "__DATA, __objc_const",
6470 nullptr, PD, ObjCTypes);
6472 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
6473 Values[8] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6474 Values[9] = llvm::Constant::getNullValue(ObjCTypes.IntTy);
6475 Values[10] = EmitProtocolMethodTypes(
"\01l_OBJC_$_PROTOCOL_METHOD_TYPES_"
6477 MethodTypesExt, ObjCTypes);
6479 Values[11] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
6481 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolnfABITy,
6486 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
6487 Entry->setInitializer(Init);
6490 new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolnfABITy,
6491 false, llvm::GlobalValue::WeakAnyLinkage, Init,
6493 Entry->setAlignment(
6494 CGM.
getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABITy));
6495 Entry->setSection(
"__DATA,__datacoal_nt,coalesced");
6504 llvm::GlobalVariable *PTGV =
6505 new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolnfABIPtrTy,
6506 false, llvm::GlobalValue::WeakAnyLinkage, Entry,
6509 CGM.
getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy));
6510 PTGV->setSection(
"__DATA, __objc_protolist, coalesced, no_dead_strip");
6525 CGObjCNonFragileABIMac::EmitProtocolList(Twine Name,
6532 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
6536 Name.toVector(TmpName);
6537 llvm::GlobalVariable *GV =
6538 CGM.
getModule().getGlobalVariable(TmpName.str(),
true);
6540 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy);
6543 ProtocolRefs.push_back(GetProtocolRef(*begin));
6546 ProtocolRefs.push_back(llvm::Constant::getNullValue(
6547 ObjCTypes.ProtocolnfABIPtrTy));
6549 llvm::Constant *Values[2];
6551 llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
6553 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolnfABIPtrTy,
6554 ProtocolRefs.size()),
6557 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
6558 GV =
new llvm::GlobalVariable(CGM.
getModule(), Init->getType(),
false,
6559 llvm::GlobalValue::PrivateLinkage,
6561 GV->setSection(
"__DATA, __objc_const");
6565 return llvm::ConstantExpr::getBitCast(GV,
6566 ObjCTypes.ProtocolListnfABIPtrTy);
6577 CGObjCNonFragileABIMac::GetMethodDescriptionConstant(
const ObjCMethodDecl *MD) {
6578 llvm::Constant *Desc[3];
6580 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->
getSelector()),
6581 ObjCTypes.SelectorPtrTy);
6582 Desc[1] = GetMethodVarType(MD);
6587 Desc[2] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
6588 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Desc);
6597 LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
6602 unsigned CVRQualifiers) {
6604 llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
6605 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
6609 llvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset(
6613 llvm::Value *IvarOffsetValue = ObjCIvarOffsetVariable(Interface, Ivar);
6616 if (IsIvarOffsetKnownIdempotent(CGF, Ivar))
6617 cast<llvm::LoadInst>(IvarOffsetValue)
6618 ->setMetadata(CGM.
getModule().getMDKindID(
"invariant.load"),
6619 llvm::MDNode::get(VMContext, None));
6624 if (ObjCTypes.IvarOffsetVarTy == ObjCTypes.IntTy)
6625 IvarOffsetValue = CGF.
Builder.CreateIntCast(
6626 IvarOffsetValue, ObjCTypes.LongTy,
true,
"ivar.conv");
6627 return IvarOffsetValue;
6630 static void appendSelectorForMessageRefTable(std::string &buffer,
6637 for (
unsigned i = 0, e = selector.
getNumArgs(); i != e; ++i) {
6669 args.
add(RValue::get(arg0), arg0Type);
6673 args.
add(RValue::get(
nullptr), ObjCTypes.MessageRefCPtrTy);
6675 args.insert(args.end(), formalArgs.begin(), formalArgs.end());
6677 MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);
6679 NullReturnState nullReturn;
6688 llvm::Constant *fn =
nullptr;
6689 std::string messageRefName(
"\01l_");
6692 fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
6693 messageRefName +=
"objc_msgSendSuper2_stret_fixup";
6695 nullReturn.init(CGF, arg0);
6696 fn = ObjCTypes.getMessageSendStretFixupFn();
6697 messageRefName +=
"objc_msgSend_stret_fixup";
6700 fn = ObjCTypes.getMessageSendFpretFixupFn();
6701 messageRefName +=
"objc_msgSend_fpret_fixup";
6704 fn = ObjCTypes.getMessageSendSuper2FixupFn();
6705 messageRefName +=
"objc_msgSendSuper2_fixup";
6707 fn = ObjCTypes.getMessageSendFixupFn();
6708 messageRefName +=
"objc_msgSend_fixup";
6711 assert(fn &&
"CGObjCNonFragileABIMac::EmitMessageSend");
6712 messageRefName +=
'_';
6716 appendSelectorForMessageRefTable(messageRefName, selector);
6718 llvm::GlobalVariable *messageRef
6719 = CGM.
getModule().getGlobalVariable(messageRefName);
6722 llvm::Constant *values[] = { fn, GetMethodVarName(selector) };
6723 llvm::Constant *init = llvm::ConstantStruct::getAnon(values);
6724 messageRef =
new llvm::GlobalVariable(CGM.
getModule(),
6727 llvm::GlobalValue::WeakAnyLinkage,
6731 messageRef->setAlignment(16);
6732 messageRef->setSection(
"__DATA, __objc_msgrefs, coalesced");
6735 bool requiresnullCheck =
false;
6737 for (
const auto *ParamDecl : method->
params()) {
6738 if (ParamDecl->
hasAttr<NSConsumedAttr>()) {
6739 if (!nullReturn.NullBB)
6740 nullReturn.init(CGF, arg0);
6741 requiresnullCheck =
true;
6760 RValue result = CGF.
EmitCall(MSI.CallInfo, callee, returnSlot, args);
6761 return nullReturn.complete(CGF, result, resultType, formalArgs,
6762 requiresnullCheck ? method :
nullptr);
6775 return isVTableDispatchedSelector(Sel)
6776 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
6778 false, CallArgs, Method)
6779 : EmitMessageSend(CGF, Return, ResultType,
6780 EmitSelector(CGF, Sel),
6782 false, CallArgs, Method, Class, ObjCTypes);
6785 llvm::GlobalVariable *
6786 CGObjCNonFragileABIMac::GetClassGlobal(
const std::string &Name,
bool Weak) {
6787 llvm::GlobalValue::LinkageTypes L =
6788 Weak ? llvm::GlobalValue::ExternalWeakLinkage
6791 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name);
6794 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassnfABITy,
6795 false, L,
nullptr,
Name);
6797 assert(GV->getLinkage() == L);
6806 llvm::GlobalVariable *&Entry = ClassReferences[II];
6809 std::string ClassName(
6810 getClassSymbolPrefix() +
6812 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName, Weak);
6813 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassnfABIPtrTy,
6814 false, llvm::GlobalValue::PrivateLinkage,
6815 ClassGV,
"OBJC_CLASSLIST_REFERENCES_$_");
6817 Entry->setSection(
"__DATA, __objc_classrefs, regular, no_dead_strip");
6828 llvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(
6831 return EmitClassRefFromId(CGF, II,
false,
nullptr);
6838 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->
getIdentifier()];
6843 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName.str(),
6845 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassnfABIPtrTy,
6846 false, llvm::GlobalValue::PrivateLinkage,
6847 ClassGV,
"OBJC_CLASSLIST_SUP_REFS_$_");
6849 Entry->setSection(
"__DATA, __objc_superrefs, regular, no_dead_strip");
6862 llvm::GlobalVariable * &Entry = MetaClassReferences[ID->
getIdentifier()];
6866 llvm::GlobalVariable *MetaClassGV =
6867 GetClassGlobal(MetaClassName.str(), Weak);
6869 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassnfABIPtrTy,
6870 false, llvm::GlobalValue::PrivateLinkage,
6871 MetaClassGV,
"OBJC_CLASSLIST_SUP_REFS_$_");
6874 Entry->setSection(
"__DATA, __objc_superrefs, regular, no_dead_strip");
6888 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName.str(),
true);
6890 assert(ClassGV->hasExternalWeakLinkage());
6893 return EmitClassRef(CGF, ID);
6905 bool isCategoryImpl,
6907 bool IsClassMessage,
6928 Target = EmitSuperClassRef(CGF, Class);
6932 llvm::Type *ClassTy =
6938 return (isVTableDispatchedSelector(Sel))
6939 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
6940 ObjCSuper.
getPointer(), ObjCTypes.SuperPtrCTy,
6941 true, CallArgs, Method)
6942 : EmitMessageSend(CGF, Return, ResultType,
6943 EmitSelector(CGF, Sel),
6944 ObjCSuper.
getPointer(), ObjCTypes.SuperPtrCTy,
6945 true, CallArgs, Method, Class, ObjCTypes);
6950 Address Addr = EmitSelectorAddr(CGF, Sel);
6953 LI->setMetadata(CGM.
getModule().getMDKindID(
"invariant.load"),
6954 llvm::MDNode::get(VMContext, None));
6960 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
6964 llvm::Constant *Casted =
6965 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
6966 ObjCTypes.SelectorPtrTy);
6967 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.SelectorPtrTy,
6968 false, llvm::GlobalValue::PrivateLinkage,
6969 Casted,
"OBJC_SELECTOR_REFERENCES_");
6970 Entry->setExternallyInitialized(
true);
6971 Entry->setSection(
"__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
6986 llvm::Type * SrcTy = src->getType();
6987 if (!isa<llvm::PointerType>(SrcTy)) {
6988 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(SrcTy);
6989 assert(Size <= 8 && "does not support size > 8
");
6990 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
6991 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
6992 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
6994 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
6995 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
6996 llvm::Value *args[] = { src, dst.getPointer(), ivarOffset };
6997 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
7003 void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
7004 CodeGen::CodeGenFunction &CGF,
7005 llvm::Value *src, Address dst) {
7006 llvm::Type * SrcTy = src->getType();
7007 if (!isa<llvm::PointerType>(SrcTy)) {
7008 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7009 assert(Size <= 8 && "does
not support size > 8
");
7010 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7011 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7012 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7014 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7015 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
7016 llvm::Value *args[] = { src, dst.getPointer() };
7017 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(),
7018 args, "weakassign
");
7021 void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
7022 CodeGen::CodeGenFunction &CGF,
7025 llvm::Value *Size) {
7026 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
7027 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
7028 llvm::Value *args[] = { DestPtr.getPointer(), SrcPtr.getPointer(), Size };
7029 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
7035 llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(
7036 CodeGen::CodeGenFunction &CGF,
7037 Address AddrWeakObj) {
7038 llvm::Type *DestTy = AddrWeakObj.getElementType();
7039 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy);
7040 llvm::Value *read_weak =
7041 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(),
7042 AddrWeakObj.getPointer(), "weakread
");
7043 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
7050 void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
7051 llvm::Value *src, Address dst) {
7052 llvm::Type * SrcTy = src->getType();
7053 if (!isa<llvm::PointerType>(SrcTy)) {
7054 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7055 assert(Size <= 8 && "does
not support size > 8
");
7056 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7057 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7058 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7060 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7061 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
7062 llvm::Value *args[] = { src, dst.getPointer() };
7063 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(),
7064 args, "weakassign
");
7070 void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
7071 llvm::Value *src, Address dst,
7073 llvm::Type * SrcTy = src->getType();
7074 if (!isa<llvm::PointerType>(SrcTy)) {
7075 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7076 assert(Size <= 8 && "does
not support size > 8
");
7077 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7078 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7079 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7081 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7082 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
7083 llvm::Value *args[] = { src, dst.getPointer() };
7085 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(),
7086 args, "globalassign
");
7088 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(),
7089 args, "threadlocalassign
");
7093 CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
7094 const ObjCAtSynchronizedStmt &S) {
7095 EmitAtSynchronizedStmt(CGF, S,
7096 cast<llvm::Function>(ObjCTypes.getSyncEnterFn()),
7097 cast<llvm::Function>(ObjCTypes.getSyncExitFn()));
7101 CGObjCNonFragileABIMac::GetEHType(QualType T) {
7102 // There's a particular fixed type info for 'id'.
7103 if (T->isObjCIdType() ||
7104 T->isObjCQualifiedIdType()) {
7105 llvm::Constant *IDEHType =
7106 CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id
");
7109 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy,
7111 llvm::GlobalValue::ExternalLinkage,
7112 nullptr, "OBJC_EHTYPE_id
");
7116 // All other types should be Objective-C interface pointer types.
7117 const ObjCObjectPointerType *PT =
7118 T->getAs<ObjCObjectPointerType>();
7119 assert(PT && "Invalid
@catch type.
");
7120 const ObjCInterfaceType *IT = PT->getInterfaceType();
7121 assert(IT && "Invalid
@catch type.
");
7122 return GetInterfaceEHType(IT->getDecl(), false);
7125 void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
7126 const ObjCAtTryStmt &S) {
7127 EmitTryCatchStmt(CGF, S,
7128 cast<llvm::Function>(ObjCTypes.getObjCBeginCatchFn()),
7129 cast<llvm::Function>(ObjCTypes.getObjCEndCatchFn()),
7130 cast<llvm::Function>(ObjCTypes.getExceptionRethrowFn()));
7134 void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
7135 const ObjCAtThrowStmt &S,
7136 bool ClearInsertionPoint) {
7137 if (const Expr *ThrowExpr = S.getThrowExpr()) {
7138 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
7139 Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
7140 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception)
7141 .setDoesNotReturn();
7143 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionRethrowFn())
7144 .setDoesNotReturn();
7147 CGF.Builder.CreateUnreachable();
7148 if (ClearInsertionPoint)
7149 CGF.Builder.ClearInsertionPoint();
7153 CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
7154 bool ForDefinition) {
7155 llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
7157 // If we don't need a definition, return the entry if found or check
7158 // if we use an external reference.
7159 if (!ForDefinition) {
7163 // If this type (or a super class) has the __objc_exception__
7164 // attribute, emit an external reference.
7165 if (hasObjCExceptionAttribute(CGM.getContext(), ID))
7167 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
7168 llvm::GlobalValue::ExternalLinkage,
7171 ID->getObjCRuntimeNameAsString()));
7174 // Otherwise we need to either make a new entry or fill in the
7176 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition
");
7177 llvm::SmallString<64> ClassName(getClassSymbolPrefix());
7178 ClassName += ID->getObjCRuntimeNameAsString();
7179 std::string VTableName = "objc_ehtype_vtable
";
7180 llvm::GlobalVariable *VTableGV =
7181 CGM.getModule().getGlobalVariable(VTableName);
7183 VTableGV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy,
7185 llvm::GlobalValue::ExternalLinkage,
7186 nullptr, VTableName);
7188 llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2);
7190 llvm::Constant *Values[] = {
7191 llvm::ConstantExpr::getGetElementPtr(VTableGV->getValueType(), VTableGV,
7193 GetClassName(ID->getObjCRuntimeNameAsString()),
7194 GetClassGlobal(ClassName.str())};
7195 llvm::Constant *Init =
7196 llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values);
7198 llvm::GlobalValue::LinkageTypes L = ForDefinition
7199 ? llvm::GlobalValue::ExternalLinkage
7200 : llvm::GlobalValue::WeakAnyLinkage;
7202 Entry->setInitializer(Init);
7204 llvm::SmallString<64> EHTYPEName("OBJC_EHTYPE_$_
");
7205 EHTYPEName += ID->getObjCRuntimeNameAsString();
7206 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
7211 assert(Entry->getLinkage() == L);
7213 if (ID->getVisibility() == HiddenVisibility)
7214 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
7215 Entry->setAlignment(CGM.getDataLayout().getABITypeAlignment(
7216 ObjCTypes.EHTypeTy));
7219 Entry->setSection("__DATA,__objc_const
");
7221 Entry->setSection("__DATA,__datacoal_nt,coalesced
");
7228 CodeGen::CGObjCRuntime *
7229 CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
7230 switch (CGM.getLangOpts().ObjCRuntime.getKind()) {
7231 case ObjCRuntime::FragileMacOSX:
7232 return new CGObjCMac(CGM);
7234 case ObjCRuntime::MacOSX:
7235 case ObjCRuntime::iOS:
7236 case ObjCRuntime::WatchOS:
7237 return new CGObjCNonFragileABIMac(CGM);
7239 case ObjCRuntime::GNUstep:
7240 case ObjCRuntime::GCC:
7241 case ObjCRuntime::ObjFW:
7242 llvm_unreachable("these runtimes are
not Mac runtimes
");
7244 llvm_unreachable("bad runtime
");
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for class's metadata.
param_const_iterator param_begin() const
ReturnValueSlot - Contains the address where the return value of a function can be stored...
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
getIdentifier - Get the identifier that names the class interface associated with this implementation...
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
protocol_range protocols() const
CharUnits BlockHeaderForcedGapOffset
Smart pointer class that efficiently represents Objective-C method names.
Class implementation was compiled under ARC.
PointerType - C99 6.7.5.1 - Pointer Declarators.
const ObjCAtFinallyStmt * getFinallyStmt() const
Retrieve the @finally statement, if any.
A (possibly-)qualified type.
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
getIdentifier - Get the identifier that names this declaration, if there is one.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
CharUnits getOffset() const
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
CreateTempAlloca - This creates a alloca and inserts it into the entry block.
Implements runtime-specific code generation functions.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
bool isRecordType() const
Decl - This represents one declaration (or definition), e.g.
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
llvm::CallingConv::ID getRuntimeCC() const
void EmitAutoVarDecl(const VarDecl &D)
EmitAutoVarDecl - Emit an auto variable declaration.
std::string getAsString() const
const llvm::DataLayout & getDataLayout() const
Has a non-trivial constructor or destructor.
bool isObjCQualifiedClassType() const
Represents Objective-C's @throw statement.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
static bool hasObjCExceptionAttribute(ASTContext &Context, const ObjCInterfaceDecl *OID)
hasObjCExceptionAttribute - Return true if this class or any super class has the objc_exception attri...
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
bool isBlockPointerType() const
ObjCProtocolList::iterator protocol_iterator
static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT, bool pointee=false)
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.
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
Objects with "hidden" visibility are not seen by the dynamic linker.
llvm::Type * getElementType() const
Return the type of the values stored in this address.
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.
ObjCMethodDecl - Represents an instance or class method declaration.
Visibility getVisibility() const
Determines the visibility of this entity.
Defines the Objective-C statement AST node classes.
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
ParmVarDecl - Represents a parameter to a function.
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names the category interface associated with this implementat...
A jump destination is an abstract label, branching to which may require a jump out through normal cle...
llvm::Value * EmitObjCThrowOperand(const Expr *expr)
Class implementation was compiled under ARC.
RecordDecl - Represents a struct/union/class.
One of these records is kept for each identifier that is lexed.
const ObjCInterfaceDecl * getContainingInterface() const
Return the class interface that this ivar is logically contained in; this is either the interface whe...
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
Represents a class type in Objective C.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
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 ...
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.
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
llvm::CallInst * EmitRuntimeCall(llvm::Value *callee, const Twine &name="")
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
Class implementation was compiled under MRC and has MRC weak ivars.
const CGFunctionInfo & arrangeLLVMFunctionInfo(CanQualType returnType, bool instanceMethod, bool chainCall, ArrayRef< CanQualType > argTypes, FunctionType::ExtInfo info, RequiredArgs args)
"Arrange" the LLVM information for a call or type with the given signature.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
RValue EmitCall(const CGFunctionInfo &FnInfo, llvm::Value *Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, CGCalleeInfo CalleeInfo=CGCalleeInfo(), llvm::Instruction **callOrInvoke=nullptr)
EmitCall - Generate a call of the given function, expecting the given result type, and using the given argument list which specifies both the LLVM arguments and the types they were derived from.
Has the exception attribute.
const VarDecl * getCatchParamDecl() const
Objects with "default" visibility are seen by the dynamic linker and act like normal objects...
Represents Objective-C's @catch statement.
const Capture & getCapture(const VarDecl *var) const
static bool isWeakLinkedClass(const ObjCInterfaceDecl *ID)
ObjCContainerDecl - Represents a container for method declarations.
const LangOptions & getLangOpts() const
CharUnits - This is an opaque type for sizes expressed in character units.
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
protocol_iterator protocol_end() const
field_range fields() const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
RecordDecl * getDecl() const
CharUnits getPointerSize() const
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface...
std::string getNameAsString() const
getNameAsString - Get a human-readable name for the declaration, even if it is one of the special kin...
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)
EmitStmt - Emit the code for the statement.
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
getFieldOffset - Get the offset of the given field index, in bits.
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
detail::InMemoryDirectory::const_iterator I
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
Returns lifetime attribute of this type.
CGBlockInfo - Information to generate a block literal.
const TargetInfo & getTarget() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
ID
Defines the set of possible language-specific address spaces.
bool isUnarySelector() const
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
bool hasDestructors() const
Do any of the ivars of this class (not counting its base classes) require non-trivial destruction...
llvm::Value * getPointer() const
BlockDecl - This represents a block literal declaration, which is like an unnamed FunctionDecl...
Expr - This represents one expression.
unsigned getIndex() const
Defines the clang::LangOptions interface.
StringRef getName() const
Return the actual identifier string.
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for class's metadata.
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
Produce a name to be used for protocol's metadata.
bool isObjCGCWeak() const
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)
Return true iff the given type uses an argument slot when 'sret' is used as a return type...
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
QualType getObjCIdType() const
Represents the Objective-CC id type.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep)
Creates clause with a list of variables VL and a linear step Step.
static llvm::Constant * getConstantGEP(llvm::LLVMContext &VMContext, llvm::GlobalVariable *C, unsigned idx0, unsigned idx1)
getConstantGEP() - Help routine to construct simple GEPs.
CharUnits getSizeAlign() const
The result type of a method or function.
(Obsolete) ARC-specific: this class has a .release_ivars method
param_const_iterator param_end() const
The l-value was considered opaque, so the alignment was determined from a type.
bool isClassMethod() const
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
Address CreateBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
bool ReturnTypeUsesFPRet(QualType ResultType)
Return true iff the given type uses 'fpret' when used as a return type.
ASTContext & getContext() const
CharUnits getPointerAlign() const
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go...
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
void EmitARCRelease(llvm::Value *value, ARCPreciseLifetime_t precise)
Release the given object.
const TemplateArgument * iterator
CharUnits getSize() const
getSize - Get the record size in characters.
unsigned getBitWidthValue(const ASTContext &Ctx) const
StringRef getName() const
getName - Get the name of identifier for the class interface associated with this implementation as a...
llvm::StructType * StructureType
SmallVector< llvm::Value *, 8 > ObjCEHValueStack
ObjCEHValueStack - Stack of Objective-C exception values, used for rethrows.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
const CGFunctionInfo & arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD)
Arrange the argument and result information for the declaration or definition of an Objective-C metho...
CanQualType getCanonicalParamType(QualType T) const
Return the canonical parameter type corresponding to the specific potentially non-canonical one...
static bool hasMRCWeakIvars(CodeGenModule &CGM, const ObjCImplementationDecl *ID)
For compatibility, we only want to set the "HasMRCWeakIvars" flag (and actually fill in a layout stri...
all_protocol_iterator all_referenced_protocol_end() const
ObjCCategoryDecl - Represents a category declaration.
const ObjCInterfaceDecl * getClassInterface() const
static bool hasWeakMember(QualType type)
const LangOptions & getLangOpts() const
Represents one property declaration in an Objective-C interface.
Class implementation was compiled under MRC and has MRC weak ivars.
QualType getReturnType() const
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)
The given basic block lies in the current EH scope, but may be a target of a potentially scope-crossi...
virtual void Emit(CodeGenFunction &CGF, Flags flags)=0
Emit the cleanup.
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type, returning the result.
ObjCIvarDecl * getNextIvar()
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...
instmeth_range instance_methods() const
This class organizes the cross-function state that is used while generating LLVM code.
ObjCCategoryDecl * FindCategoryDeclaration(IdentifierInfo *CategoryId) const
FindCategoryDeclaration - Finds category declaration in the list of categories for this class and ret...
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.
Address CreateStructGEP(Address Addr, unsigned Index, CharUnits Offset, const llvm::Twine &Name="")
unsigned getCharWidth() const
llvm::LoadInst * CreateAlignedLoad(llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::IntegerType * IntPtrTy
QualType getObjCProtoType() const
Retrieve the type of the Objective-C Protocol class.
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
Selector getSelector() const
detail::InMemoryDirectory::const_iterator E
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Apparently: is not a meta-class.
Address getNormalCleanupDestSlot()
Represents a pointer to an Objective C object.
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
ObjCMethodDecl * getGetterMethodDecl() const
bool hasNonZeroConstructors() const
Do any of the ivars of this class (not counting its base classes) require construction other than zer...
llvm::PointerType * getType() const
Return the type of the pointer value.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
const T * getAs() const
Member-template getAs<specific type>'.
ObjCMethodDecl * getSetterMethodDecl() const
This class organizes the cross-module state that is used while lowering AST types to LLVM types...
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)
EmitBlock - Emit the given block.
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.
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
bool isObjCGCStrong() const
true when Type is objc's strong.
AccessControl getAccessControl() const
classmeth_range class_methods() const
BoundNodesTreeBuilder *const Builder
StringRef getName() const
getName - Get the name of identifier for the class interface associated with this implementation as a...
bool isObjCObjectPointerType() const
llvm::Type * ConvertType(QualType T)
all_protocol_iterator all_referenced_protocol_begin() const
A specialization of Address that requires the address to be an LLVM Constant.
ObjCIvarDecl - Represents an ObjC instance variable.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
const BlockDecl * getBlockDecl() const
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
CharUnits BlockHeaderForcedGapSize
Has a non-trivial constructor or destructor.
Represents Objective-C's @try ... @catch ... @finally statement.
const Expr * getThrowExpr() const
StringLiteral - This represents a string literal expression, e.g.
ObjCInterfaceDecl * getSuperClass() const
static RValue get(llvm::Value *V)
QualType getElementType() const
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
LValue - This represents an lvalue references.
Information for lazily generating a cleanup.
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
bool isObjCIdType() const
True if this is equivalent to the 'id' type, i.e.
CallArgList - Type for representing both the value and type of arguments in a call.
void PopCleanupBlock(bool FallThroughIsBranchThrough=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration...
Represents the canonical version of C arrays with a specified constant size.
CGCalleeInfo - Class to encapsulate the information about a callee to be used during the generation o...
A class which abstracts out some details necessary for making a call.
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
ObjCCompatibleAliasDecl - Represents alias of a class.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.