29 #include "llvm/ADT/CachedHashString.h" 30 #include "llvm/ADT/DenseSet.h" 31 #include "llvm/ADT/SetVector.h" 32 #include "llvm/ADT/SmallPtrSet.h" 33 #include "llvm/ADT/SmallString.h" 34 #include "llvm/IR/CallSite.h" 35 #include "llvm/IR/DataLayout.h" 36 #include "llvm/IR/InlineAsm.h" 37 #include "llvm/IR/IntrinsicInst.h" 38 #include "llvm/IR/LLVMContext.h" 39 #include "llvm/IR/Module.h" 40 #include "llvm/Support/raw_ostream.h" 43 using namespace clang;
44 using namespace CodeGen;
51 class ObjCCommonTypesHelper {
53 llvm::LLVMContext &VMContext;
63 llvm::Constant *getMessageSendFn()
const {
66 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
67 return CGM.CreateRuntimeFunction(
68 llvm::FunctionType::get(ObjectPtrTy, params,
true),
"objc_msgSend",
69 llvm::AttributeList::get(CGM.getLLVMContext(),
70 llvm::AttributeList::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);
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::IntegerType *ShortTy, *IntTy, *LongTy;
176 llvm::PointerType *Int8PtrTy, *Int8PtrPtrTy;
180 llvm::PointerType *ObjectPtrTy;
183 llvm::PointerType *PtrObjectPtrTy;
186 llvm::PointerType *SelectorPtrTy;
195 if (!ExternalProtocolPtrTy) {
201 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
204 return ExternalProtocolPtrTy;
213 llvm::StructType *SuperTy;
215 llvm::PointerType *SuperPtrTy;
219 llvm::StructType *PropertyTy;
223 llvm::StructType *PropertyListTy;
225 llvm::PointerType *PropertyListPtrTy;
228 llvm::StructType *MethodTy;
233 llvm::PointerType *CachePtrTy;
235 llvm::Constant *getGetPropertyFn() {
244 llvm::FunctionType *FTy =
250 llvm::Constant *getSetPropertyFn() {
263 llvm::FunctionType *FTy =
269 llvm::Constant *getOptimizedSetPropertyFn(
bool atomic,
bool copy) {
284 Params.push_back(IdType);
285 Params.push_back(SelType);
286 Params.push_back(IdType);
288 llvm::FunctionType *FTy =
293 name =
"objc_setProperty_atomic_copy";
294 else if (atomic && !copy)
295 name =
"objc_setProperty_atomic";
296 else if (!atomic && copy)
297 name =
"objc_setProperty_nonatomic_copy";
299 name =
"objc_setProperty_nonatomic";
304 llvm::Constant *getCopyStructFn() {
312 Params.push_back(Ctx.
BoolTy);
313 Params.push_back(Ctx.
BoolTy);
314 llvm::FunctionType *FTy =
324 llvm::Constant *getCppAtomicObjectFunction() {
332 llvm::FunctionType *FTy =
338 llvm::Constant *getEnumerationMutationFn() {
344 llvm::FunctionType *FTy =
350 llvm::Constant *getLookUpClassFn() {
357 llvm::FunctionType *FTy =
365 llvm::Constant *getGcReadWeakFn() {
367 llvm::Type *args[] = { ObjectPtrTy->getPointerTo() };
368 llvm::FunctionType *FTy =
369 llvm::FunctionType::get(ObjectPtrTy, args,
false);
374 llvm::Constant *getGcAssignWeakFn() {
376 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
377 llvm::FunctionType *FTy =
378 llvm::FunctionType::get(ObjectPtrTy, args,
false);
383 llvm::Constant *getGcAssignGlobalFn() {
385 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
386 llvm::FunctionType *FTy =
387 llvm::FunctionType::get(ObjectPtrTy, args,
false);
392 llvm::Constant *getGcAssignThreadLocalFn() {
394 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
395 llvm::FunctionType *FTy =
396 llvm::FunctionType::get(ObjectPtrTy, args,
false);
401 llvm::Constant *getGcAssignIvarFn() {
403 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo(),
405 llvm::FunctionType *FTy =
406 llvm::FunctionType::get(ObjectPtrTy, args,
false);
411 llvm::Constant *GcMemmoveCollectableFn() {
413 llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, LongTy };
414 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, args,
false);
419 llvm::Constant *getGcAssignStrongCastFn() {
421 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
422 llvm::FunctionType *FTy =
423 llvm::FunctionType::get(ObjectPtrTy, args,
false);
428 llvm::Constant *getExceptionThrowFn() {
431 llvm::FunctionType *FTy =
432 llvm::FunctionType::get(CGM.
VoidTy, args,
false);
437 llvm::Constant *getExceptionRethrowFn() {
439 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
444 llvm::Constant *getSyncEnterFn() {
447 llvm::FunctionType *FTy =
448 llvm::FunctionType::get(CGM.
IntTy, args,
false);
453 llvm::Constant *getSyncExitFn() {
456 llvm::FunctionType *FTy =
457 llvm::FunctionType::get(CGM.
IntTy, args,
false);
461 llvm::Constant *getSendFn(
bool IsSuper)
const {
462 return IsSuper ? getMessageSendSuperFn() : getMessageSendFn();
465 llvm::Constant *getSendFn2(
bool IsSuper)
const {
466 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();
469 llvm::Constant *getSendStretFn(
bool IsSuper)
const {
470 return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();
473 llvm::Constant *getSendStretFn2(
bool IsSuper)
const {
474 return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();
477 llvm::Constant *getSendFpretFn(
bool IsSuper)
const {
478 return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();
481 llvm::Constant *getSendFpretFn2(
bool IsSuper)
const {
482 return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();
485 llvm::Constant *getSendFp2retFn(
bool IsSuper)
const {
486 return IsSuper ? getMessageSendSuperFn() : getMessageSendFp2retFn();
489 llvm::Constant *getSendFp2RetFn2(
bool IsSuper)
const {
490 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFp2retFn();
498 class ObjCTypesHelper :
public ObjCCommonTypesHelper {
501 llvm::StructType *SymtabTy;
503 llvm::PointerType *SymtabPtrTy;
505 llvm::StructType *ModuleTy;
508 llvm::StructType *ProtocolTy;
510 llvm::PointerType *ProtocolPtrTy;
513 llvm::StructType *ProtocolExtensionTy;
516 llvm::PointerType *ProtocolExtensionPtrTy;
519 llvm::StructType *MethodDescriptionTy;
522 llvm::StructType *MethodDescriptionListTy;
525 llvm::PointerType *MethodDescriptionListPtrTy;
527 llvm::StructType *ProtocolListTy;
529 llvm::PointerType *ProtocolListPtrTy;
531 llvm::StructType *CategoryTy;
533 llvm::StructType *ClassTy;
535 llvm::PointerType *ClassPtrTy;
537 llvm::StructType *ClassExtensionTy;
539 llvm::PointerType *ClassExtensionPtrTy;
541 llvm::StructType *IvarTy;
543 llvm::StructType *IvarListTy;
545 llvm::PointerType *IvarListPtrTy;
547 llvm::StructType *MethodListTy;
549 llvm::PointerType *MethodListPtrTy;
552 llvm::StructType *ExceptionDataTy;
555 llvm::Constant *getExceptionTryEnterFn() {
556 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
558 llvm::FunctionType::get(CGM.
VoidTy, params,
false),
559 "objc_exception_try_enter");
563 llvm::Constant *getExceptionTryExitFn() {
564 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
566 llvm::FunctionType::get(CGM.
VoidTy, params,
false),
567 "objc_exception_try_exit");
571 llvm::Constant *getExceptionExtractFn() {
572 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
575 "objc_exception_extract");
579 llvm::Constant *getExceptionMatchFn() {
580 llvm::Type *params[] = { ClassPtrTy, ObjectPtrTy };
582 llvm::FunctionType::get(CGM.
Int32Ty, params,
false),
583 "objc_exception_match");
587 llvm::Constant *getSetJmpFn() {
591 llvm::FunctionType::get(CGM.
Int32Ty, params,
false),
"_setjmp",
593 llvm::AttributeList::FunctionIndex,
594 llvm::Attribute::NonLazyBind));
603 class ObjCNonFragileABITypesHelper :
public ObjCCommonTypesHelper {
606 llvm::StructType *MethodListnfABITy;
609 llvm::PointerType *MethodListnfABIPtrTy;
612 llvm::StructType *ProtocolnfABITy;
615 llvm::PointerType *ProtocolnfABIPtrTy;
618 llvm::StructType *ProtocolListnfABITy;
621 llvm::PointerType *ProtocolListnfABIPtrTy;
624 llvm::StructType *ClassnfABITy;
627 llvm::PointerType *ClassnfABIPtrTy;
630 llvm::StructType *IvarnfABITy;
633 llvm::StructType *IvarListnfABITy;
636 llvm::PointerType *IvarListnfABIPtrTy;
639 llvm::StructType *ClassRonfABITy;
642 llvm::PointerType *ImpnfABITy;
645 llvm::StructType *CategorynfABITy;
654 llvm::StructType *MessageRefTy;
668 llvm::StructType *SuperMessageRefTy;
671 llvm::PointerType *SuperMessageRefPtrTy;
673 llvm::Constant *getMessageSendFixupFn() {
675 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
678 "objc_msgSend_fixup");
681 llvm::Constant *getMessageSendFpretFixupFn() {
683 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
686 "objc_msgSend_fpret_fixup");
689 llvm::Constant *getMessageSendStretFixupFn() {
691 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
694 "objc_msgSend_stret_fixup");
697 llvm::Constant *getMessageSendSuper2FixupFn() {
700 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
703 "objc_msgSendSuper2_fixup");
706 llvm::Constant *getMessageSendSuper2StretFixupFn() {
709 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
712 "objc_msgSendSuper2_stret_fixup");
715 llvm::Constant *getObjCEndCatchFn() {
721 llvm::Constant *getObjCBeginCatchFn() {
728 llvm::StructType *EHTypeTy;
747 SKIP_SCAN(
unsigned _skip = 0,
unsigned _scan = 0)
748 : skip(_skip), scan(_scan) {}
755 enum BLOCK_LAYOUT_OPCODE {
762 BLOCK_LAYOUT_OPERATOR = 0,
768 BLOCK_LAYOUT_NON_OBJECT_BYTES = 1,
773 BLOCK_LAYOUT_NON_OBJECT_WORDS = 2,
777 BLOCK_LAYOUT_STRONG = 3,
780 BLOCK_LAYOUT_BYREF = 4,
784 BLOCK_LAYOUT_WEAK = 5,
788 BLOCK_LAYOUT_UNRETAINED = 6
805 enum BLOCK_LAYOUT_OPCODE opcode;
808 RUN_SKIP(
enum BLOCK_LAYOUT_OPCODE Opcode = BLOCK_LAYOUT_OPERATOR,
811 : opcode(Opcode), block_var_bytepos(BytePos), block_var_size(Size) {}
814 bool operator<(
const RUN_SKIP &b)
const {
815 return block_var_bytepos < b.block_var_bytepos;
820 llvm::LLVMContext &VMContext;
829 llvm::SetVector<IdentifierInfo*> LazySymbols;
835 llvm::SetVector<IdentifierInfo*> DefinedSymbols;
838 llvm::StringMap<llvm::GlobalVariable*> ClassNames;
841 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
848 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
852 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
855 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
858 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
861 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
866 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
889 llvm::WeakTrackingVH ConstantStringClassRef;
892 llvm::StructType *NSConstantStringType =
nullptr;
894 llvm::StringMap<llvm::GlobalVariable *> NSConstantStringMap;
904 llvm::Constant *GetMethodVarName(
Selector Sel);
912 bool Extended =
false);
913 llvm::Constant *GetMethodVarType(
const FieldDecl *D);
921 const Decl *Container);
926 llvm::Constant *GetClassName(StringRef RuntimeName);
940 bool forStrongLayout,
946 return BuildIvarLayout(OI, beginOffset, endOffset,
true,
false);
952 bool hasMRCWeakIvars) {
953 return BuildIvarLayout(OI, beginOffset, endOffset,
false, hasMRCWeakIvars);
958 void UpdateRunSkipBlockVars(
bool IsByref,
963 void BuildRCBlockVarRecordLayout(
const RecordType *RT,
965 bool ByrefLayout=
false);
967 void BuildRCRecordLayout(
const llvm::StructLayout *RecLayout,
975 llvm::Constant *getBitmapBlockLayout(
bool ComputeByrefLayout);
980 const ObjCCommonTypesHelper &ObjCTypes);
984 llvm::Constant *EmitPropertyList(Twine Name,
985 const Decl *Container,
987 const ObjCCommonTypesHelper &ObjCTypes,
988 bool IsClassProperty);
992 llvm::Constant *EmitProtocolMethodTypes(Twine Name,
994 const ObjCCommonTypesHelper &ObjCTypes);
1005 ObjCCommonTypesHelper &ObjCTypes);
1007 std::string GetSectionName(StringRef Section, StringRef MachOAttributes);
1024 llvm::GlobalVariable *CreateMetadataVar(Twine Name,
1028 llvm::GlobalVariable *CreateMetadataVar(Twine Name,
1029 llvm::Constant *Init,
1033 llvm::GlobalVariable *CreateCStringLiteral(StringRef Name,
1035 bool ForceNonFragileABI =
false,
1036 bool NullTerminate =
true);
1049 const ObjCCommonTypesHelper &ObjCTypes);
1053 void EmitImageInfo();
1059 bool isNonFragileABI()
const {
1060 return ObjCABI == 2;
1080 virtual llvm::Constant *GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD)=0;
1082 virtual llvm::Constant *getNSConstantStringClassRef() = 0;
1096 CategoryInstanceMethods,
1097 CategoryClassMethods,
1100 ProtocolInstanceMethods,
1101 ProtocolClassMethods,
1102 OptionalProtocolInstanceMethods,
1103 OptionalProtocolClassMethods,
1108 class ProtocolMethodLists {
1111 RequiredInstanceMethods,
1112 RequiredClassMethods,
1113 OptionalInstanceMethods,
1114 OptionalClassMethods
1117 NumProtocolMethodLists = 4
1122 case RequiredInstanceMethods:
1123 return MethodListType::ProtocolInstanceMethods;
1124 case RequiredClassMethods:
1125 return MethodListType::ProtocolClassMethods;
1126 case OptionalInstanceMethods:
1127 return MethodListType::OptionalProtocolInstanceMethods;
1128 case OptionalClassMethods:
1129 return MethodListType::OptionalProtocolClassMethods;
1131 llvm_unreachable(
"bad kind");
1137 ProtocolMethodLists result;
1139 for (
auto MD : PD->methods()) {
1140 size_t index = (2 *
size_t(MD->isOptional()))
1141 + (
size_t(MD->isClassMethod()));
1142 result.Methods[index].push_back(MD);
1148 template <
class Self>
1159 for (
auto &list : Methods) {
1160 for (
auto MD : list) {
1161 result.push_back(self->GetMethodVarType(MD,
true));
1168 template <
class Self>
1172 getMethodListKind(kind), Methods[
kind]);
1178 class CGObjCMac :
public CGObjCCommonMac {
1180 friend ProtocolMethodLists;
1182 ObjCTypesHelper ObjCTypes;
1186 void EmitModuleInfo();
1190 llvm::Constant *EmitModuleSymbols();
1194 void FinishModule();
1233 llvm::Constant *Protocols,
1264 const ProtocolMethodLists &methodLists);
1268 llvm::Constant *EmitProtocolList(Twine Name,
1280 llvm::Constant *getNSConstantStringClassRef()
override;
1282 llvm::Function *ModuleInitFunction()
override;
1311 llvm::Constant *GetEHType(
QualType T)
override;
1322 llvm::Constant *GetPropertyGetFunction()
override;
1323 llvm::Constant *GetPropertySetFunction()
override;
1324 llvm::Constant *GetOptimizedPropertySetFunction(
bool atomic,
1325 bool copy)
override;
1326 llvm::Constant *GetGetStructFunction()
override;
1327 llvm::Constant *GetSetStructFunction()
override;
1328 llvm::Constant *GetCppAtomicObjectGetFunction()
override;
1329 llvm::Constant *GetCppAtomicObjectSetFunction()
override;
1330 llvm::Constant *EnumerationMutationFunction()
override;
1338 bool ClearInsertionPoint=
true)
override;
1340 Address AddrWeakObj)
override;
1345 bool threadlocal =
false)
override;
1357 unsigned CVRQualifiers)
override;
1363 class CGObjCNonFragileABIMac :
public CGObjCCommonMac {
1365 friend ProtocolMethodLists;
1366 ObjCNonFragileABITypesHelper ObjCTypes;
1367 llvm::GlobalVariable* ObjCEmptyCacheVar;
1368 llvm::Constant* ObjCEmptyVtableVar;
1371 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences;
1374 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences;
1377 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences;
1384 std::vector<llvm::GlobalValue*> DefinedMetaClasses;
1388 bool isVTableDispatchedSelector(
Selector Sel);
1392 void FinishNonFragileABIModule();
1397 StringRef SymbolName, StringRef SectionName);
1399 llvm::GlobalVariable * BuildClassRoTInitializer(
unsigned flags,
1400 unsigned InstanceStart,
1401 unsigned InstanceSize,
1405 llvm::Constant *IsAGV,
1406 llvm::Constant *SuperClassGV,
1407 llvm::Constant *ClassRoGV,
1428 unsigned long int offset);
1443 llvm::Constant *EmitProtocolList(Twine Name,
1459 llvm::Constant *GetClassGlobal(StringRef Name,
1461 bool Weak =
false,
bool DLLImport =
false);
1490 llvm::GlobalVariable * ObjCIvarOffsetVariable(
1504 StringRef getMetaclassSymbolPrefix()
const {
return "OBJC_METACLASS_$_"; }
1506 StringRef getClassSymbolPrefix()
const {
return "OBJC_CLASS_$_"; }
1509 uint32_t &InstanceStart,
1510 uint32_t &InstanceSize);
1525 bool ImplementationIsNonLazy(
const ObjCImplDecl *OD)
const;
1540 dyn_cast_or_null<ObjCMethodDecl>(CGF.
CurFuncDecl))
1550 llvm::Constant *getNSConstantStringClassRef()
override;
1552 llvm::Function *ModuleInitFunction()
override;
1574 {
return EmitSelector(CGF, Sel); }
1576 {
return EmitSelectorAddr(CGF, Sel); }
1582 {
return EmitSelector(CGF, Method->
getSelector()); }
1593 llvm::Constant *GetEHType(
QualType T)
override;
1595 llvm::Constant *GetPropertyGetFunction()
override {
1596 return ObjCTypes.getGetPropertyFn();
1598 llvm::Constant *GetPropertySetFunction()
override {
1599 return ObjCTypes.getSetPropertyFn();
1602 llvm::Constant *GetOptimizedPropertySetFunction(
bool atomic,
1603 bool copy)
override {
1604 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
1607 llvm::Constant *GetSetStructFunction()
override {
1608 return ObjCTypes.getCopyStructFn();
1611 llvm::Constant *GetGetStructFunction()
override {
1612 return ObjCTypes.getCopyStructFn();
1615 llvm::Constant *GetCppAtomicObjectSetFunction()
override {
1616 return ObjCTypes.getCppAtomicObjectFunction();
1619 llvm::Constant *GetCppAtomicObjectGetFunction()
override {
1620 return ObjCTypes.getCppAtomicObjectFunction();
1623 llvm::Constant *EnumerationMutationFunction()
override {
1624 return ObjCTypes.getEnumerationMutationFn();
1632 bool ClearInsertionPoint=
true)
override;
1634 Address AddrWeakObj)
override;
1639 bool threadlocal =
false)
override;
1650 unsigned CVRQualifiers)
override;
1658 struct NullReturnState {
1659 llvm::BasicBlock *NullBB;
1660 NullReturnState() : NullBB(
nullptr) {}
1673 CGF.
Builder.CreateCondBr(isNull, NullBB, callBB);
1688 if (!NullBB)
return result;
1692 llvm::BasicBlock *contBB =
nullptr;
1695 llvm::BasicBlock *callBB = CGF.
Builder.GetInsertBlock();
1706 CallArgList::const_iterator I = CallArgs.begin();
1708 e = Method->
param_end(); i != e; ++i, ++I) {
1710 if (ParamDecl->
hasAttr<NSConsumedAttr>()) {
1711 RValue RV = I->getRValue(CGF);
1713 "NullReturnState::complete - arg not on object");
1720 assert(CGF.
Builder.GetInsertBlock() == NullBB);
1739 llvm::PHINode *phi = CGF.
Builder.CreatePHI(null->getType(), 2);
1741 phi->addIncoming(null, NullBB);
1750 assert(result.
isAggregate() &&
"null init of non-aggregate result?");
1762 llvm::Type *scalarTy = callResult.first->getType();
1763 llvm::Constant *scalarZero = llvm::Constant::getNullValue(scalarTy);
1766 llvm::PHINode *real = CGF.
Builder.CreatePHI(scalarTy, 2);
1767 real->addIncoming(callResult.first, callBB);
1768 real->addIncoming(scalarZero, NullBB);
1769 llvm::PHINode *imag = CGF.
Builder.CreatePHI(scalarTy, 2);
1770 imag->addIncoming(callResult.second, callBB);
1771 imag->addIncoming(scalarZero, NullBB);
1782 llvm::GlobalVariable *C,
unsigned idx0,
1785 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),
1786 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)
1788 return llvm::ConstantExpr::getGetElementPtr(C->getValueType(), C, Idxs);
1795 if (OID->
hasAttr<ObjCExceptionAttr>())
1814 return EmitClassRef(CGF, ID);
1819 return EmitSelector(CGF, Sel);
1822 return EmitSelectorAddr(CGF, Sel);
1829 llvm::Constant *CGObjCMac::GetEHType(
QualType T) {
1843 llvm_unreachable(
"asking for catch type for ObjC type in fragile runtime");
1866 CGObjCCommonMac::GenerateConstantString(
const StringLiteral *SL) {
1869 : GenerateConstantNSString(SL));
1872 static llvm::StringMapEntry<llvm::GlobalVariable *> &
1875 StringRef String = Literal->
getString();
1876 StringLength = String.size();
1877 return *Map.insert(std::make_pair(String,
nullptr)).first;
1880 llvm::Constant *CGObjCMac::getNSConstantStringClassRef() {
1882 return cast<llvm::Constant>(V);
1886 StringClass.empty() ?
"_NSConstantStringClassReference" 1887 :
"_" + StringClass +
"ClassReference";
1891 auto V = llvm::ConstantExpr::getBitCast(GV, CGM.
IntTy->getPointerTo());
1892 ConstantStringClassRef = V;
1896 llvm::Constant *CGObjCNonFragileABIMac::getNSConstantStringClassRef() {
1898 return cast<llvm::Constant>(V);
1902 StringClass.empty() ?
"OBJC_CLASS_$_NSConstantString" 1903 :
"OBJC_CLASS_$_" + StringClass;
1907 auto V = llvm::ConstantExpr::getBitCast(GV, CGM.
IntTy->getPointerTo());
1909 ConstantStringClassRef = V;
1914 CGObjCCommonMac::GenerateConstantNSString(
const StringLiteral *Literal) {
1915 unsigned StringLength = 0;
1916 llvm::StringMapEntry<llvm::GlobalVariable *> &Entry =
1919 if (
auto *C = Entry.second)
1923 llvm::Constant *Class = getNSConstantStringClassRef();
1926 if (!NSConstantStringType) {
1927 NSConstantStringType =
1932 },
"struct.__builtin_NSString");
1936 auto Fields = Builder.beginStruct(NSConstantStringType);
1943 llvm::ConstantDataArray::getString(VMContext, Entry.first());
1945 llvm::GlobalValue::LinkageTypes
Linkage = llvm::GlobalValue::PrivateLinkage;
1946 bool isConstant = !CGM.
getLangOpts().WritableStrings;
1948 auto *GV =
new llvm::GlobalVariable(CGM.
getModule(), C->getType(), isConstant,
1950 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1953 GV->setAlignment(1);
1957 Fields.addInt(CGM.
IntTy, StringLength);
1961 GV = Fields.finishAndCreateGlobal(
"_unnamed_nsstring_", Alignment,
1963 llvm::GlobalVariable::PrivateLinkage);
1964 const char *NSStringSection =
"__OBJC,__cstring_object,regular,no_dead_strip";
1965 const char *NSStringNonFragileABISection =
1966 "__DATA,__objc_stringobj,regular,no_dead_strip";
1969 ? NSStringNonFragileABISection
1989 bool isCategoryImpl,
1991 bool IsClassMessage,
2007 if (IsClassMessage) {
2008 if (isCategoryImpl) {
2019 llvm::Constant *MetaClassPtr = EmitMetaClassRef(Class);
2026 }
else if (isCategoryImpl)
2040 return EmitMessageSend(CGF, Return, ResultType,
2041 EmitSelector(CGF, Sel),
2042 ObjCSuper.
getPointer(), ObjCTypes.SuperPtrCTy,
2043 true, CallArgs, Method, Class, ObjCTypes);
2055 return EmitMessageSend(CGF, Return, ResultType,
2056 EmitSelector(CGF, Sel),
2058 false, CallArgs, Method, Class, ObjCTypes);
2081 const ObjCCommonTypesHelper &ObjCTypes) {
2090 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2095 "Result type mismatch!");
2097 bool ReceiverCanBeNull =
true;
2102 ReceiverCanBeNull =
false;
2106 }
else if (ClassReceiver && Method && Method->
isClassMethod()) {
2111 }
else if (
auto CurMethod =
2112 dyn_cast_or_null<ObjCMethodDecl>(CGF.
CurCodeDecl)) {
2113 auto Self = CurMethod->getSelfDecl();
2114 if (Self->getType().isConstQualified()) {
2115 if (
auto LI = dyn_cast<llvm::LoadInst>(Arg0->stripPointerCasts())) {
2117 if (SelfAddr == LI->getPointerOperand()) {
2118 ReceiverCanBeNull =
false;
2124 bool RequiresNullCheck =
false;
2126 llvm::Constant *Fn =
nullptr;
2128 if (ReceiverCanBeNull) RequiresNullCheck =
true;
2129 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
2130 : ObjCTypes.getSendStretFn(IsSuper);
2132 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
2133 : ObjCTypes.getSendFpretFn(IsSuper);
2135 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)
2136 : ObjCTypes.getSendFp2retFn(IsSuper);
2141 RequiresNullCheck =
true;
2142 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
2143 : ObjCTypes.getSendFn(IsSuper);
2149 RequiresNullCheck =
false;
2152 if (!RequiresNullCheck && CGM.
getLangOpts().ObjCAutoRefCount && Method) {
2153 for (
const auto *ParamDecl : Method->
parameters()) {
2154 if (ParamDecl->hasAttr<NSConsumedAttr>()) {
2155 RequiresNullCheck =
true;
2161 NullReturnState nullReturn;
2162 if (RequiresNullCheck) {
2163 nullReturn.init(CGF, Arg0);
2166 llvm::Instruction *CallSite;
2167 Fn = llvm::ConstantExpr::getBitCast(Fn, MSI.MessengerType);
2169 RValue rvalue = CGF.
EmitCall(MSI.CallInfo, Callee, Return, ActualArgs,
2174 if (Method && Method->
hasAttr<NoReturnAttr>() && !ReceiverCanBeNull) {
2175 llvm::CallSite(CallSite).setDoesNotReturn();
2178 return nullReturn.complete(CGF, Return, rvalue, ResultType, CallArgs,
2179 RequiresNullCheck ? Method :
nullptr);
2183 bool pointee =
false) {
2196 switch (ownership) {
2203 llvm_unreachable(
"bad objc ownership");
2222 uint64_t SizeInWords;
2223 IvarInfo(
CharUnits offset, uint64_t sizeInWords)
2224 :
Offset(offset), SizeInWords(sizeInWords) {}
2227 bool operator<(
const IvarInfo &other)
const {
2228 return Offset < other.Offset;
2233 class IvarLayoutBuilder {
2244 bool ForStrongLayout;
2247 bool IsDisordered =
false;
2253 CharUnits instanceEnd,
bool forStrongLayout)
2254 : CGM(CGM), InstanceBegin(instanceBegin), InstanceEnd(instanceEnd),
2255 ForStrongLayout(forStrongLayout) {
2260 template <
class Iterator,
class GetOffsetFn>
2261 void visitAggregate(Iterator begin, Iterator end,
2263 const GetOffsetFn &getOffset);
2271 bool hasBitmapData()
const {
return !IvarsInfo.empty(); }
2273 llvm::Constant *buildBitmap(CGObjCCommonMac &CGObjC,
2277 const unsigned char *s = buffer.data();
2278 for (
unsigned i = 0, e = buffer.size(); i < e; i++)
2280 printf(
"0x0%x%s", s[i], s[i] != 0 ?
", " :
"");
2282 printf(
"0x%x%s", s[i], s[i] != 0 ?
", " :
"");
2288 llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(
CodeGenModule &CGM,
2291 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2298 builder.visitBlock(blockInfo);
2300 if (!builder.hasBitmapData())
2304 llvm::Constant *C = builder.buildBitmap(*
this, buffer);
2305 if (CGM.
getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
2306 printf(
"\n block variable layout for block: ");
2307 builder.dump(buffer);
2313 void IvarLayoutBuilder::visitBlock(
const CGBlockInfo &blockInfo) {
2326 for (
const auto &CI : blockDecl->
captures()) {
2327 const VarDecl *variable = CI.getVariable();
2339 if (fieldOffset < lastFieldOffset)
2340 IsDisordered =
true;
2341 lastFieldOffset = fieldOffset;
2345 IvarsInfo.push_back(IvarInfo(fieldOffset, 1));
2349 assert(!type->
isArrayType() &&
"array variable should not be caught");
2351 visitRecord(record, fieldOffset);
2360 IvarsInfo.push_back(IvarInfo(fieldOffset, 1));
2385 void CGObjCCommonMac::UpdateRunSkipBlockVars(
bool IsByref,
2391 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset,
2394 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset,
2397 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset,
2400 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset,
2403 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES,
2408 void CGObjCCommonMac::BuildRCRecordLayout(
const llvm::StructLayout *RecLayout,
2413 bool IsUnion = (RD && RD->
isUnion());
2416 const FieldDecl *LastFieldBitfieldOrUnnamed =
nullptr;
2420 if (RecFields.empty())
2424 for (
unsigned i = 0, e = RecFields.size(); i != e; ++i) {
2434 LastFieldBitfieldOrUnnamed = Field;
2435 LastBitfieldOrUnnamedOffset = FieldOffset;
2439 LastFieldBitfieldOrUnnamed =
nullptr;
2446 BytePos + FieldOffset, HasUnion);
2452 dyn_cast_or_null<ConstantArrayType>(Array);
2453 uint64_t ElCount = CArray->
getSize().getZExtValue();
2454 assert(CArray &&
"only array with known element size is supported");
2458 dyn_cast_or_null<ConstantArrayType>(Array);
2459 ElCount *= CArray->
getSize().getZExtValue();
2463 int OldIndex = RunSkipBlockVars.size() - 1;
2465 BuildRCBlockVarRecordLayout(RT, BytePos + FieldOffset,
2471 for (
int FirstIndex = RunSkipBlockVars.size() - 1 ;ElIx < ElCount; ElIx++) {
2473 for (
int i = OldIndex+1; i <= FirstIndex; ++i)
2474 RunSkipBlockVars.push_back(
2475 RUN_SKIP(RunSkipBlockVars[i].opcode,
2476 RunSkipBlockVars[i].block_var_bytepos + Size*ElIx,
2477 RunSkipBlockVars[i].block_var_size));
2485 if (UnionIvarSize > MaxUnionSize) {
2486 MaxUnionSize = UnionIvarSize;
2488 MaxFieldOffset = FieldOffset;
2491 UpdateRunSkipBlockVars(
false,
2492 getBlockCaptureLifetime(FQT, ByrefLayout),
2493 BytePos + FieldOffset,
2498 if (LastFieldBitfieldOrUnnamed) {
2499 if (LastFieldBitfieldOrUnnamed->
isBitField()) {
2501 uint64_t BitFieldSize
2503 unsigned UnsSize = (BitFieldSize / ByteSizeInBits) +
2504 ((BitFieldSize % ByteSizeInBits) != 0);
2506 Size += LastBitfieldOrUnnamedOffset;
2507 UpdateRunSkipBlockVars(
false,
2508 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
2510 BytePos + LastBitfieldOrUnnamedOffset,
2513 assert(!LastFieldBitfieldOrUnnamed->
getIdentifier() &&
"Expected unnamed");
2517 UpdateRunSkipBlockVars(
false,
2518 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
2520 BytePos + LastBitfieldOrUnnamedOffset,
2526 UpdateRunSkipBlockVars(
false,
2527 getBlockCaptureLifetime(MaxField->
getType(), ByrefLayout),
2528 BytePos + MaxFieldOffset,
2532 void CGObjCCommonMac::BuildRCBlockVarRecordLayout(
const RecordType *RT,
2539 const llvm::StructLayout *RecLayout =
2540 CGM.
getDataLayout().getStructLayout(cast<llvm::StructType>(Ty));
2542 BuildRCRecordLayout(RecLayout, RD, Fields, BytePos, HasUnion, ByrefLayout);
2554 uint64_t CGObjCCommonMac::InlineLayoutInstruction(
2556 uint64_t Result = 0;
2557 if (Layout.size() <= 3) {
2558 unsigned size = Layout.size();
2559 unsigned strong_word_count = 0, byref_word_count=0, weak_word_count=0;
2561 enum BLOCK_LAYOUT_OPCODE opcode ;
2565 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2566 if (opcode == BLOCK_LAYOUT_STRONG)
2567 strong_word_count = (inst & 0xF)+1;
2571 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2572 if (opcode == BLOCK_LAYOUT_BYREF)
2573 byref_word_count = (inst & 0xF)+1;
2577 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2578 if (opcode == BLOCK_LAYOUT_WEAK)
2579 weak_word_count = (inst & 0xF)+1;
2586 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2587 if (opcode == BLOCK_LAYOUT_STRONG) {
2588 strong_word_count = (inst & 0xF)+1;
2590 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2591 if (opcode == BLOCK_LAYOUT_BYREF)
2592 byref_word_count = (inst & 0xF)+1;
2593 else if (opcode == BLOCK_LAYOUT_WEAK)
2594 weak_word_count = (inst & 0xF)+1;
2598 else if (opcode == BLOCK_LAYOUT_BYREF) {
2599 byref_word_count = (inst & 0xF)+1;
2601 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2602 if (opcode == BLOCK_LAYOUT_WEAK)
2603 weak_word_count = (inst & 0xF)+1;
2613 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2614 if (opcode == BLOCK_LAYOUT_STRONG)
2615 strong_word_count = (inst & 0xF)+1;
2616 else if (opcode == BLOCK_LAYOUT_BYREF)
2617 byref_word_count = (inst & 0xF)+1;
2618 else if (opcode == BLOCK_LAYOUT_WEAK)
2619 weak_word_count = (inst & 0xF)+1;
2631 if (strong_word_count == 16 || byref_word_count == 16 || weak_word_count == 16)
2635 (strong_word_count != 0) + (byref_word_count != 0) + (weak_word_count != 0);
2637 if (size == count) {
2638 if (strong_word_count)
2639 Result = strong_word_count;
2641 if (byref_word_count)
2642 Result += byref_word_count;
2644 if (weak_word_count)
2645 Result += weak_word_count;
2651 llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(
bool ComputeByrefLayout) {
2652 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2653 if (RunSkipBlockVars.empty())
2657 unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2661 llvm::array_pod_sort(RunSkipBlockVars.begin(), RunSkipBlockVars.end());
2664 unsigned size = RunSkipBlockVars.size();
2665 for (
unsigned i = 0; i < size; i++) {
2666 enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode;
2667 CharUnits start_byte_pos = RunSkipBlockVars[i].block_var_bytepos;
2668 CharUnits end_byte_pos = start_byte_pos;
2671 if (opcode == RunSkipBlockVars[j].opcode) {
2672 end_byte_pos = RunSkipBlockVars[j++].block_var_bytepos;
2679 end_byte_pos - start_byte_pos + RunSkipBlockVars[j-1].block_var_size;
2682 RunSkipBlockVars[j].block_var_bytepos -
2683 RunSkipBlockVars[j-1].block_var_bytepos - RunSkipBlockVars[j-1].block_var_size;
2684 size_in_bytes += gap;
2687 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) {
2688 residue_in_bytes = size_in_bytes % WordSizeInBytes;
2689 size_in_bytes -= residue_in_bytes;
2690 opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS;
2693 unsigned size_in_words = size_in_bytes.
getQuantity() / WordSizeInBytes;
2694 while (size_in_words >= 16) {
2697 unsigned char inst = (opcode << 4) | 0xf;
2698 Layout.push_back(inst);
2699 size_in_words -= 16;
2701 if (size_in_words > 0) {
2704 unsigned char inst = (opcode << 4) | (size_in_words-1);
2705 Layout.push_back(inst);
2708 unsigned char inst =
2709 (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) | (residue_in_bytes.
getQuantity()-1);
2710 Layout.push_back(inst);
2714 while (!Layout.empty()) {
2715 unsigned char inst = Layout.back();
2716 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2717 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES || opcode == BLOCK_LAYOUT_NON_OBJECT_WORDS)
2723 uint64_t Result = InlineLayoutInstruction(Layout);
2727 if (ComputeByrefLayout)
2728 printf(
"\n Inline BYREF variable layout: ");
2730 printf(
"\n Inline block variable layout: ");
2731 printf(
"0x0%" PRIx64
"", Result);
2732 if (
auto numStrong = (Result & 0xF00) >> 8)
2733 printf(
", BL_STRONG:%d", (
int) numStrong);
2734 if (
auto numByref = (Result & 0x0F0) >> 4)
2735 printf(
", BL_BYREF:%d", (
int) numByref);
2736 if (
auto numWeak = (Result & 0x00F) >> 0)
2737 printf(
", BL_WEAK:%d", (
int) numWeak);
2738 printf(
", BL_OPERATOR:0\n");
2740 return llvm::ConstantInt::get(CGM.
IntPtrTy, Result);
2743 unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0;
2744 Layout.push_back(inst);
2746 for (
unsigned i = 0, e = Layout.size(); i != e; i++)
2747 BitMap += Layout[i];
2750 if (ComputeByrefLayout)
2751 printf(
"\n Byref variable layout: ");
2753 printf(
"\n Block variable layout: ");
2754 for (
unsigned i = 0, e = BitMap.size(); i != e; i++) {
2755 unsigned char inst = BitMap[i];
2756 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2759 case BLOCK_LAYOUT_OPERATOR:
2763 case BLOCK_LAYOUT_NON_OBJECT_BYTES:
2764 printf(
"BL_NON_OBJECT_BYTES:");
2766 case BLOCK_LAYOUT_NON_OBJECT_WORDS:
2767 printf(
"BL_NON_OBJECT_WORD:");
2769 case BLOCK_LAYOUT_STRONG:
2772 case BLOCK_LAYOUT_BYREF:
2775 case BLOCK_LAYOUT_WEAK:
2778 case BLOCK_LAYOUT_UNRETAINED:
2779 printf(
"BL_UNRETAINED:");
2784 printf(
"%d", (inst & 0xf) + delta);
2792 auto *Entry = CreateCStringLiteral(BitMap, ObjCLabelType::ClassName,
2798 llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(
CodeGenModule &CGM,
2802 RunSkipBlockVars.clear();
2803 bool hasUnion =
false;
2807 unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2812 const llvm::StructLayout *layout =
2822 for (
const auto &CI : blockDecl->
captures()) {
2823 const VarDecl *variable = CI.getVariable();
2834 assert(!type->
isArrayType() &&
"array variable should not be caught");
2837 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion);
2845 UpdateRunSkipBlockVars(CI.isByRef(), getBlockCaptureLifetime(type,
false),
2846 fieldOffset, fieldSize);
2848 return getBitmapBlockLayout(
false);
2854 assert(!T->
isArrayType() &&
"__block array variable should not be caught");
2856 RunSkipBlockVars.clear();
2857 bool hasUnion =
false;
2859 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion,
true );
2860 llvm::Constant *Result = getBitmapBlockLayout(
true);
2861 if (isa<llvm::ConstantInt>(Result))
2862 Result = llvm::ConstantExpr::getIntToPtr(Result, CGM.
Int8PtrTy);
2865 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2875 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
2876 ObjCTypes.getExternalProtocolPtrTy());
2888 GetOrEmitProtocol(PD);
2891 llvm::Constant *CGObjCCommonMac::GetProtocolRef(
const ObjCProtocolDecl *PD) {
2893 return GetOrEmitProtocol(PD);
2895 return GetOrEmitProtocolRef(PD);
2898 llvm::Value *CGObjCCommonMac::EmitClassRefViaRuntime(
2901 ObjCCommonTypesHelper &ObjCTypes) {
2902 llvm::Constant *lookUpClassFn = ObjCTypes.getLookUpClassFn();
2912 llvm::CallInst *call = CGF.
Builder.CreateCall(lookUpClassFn, className);
2913 call->setDoesNotThrow();
2930 llvm::GlobalVariable *Entry = Protocols[PD->
getIdentifier()];
2933 if (Entry && Entry->hasInitializer())
2945 auto methodLists = ProtocolMethodLists::get(PD);
2948 auto values = builder.
beginStruct(ObjCTypes.ProtocolTy);
2949 values.add(EmitProtocolExtension(PD, methodLists));
2951 values.add(EmitProtocolList(
"OBJC_PROTOCOL_REFS_" + PD->
getName(),
2953 values.add(methodLists.emitMethodList(
this, PD,
2954 ProtocolMethodLists::RequiredInstanceMethods));
2955 values.add(methodLists.emitMethodList(
this, PD,
2956 ProtocolMethodLists::RequiredClassMethods));
2960 assert(Entry->hasPrivateLinkage());
2961 values.finishAndSetAsInitializer(Entry);
2963 Entry = values.finishAndCreateGlobal(
"OBJC_PROTOCOL_" + PD->
getName(),
2966 llvm::GlobalValue::PrivateLinkage);
2967 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
2976 llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD) {
2977 llvm::GlobalVariable *&Entry = Protocols[PD->
getIdentifier()];
2983 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolTy,
2984 false, llvm::GlobalValue::PrivateLinkage,
2985 nullptr,
"OBJC_PROTOCOL_" + PD->
getName());
2986 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
2988 Entry->setAlignment(4);
3006 const ProtocolMethodLists &methodLists) {
3007 auto optInstanceMethods =
3008 methodLists.emitMethodList(
this, PD,
3009 ProtocolMethodLists::OptionalInstanceMethods);
3010 auto optClassMethods =
3011 methodLists.emitMethodList(
this, PD,
3012 ProtocolMethodLists::OptionalClassMethods);
3014 auto extendedMethodTypes =
3015 EmitProtocolMethodTypes(
"OBJC_PROTOCOL_METHOD_TYPES_" + PD->
getName(),
3016 methodLists.emitExtendedTypesArray(
this),
3019 auto instanceProperties =
3020 EmitPropertyList(
"OBJC_$_PROP_PROTO_LIST_" + PD->
getName(),
nullptr, PD,
3022 auto classProperties =
3023 EmitPropertyList(
"OBJC_$_CLASS_PROP_PROTO_LIST_" + PD->
getName(),
nullptr,
3024 PD, ObjCTypes,
true);
3027 if (optInstanceMethods->isNullValue() &&
3028 optClassMethods->isNullValue() &&
3029 extendedMethodTypes->isNullValue() &&
3030 instanceProperties->isNullValue() &&
3031 classProperties->isNullValue()) {
3032 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
3036 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
3039 auto values = builder.
beginStruct(ObjCTypes.ProtocolExtensionTy);
3040 values.addInt(ObjCTypes.IntTy, size);
3041 values.add(optInstanceMethods);
3042 values.add(optClassMethods);
3043 values.add(instanceProperties);
3044 values.add(extendedMethodTypes);
3045 values.add(classProperties);
3048 return CreateMetadataVar(
"\01l_OBJC_PROTOCOLEXT_" + PD->
getName(), values,
3060 CGObjCMac::EmitProtocolList(Twine name,
3065 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
3071 values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
3074 auto countSlot = values.addPlaceholder();
3076 auto refsArray = values.beginArray(ObjCTypes.ProtocolPtrTy);
3077 for (; begin != end; ++begin) {
3078 refsArray.add(GetProtocolRef(*begin));
3080 auto count = refsArray.size();
3083 refsArray.addNullPointer(ObjCTypes.ProtocolPtrTy);
3085 refsArray.finishAndAddTo(values);
3086 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
3089 if (CGM.
getTriple().isOSBinFormatMachO())
3090 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3092 llvm::GlobalVariable *GV =
3093 CreateMetadataVar(name, values, section, CGM.
getPointerAlign(),
false);
3094 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
3101 bool IsClassProperty) {
3106 if (IsClassProperty != PD->isClassProperty())
3110 Properties.push_back(PD);
3126 llvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name,
3127 const Decl *Container,
3129 const ObjCCommonTypesHelper &ObjCTypes,
3130 bool IsClassProperty) {
3131 if (IsClassProperty) {
3135 if ((Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 11)) ||
3136 (Triple.isiOS() && Triple.isOSVersionLT(9)))
3137 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3141 llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
3146 if (IsClassProperty != PD->isClassProperty())
3149 Properties.push_back(PD);
3153 if (IsClassProperty != PD->isClassProperty())
3159 Properties.push_back(PD);
3163 for (
const auto *
P : OID->all_referenced_protocols())
3167 for (
const auto *
P : CD->protocols())
3172 if (Properties.empty())
3173 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3175 unsigned propertySize =
3180 values.addInt(ObjCTypes.IntTy, propertySize);
3181 values.addInt(ObjCTypes.IntTy, Properties.size());
3182 auto propertiesArray = values.beginArray(ObjCTypes.PropertyTy);
3183 for (
auto PD : Properties) {
3184 auto property = propertiesArray.beginStruct(ObjCTypes.PropertyTy);
3186 property.add(GetPropertyTypeString(PD, Container));
3187 property.finishAndAddTo(propertiesArray);
3189 propertiesArray.finishAndAddTo(values);
3192 if (CGM.
getTriple().isOSBinFormatMachO())
3193 Section = (ObjCABI == 2) ?
"__DATA, __objc_const" 3194 :
"__OBJC,__property,regular,no_dead_strip";
3196 llvm::GlobalVariable *GV =
3197 CreateMetadataVar(Name, values, Section, CGM.
getPointerAlign(),
true);
3198 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy);
3202 CGObjCCommonMac::EmitProtocolMethodTypes(Twine Name,
3204 const ObjCCommonTypesHelper &ObjCTypes) {
3206 if (MethodTypes.empty())
3207 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy);
3209 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
3210 MethodTypes.size());
3211 llvm::Constant *Init = llvm::ConstantArray::get(AT, MethodTypes);
3214 if (CGM.
getTriple().isOSBinFormatMachO() && ObjCABI == 2)
3215 Section =
"__DATA, __objc_const";
3217 llvm::GlobalVariable *GV =
3219 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.Int8PtrPtrTy);
3235 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.CategoryTy);
3246 llvm::raw_svector_ostream(ExtName) << Interface->
getName() <<
'_' 3250 auto Values = Builder.
beginStruct(ObjCTypes.CategoryTy);
3258 for (
const auto *MD : OCD->
methods()) {
3259 Methods[unsigned(MD->isClassMethod())].push_back(MD);
3262 Values.add(GetClassName(OCD->
getName()));
3266 Values.add(emitMethodList(ExtName, MethodListType::CategoryInstanceMethods,
3267 Methods[InstanceMethods]));
3268 Values.add(emitMethodList(ExtName, MethodListType::CategoryClassMethods,
3269 Methods[ClassMethods]));
3272 EmitProtocolList(
"OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
3275 Values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
3277 Values.addInt(ObjCTypes.IntTy, Size);
3281 Values.add(EmitPropertyList(
"\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
3283 Values.add(EmitPropertyList(
"\01l_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(),
3286 Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
3287 Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
3290 llvm::GlobalVariable *GV =
3291 CreateMetadataVar(
"OBJC_CATEGORY_" + ExtName.str(), Values,
3292 "__OBJC,__category,regular,no_dead_strip",
3294 DefinedCategories.push_back(GV);
3295 DefinedCategoryNames.insert(llvm::CachedHashString(ExtName));
3297 MethodDefinitions.clear();
3357 for (
auto field : recType->getDecl()->fields()) {
3406 DefinedSymbols.insert(RuntimeName);
3412 llvm::Constant *Protocols =
3413 EmitProtocolList(
"OBJC_CLASS_PROTOCOLS_" + ID->
getName(),
3420 bool hasMRCWeak =
false;
3440 for (
const auto *MD : ID->
methods()) {
3441 Methods[unsigned(MD->isClassMethod())].push_back(MD);
3449 if (GetMethodDefinition(MD))
3450 Methods[InstanceMethods].push_back(MD);
3452 if (GetMethodDefinition(MD))
3453 Methods[InstanceMethods].push_back(MD);
3458 auto values = builder.
beginStruct(ObjCTypes.ClassTy);
3459 values.add(EmitMetaClass(ID, Protocols, Methods[ClassMethods]));
3462 LazySymbols.insert(Super->getIdentifier());
3464 values.addBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
3465 ObjCTypes.ClassPtrTy);
3467 values.addNullPointer(ObjCTypes.ClassPtrTy);
3471 values.addInt(ObjCTypes.LongTy, 0);
3472 values.addInt(ObjCTypes.LongTy, Flags);
3473 values.addInt(ObjCTypes.LongTy, Size.
getQuantity());
3474 values.add(EmitIvarList(ID,
false));
3475 values.add(emitMethodList(ID->
getName(), MethodListType::InstanceMethods,
3476 Methods[InstanceMethods]));
3478 values.addNullPointer(ObjCTypes.CachePtrTy);
3479 values.add(Protocols);
3481 values.add(EmitClassExtension(ID, Size, hasMRCWeak,
3484 std::string Name(
"OBJC_CLASS_");
3486 const char *Section =
"__OBJC,__class,regular,no_dead_strip";
3488 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3490 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3491 "Forward metaclass reference has incorrect type.");
3492 values.finishAndSetAsInitializer(GV);
3493 GV->setSection(Section);
3497 GV = CreateMetadataVar(Name, values, Section, CGM.
getPointerAlign(),
true);
3498 DefinedClasses.push_back(GV);
3499 ImplementedClasses.push_back(Interface);
3501 MethodDefinitions.clear();
3505 llvm::Constant *Protocols,
3508 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ClassTy);
3514 auto values = builder.
beginStruct(ObjCTypes.ClassTy);
3520 ObjCTypes.ClassPtrTy);
3525 values.addBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
3526 ObjCTypes.ClassPtrTy);
3528 values.addNullPointer(ObjCTypes.ClassPtrTy);
3532 values.addInt(ObjCTypes.LongTy, 0);
3533 values.addInt(ObjCTypes.LongTy, Flags);
3534 values.addInt(ObjCTypes.LongTy, Size);
3535 values.add(EmitIvarList(ID,
true));
3536 values.add(emitMethodList(ID->
getName(), MethodListType::ClassMethods,
3539 values.addNullPointer(ObjCTypes.CachePtrTy);
3540 values.add(Protocols);
3542 values.addNullPointer(ObjCTypes.Int8PtrTy);
3547 std::string Name(
"OBJC_METACLASS_");
3551 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3553 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3554 "Forward metaclass reference has incorrect type.");
3555 values.finishAndSetAsInitializer(GV);
3559 llvm::GlobalValue::PrivateLinkage);
3561 GV->setSection(
"__OBJC,__meta_class,regular,no_dead_strip");
3578 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3580 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
3581 llvm::GlobalValue::PrivateLinkage,
nullptr,
3584 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3585 "Forward metaclass reference has incorrect type.");
3591 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3594 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
3595 llvm::GlobalValue::PrivateLinkage,
nullptr,
3598 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3599 "Forward class metadata reference has incorrect type.");
3619 llvm::Constant *layout;
3621 layout = llvm::ConstantPointerNull::get(CGM.
Int8PtrTy);
3628 llvm::Constant *propertyList =
3629 EmitPropertyList((isMetaclass ? Twine(
"\01l_OBJC_$_CLASS_PROP_LIST_")
3630 : Twine(
"\01l_OBJC_$_PROP_LIST_"))
3635 if (layout->isNullValue() && propertyList->isNullValue()) {
3636 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
3640 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
3643 auto values = builder.
beginStruct(ObjCTypes.ClassExtensionTy);
3644 values.addInt(ObjCTypes.IntTy, size);
3646 values.add(propertyList);
3648 return CreateMetadataVar(
"OBJC_CLASSEXT_" + ID->
getName(), values,
3649 "__OBJC,__class_ext,regular,no_dead_strip",
3673 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3679 auto countSlot = ivarList.addPlaceholder();
3680 auto ivars = ivarList.beginArray(ObjCTypes.IvarTy);
3685 if (!IVD->getDeclName())
3688 auto ivar = ivars.beginStruct(ObjCTypes.IvarTy);
3689 ivar.add(GetMethodVarName(IVD->getIdentifier()));
3690 ivar.add(GetMethodVarType(IVD));
3691 ivar.addInt(ObjCTypes.IntTy, ComputeIvarBaseOffset(CGM, OID, IVD));
3692 ivar.finishAndAddTo(ivars);
3696 auto count = ivars.size();
3700 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3703 ivars.finishAndAddTo(ivarList);
3704 ivarList.fillPlaceholderWithInt(countSlot, ObjCTypes.IntTy, count);
3706 llvm::GlobalVariable *GV;
3709 CreateMetadataVar(
"OBJC_CLASS_VARIABLES_" + ID->
getName(), ivarList,
3710 "__OBJC,__class_vars,regular,no_dead_strip",
3713 GV = CreateMetadataVar(
"OBJC_INSTANCE_VARIABLES_" + ID->
getName(), ivarList,
3714 "__OBJC,__instance_vars,regular,no_dead_strip",
3716 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy);
3727 auto description = builder.
beginStruct(ObjCTypes.MethodDescriptionTy);
3728 description.addBitCast(GetMethodVarName(MD->
getSelector()),
3729 ObjCTypes.SelectorPtrTy);
3730 description.add(GetMethodVarType(MD));
3731 description.finishAndAddTo(builder);
3743 llvm::Function *fn = GetMethodDefinition(MD);
3744 assert(fn &&
"no definition registered for method");
3746 auto method = builder.
beginStruct(ObjCTypes.MethodTy);
3747 method.addBitCast(GetMethodVarName(MD->
getSelector()),
3748 ObjCTypes.SelectorPtrTy);
3749 method.add(GetMethodVarType(MD));
3750 method.addBitCast(fn, ObjCTypes.Int8PtrTy);
3751 method.finishAndAddTo(builder);
3767 llvm::Constant *CGObjCMac::emitMethodList(Twine name,
MethodListType MLT,
3771 bool forProtocol =
false;
3773 case MethodListType::CategoryInstanceMethods:
3774 prefix =
"OBJC_CATEGORY_INSTANCE_METHODS_";
3775 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
3776 forProtocol =
false;
3778 case MethodListType::CategoryClassMethods:
3779 prefix =
"OBJC_CATEGORY_CLASS_METHODS_";
3780 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3781 forProtocol =
false;
3783 case MethodListType::InstanceMethods:
3784 prefix =
"OBJC_INSTANCE_METHODS_";
3785 section =
"__OBJC,__inst_meth,regular,no_dead_strip";
3786 forProtocol =
false;
3788 case MethodListType::ClassMethods:
3789 prefix =
"OBJC_CLASS_METHODS_";
3790 section =
"__OBJC,__cls_meth,regular,no_dead_strip";
3791 forProtocol =
false;
3793 case MethodListType::ProtocolInstanceMethods:
3794 prefix =
"OBJC_PROTOCOL_INSTANCE_METHODS_";
3795 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
3798 case MethodListType::ProtocolClassMethods:
3799 prefix =
"OBJC_PROTOCOL_CLASS_METHODS_";
3800 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3803 case MethodListType::OptionalProtocolInstanceMethods:
3804 prefix =
"OBJC_PROTOCOL_INSTANCE_METHODS_OPT_";
3805 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
3808 case MethodListType::OptionalProtocolClassMethods:
3809 prefix =
"OBJC_PROTOCOL_CLASS_METHODS_OPT_";
3810 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3816 if (methods.empty())
3817 return llvm::Constant::getNullValue(forProtocol
3818 ? ObjCTypes.MethodDescriptionListPtrTy
3819 : ObjCTypes.MethodListPtrTy);
3826 values.addInt(ObjCTypes.IntTy, methods.size());
3827 auto methodArray = values.beginArray(ObjCTypes.MethodDescriptionTy);
3828 for (
auto MD : methods) {
3829 emitMethodDescriptionConstant(methodArray, MD);
3831 methodArray.finishAndAddTo(values);
3833 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
3835 return llvm::ConstantExpr::getBitCast(GV,
3836 ObjCTypes.MethodDescriptionListPtrTy);
3842 values.addNullPointer(ObjCTypes.Int8PtrTy);
3843 values.addInt(ObjCTypes.IntTy, methods.size());
3844 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
3845 for (
auto MD : methods) {
3846 emitMethodConstant(methodArray, MD);
3848 methodArray.finishAndAddTo(values);
3850 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
3852 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListPtrTy);
3855 llvm::Function *CGObjCCommonMac::GenerateMethod(
const ObjCMethodDecl *OMD,
3858 GetNameForMethod(OMD, CD, Name);
3861 llvm::FunctionType *MethodTy =
3863 llvm::Function *Method =
3868 MethodDefinitions.insert(std::make_pair(OMD, Method));
3873 llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
3878 llvm::GlobalVariable *GV =
3880 llvm::GlobalValue::PrivateLinkage);
3881 if (!Section.empty())
3882 GV->setSection(Section);
3888 llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
3889 llvm::Constant *Init,
3894 llvm::GlobalVariable *GV =
3895 new llvm::GlobalVariable(CGM.
getModule(), Ty,
false,
3896 llvm::GlobalValue::PrivateLinkage, Init, Name);
3897 if (!Section.empty())
3898 GV->setSection(Section);
3905 llvm::GlobalVariable *
3907 bool ForceNonFragileABI,
3908 bool NullTerminate) {
3911 case ObjCLabelType::ClassName: Label =
"OBJC_CLASS_NAME_";
break;
3912 case ObjCLabelType::MethodVarName: Label =
"OBJC_METH_VAR_NAME_";
break;
3913 case ObjCLabelType::MethodVarType: Label =
"OBJC_METH_VAR_TYPE_";
break;
3914 case ObjCLabelType::PropertyName: Label =
"OBJC_PROP_NAME_ATTR_";
break;
3917 bool NonFragile = ForceNonFragileABI || isNonFragileABI();
3921 case ObjCLabelType::ClassName:
3922 Section = NonFragile ?
"__TEXT,__objc_classname,cstring_literals" 3923 :
"__TEXT,__cstring,cstring_literals";
3925 case ObjCLabelType::MethodVarName:
3926 Section = NonFragile ?
"__TEXT,__objc_methname,cstring_literals" 3927 :
"__TEXT,__cstring,cstring_literals";
3929 case ObjCLabelType::MethodVarType:
3930 Section = NonFragile ?
"__TEXT,__objc_methtype,cstring_literals" 3931 :
"__TEXT,__cstring,cstring_literals";
3933 case ObjCLabelType::PropertyName:
3934 Section =
"__TEXT,__cstring,cstring_literals";
3938 llvm::Constant *
Value =
3939 llvm::ConstantDataArray::getString(VMContext, Name, NullTerminate);
3940 llvm::GlobalVariable *GV =
3941 new llvm::GlobalVariable(CGM.
getModule(), Value->getType(),
3943 llvm::GlobalValue::PrivateLinkage,
Value,
Label);
3944 if (CGM.
getTriple().isOSBinFormatMachO())
3945 GV->setSection(Section);
3946 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
3953 llvm::Function *CGObjCMac::ModuleInitFunction() {
3959 llvm::Constant *CGObjCMac::GetPropertyGetFunction() {
3960 return ObjCTypes.getGetPropertyFn();
3963 llvm::Constant *CGObjCMac::GetPropertySetFunction() {
3964 return ObjCTypes.getSetPropertyFn();
3967 llvm::Constant *CGObjCMac::GetOptimizedPropertySetFunction(
bool atomic,
3969 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
3972 llvm::Constant *CGObjCMac::GetGetStructFunction() {
3973 return ObjCTypes.getCopyStructFn();
3976 llvm::Constant *CGObjCMac::GetSetStructFunction() {
3977 return ObjCTypes.getCopyStructFn();
3980 llvm::Constant *CGObjCMac::GetCppAtomicObjectGetFunction() {
3981 return ObjCTypes.getCppAtomicObjectFunction();
3984 llvm::Constant *CGObjCMac::GetCppAtomicObjectSetFunction() {
3985 return ObjCTypes.getCppAtomicObjectFunction();
3988 llvm::Constant *CGObjCMac::EnumerationMutationFunction() {
3989 return ObjCTypes.getEnumerationMutationFn();
3993 return EmitTryOrSynchronizedStmt(CGF, S);
3998 return EmitTryOrSynchronizedStmt(CGF, S);
4007 ObjCTypesHelper &ObjCTypes;
4008 PerformFragileFinally(
const Stmt *S,
4012 ObjCTypesHelper *ObjCTypes)
4013 : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
4014 ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
4019 llvm::BasicBlock *FinallyCallExit =
4021 llvm::BasicBlock *FinallyNoCallExit =
4024 FinallyCallExit, FinallyNoCallExit);
4032 if (isa<ObjCAtTryStmt>(S)) {
4034 cast<ObjCAtTryStmt>(S).getFinallyStmt()) {
4036 if (flags.isForEHCleanup())
return;
4043 CGF.
EmitStmt(FinallyStmt->getFinallyBody());
4062 class FragileHazards {
4067 llvm::InlineAsm *ReadHazard;
4068 llvm::InlineAsm *WriteHazard;
4070 llvm::FunctionType *GetAsmFnType();
4072 void collectLocals();
4078 void emitWriteHazard();
4079 void emitHazardsInNewBlocks();
4091 if (Locals.empty())
return;
4094 for (llvm::Function::iterator
4095 I = CGF.
CurFn->begin(), E = CGF.
CurFn->end(); I != E; ++I)
4096 BlocksBeforeTry.insert(&*I);
4098 llvm::FunctionType *AsmFnTy = GetAsmFnType();
4106 std::string Constraint;
4107 for (
unsigned I = 0, E = Locals.size(); I != E; ++I) {
4108 if (I) Constraint +=
',';
4112 ReadHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
4120 std::string Constraint;
4121 for (
unsigned I = 0, E = Locals.size(); I != E; ++I) {
4122 if (I) Constraint +=
',';
4123 Constraint +=
"=*m";
4126 WriteHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
4131 void FragileHazards::emitWriteHazard() {
4132 if (Locals.empty())
return;
4137 void FragileHazards::emitReadHazard(
CGBuilderTy &Builder) {
4138 assert(!Locals.empty());
4139 llvm::CallInst *call = Builder.CreateCall(ReadHazard, Locals);
4140 call->setDoesNotThrow();
4146 void FragileHazards::emitHazardsInNewBlocks() {
4147 if (Locals.empty())
return;
4152 for (llvm::Function::iterator
4153 FI = CGF.
CurFn->begin(), FE = CGF.
CurFn->end(); FI != FE; ++FI) {
4154 llvm::BasicBlock &BB = *FI;
4155 if (BlocksBeforeTry.count(&BB))
continue;
4158 for (llvm::BasicBlock::iterator
4159 BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) {
4160 llvm::Instruction &I = *BI;
4164 if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I))
continue;
4165 if (isa<llvm::IntrinsicInst>(I))
4170 llvm::CallSite CS(&I);
4171 if (CS.doesNotThrow())
continue;
4178 Builder.SetInsertPoint(&BB, BI);
4179 emitReadHazard(Builder);
4188 void FragileHazards::collectLocals() {
4196 llvm::BasicBlock &Entry = CGF.
CurFn->getEntryBlock();
4197 for (llvm::BasicBlock::iterator
4198 I = Entry.begin(), E = Entry.end(); I != E; ++I)
4199 if (isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I))
4200 Locals.push_back(&*I);
4203 llvm::FunctionType *FragileHazards::GetAsmFnType() {
4205 for (
unsigned i = 0, e = Locals.size(); i != e; ++i)
4206 tys[i] = Locals[i]->getType();
4207 return llvm::FunctionType::get(CGF.
VoidTy, tys,
false);
4324 bool isTry = isa<ObjCAtTryStmt>(S);
4344 CGF.
EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
4357 "exceptiondata.ptr");
4363 FragileHazards Hazards(CGF);
4392 ExceptionData.getPointer());
4395 llvm::Constant *Zero = llvm::ConstantInt::get(CGF.
Builder.getInt32Ty(), 0);
4398 ObjCTypes.ExceptionDataTy, ExceptionData.getPointer(), GEPIndexes,
4401 ObjCTypes.getSetJmpFn(), SetJmpBuffer,
"setjmp_result");
4402 SetJmpResult->setCanReturnTwice();
4409 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
4410 CGF.
Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
4415 CGF.
EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
4416 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
4418 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.
Builder.saveAndClearIP();
4424 Hazards.emitWriteHazard();
4428 if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
4437 llvm::CallInst *Caught =
4439 ExceptionData.getPointer(),
"caught");
4449 llvm::BasicBlock *CatchBlock =
nullptr;
4450 llvm::BasicBlock *CatchHandler =
nullptr;
4456 "propagating_exception");
4462 ExceptionData.getPointer());
4464 llvm::CallInst *SetJmpResult =
4466 SetJmpBuffer,
"setjmp.result");
4467 SetJmpResult->setCanReturnTwice();
4470 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
4474 CGF.
Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
4484 bool AllMatched =
false;
4514 EmitInitOfCatchParam(CGF, Caught, CatchParam);
4526 assert(OPT &&
"Unexpected non-object pointer type in @catch");
4531 assert(IDecl &&
"Catch parameter must have Objective-C type!");
4537 llvm::CallInst *Match =
4539 matchArgs,
"match");
4544 CGF.
Builder.CreateCondBr(CGF.
Builder.CreateIsNotNull(Match,
"matched"),
4545 MatchedBlock, NextCatchBlock);
4561 EmitInitOfCatchParam(CGF, Tmp, CatchParam);
4577 if (Caught->use_empty())
4578 Caught->eraseFromParent();
4594 assert(PropagatingExnVar.
isValid());
4595 llvm::CallInst *NewCaught =
4597 ExceptionData.getPointer(),
"caught");
4607 Hazards.emitHazardsInNewBlocks();
4610 CGF.
Builder.restoreIP(TryFallthroughIP);
4614 CGF.
EmitBlock(FinallyEnd.getBlock(),
true);
4617 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
4622 if (PropagatingExnVar.
isValid()) {
4627 llvm::CallInst *Caught =
4629 ExceptionData.getPointer());
4630 PropagatingExn = Caught;
4635 CGF.
Builder.CreateUnreachable();
4638 CGF.
Builder.restoreIP(SavedIP);
4643 bool ClearInsertionPoint) {
4652 "Unexpected rethrow outside @catch block.");
4656 CGF.
EmitRuntimeCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
4657 ->setDoesNotReturn();
4658 CGF.
Builder.CreateUnreachable();
4661 if (ClearInsertionPoint)
4662 CGF.
Builder.ClearInsertionPoint();
4672 ObjCTypes.PtrObjectPtrTy);
4686 if (!isa<llvm::PointerType>(SrcTy)) {
4687 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(SrcTy);
4688 assert(Size <= 8 && "does not support size > 8
"); 4689 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty) 4690 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty); 4691 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 4693 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 4694 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 4695 llvm::Value *args[] = { src, dst.getPointer() }; 4696 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), 4697 args, "weakassign
"); 4703 void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
4704 llvm::Value *src, Address dst,
4706 llvm::Type * SrcTy = src->getType();
4707 if (!isa<llvm::PointerType>(SrcTy)) {
4708 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4709 assert(Size <= 8 && "does
not support size > 8
"); 4710 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty) 4711 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty); 4712 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 4714 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 4715 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 4716 llvm::Value *args[] = { src, dst.getPointer() }; 4718 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), 4719 args, "globalassign
"); 4721 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(), 4722 args, "threadlocalassign
"); 4728 void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
4729 llvm::Value *src, Address dst,
4730 llvm::Value *ivarOffset) {
4731 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is
NULL"); 4732 llvm::Type * SrcTy = src->getType(); 4733 if (!isa<llvm::PointerType>(SrcTy)) { 4734 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy); 4735 assert(Size <= 8 && "does
not support size > 8
"); 4736 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty) 4737 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty); 4738 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 4740 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 4741 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 4742 llvm::Value *args[] = { src, dst.getPointer(), ivarOffset }; 4743 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args); 4749 void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
4750 llvm::Value *src, Address dst) {
4751 llvm::Type * SrcTy = src->getType();
4752 if (!isa<llvm::PointerType>(SrcTy)) {
4753 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4754 assert(Size <= 8 && "does
not support size > 8
"); 4755 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty) 4756 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty); 4757 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 4759 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 4760 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 4761 llvm::Value *args[] = { src, dst.getPointer() }; 4762 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), 4763 args, "strongassign
"); 4766 void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, 4769 llvm::Value *size) { 4770 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy); 4771 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy); 4772 llvm::Value *args[] = { DestPtr.getPointer(), SrcPtr.getPointer(), size }; 4773 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args); 4778 LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
4780 llvm::Value *BaseValue,
4781 const ObjCIvarDecl *Ivar,
4782 unsigned CVRQualifiers) {
4783 const ObjCInterfaceDecl *ID =
4784 ObjectTy->getAs<ObjCObjectType>()->getInterface();
4785 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
4786 EmitIvarOffset(CGF, ID, Ivar));
4789 llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
4790 const ObjCInterfaceDecl *Interface,
4791 const ObjCIvarDecl *Ivar) {
4792 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
4793 return llvm::ConstantInt::get(
4794 CGM.getTypes().ConvertType(CGM.getContext().LongTy),
4798 /* *** Private Interface *** */
4800 std::string CGObjCCommonMac::GetSectionName(StringRef Section,
4801 StringRef MachOAttributes) {
4802 switch (CGM.getTriple().getObjectFormat()) {
4804 llvm_unreachable("unexpected
object file format
"); 4805 case llvm::Triple::MachO: { 4806 if (MachOAttributes.empty()) 4807 return ("__DATA,
" + Section).str(); 4808 return ("__DATA,
" + Section + ",
" + MachOAttributes).str(); 4810 case llvm::Triple::ELF: 4811 assert(Section.substr(0, 2) == "__
" && 4812 "expected the name to begin with __
"); 4813 return Section.substr(2).str(); 4814 case llvm::Triple::COFF: 4815 assert(Section.substr(0, 2) == "__
" && 4816 "expected the name to begin with __
"); 4817 return (".
" + Section.substr(2) + "$B
").str(); 4829 enum ImageInfoFlags {
4830 eImageInfo_FixAndContinue = (1 << 0), // This flag is no longer set by clang.
4831 eImageInfo_GarbageCollected = (1 << 1),
4832 eImageInfo_GCOnly = (1 << 2),
4833 eImageInfo_OptimizedByDyld = (1 << 3), // This flag is set by the dyld shared cache.
4835 // A flag indicating that the module has no instances of a @synthesize of a
4836 // superclass variable. <rdar://problem/6803242>
4837 eImageInfo_CorrectedSynthesize = (1 << 4), // This flag is no longer set by clang.
4838 eImageInfo_ImageIsSimulated = (1 << 5),
4839 eImageInfo_ClassProperties = (1 << 6)
4842 void CGObjCCommonMac::EmitImageInfo() {
4843 unsigned version = 0; // Version is unused?
4844 std::string Section =
4846 ? "__OBJC,__image_info,regular
" 4847 : GetSectionName("__objc_imageinfo
", "regular,no_dead_strip
"); 4849 // Generate module-level named metadata to convey this information to the 4850 // linker and code-gen. 4851 llvm::Module &Mod = CGM.getModule(); 4853 // Add the ObjC ABI version to the module flags. 4854 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Version
", ObjCABI); 4855 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Version
", 4857 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Section
", 4858 llvm::MDString::get(VMContext, Section)); 4860 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) { 4861 // Non-GC overrides those files which specify GC. 4862 Mod.addModuleFlag(llvm::Module::Override, 4863 "Objective-C Garbage Collection
", (uint32_t)0); 4865 // Add the ObjC garbage collection value. 4866 Mod.addModuleFlag(llvm::Module::Error, 4867 "Objective-C Garbage Collection
", 4868 eImageInfo_GarbageCollected); 4870 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) { 4871 // Add the ObjC GC Only value. 4872 Mod.addModuleFlag(llvm::Module::Error, "Objective-C GC Only
", 4875 // Require that GC be specified and set to eImageInfo_GarbageCollected. 4876 llvm::Metadata *Ops[2] = { 4877 llvm::MDString::get(VMContext, "Objective-C Garbage Collection
"), 4878 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( 4879 llvm::Type::getInt32Ty(VMContext), eImageInfo_GarbageCollected))}; 4880 Mod.addModuleFlag(llvm::Module::Require, "Objective-C GC Only
", 4881 llvm::MDNode::get(VMContext, Ops)); 4885 // Indicate whether we're compiling this to run on a simulator. 4886 if (CGM.getTarget().getTriple().isSimulatorEnvironment()) 4887 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Is Simulated
", 4888 eImageInfo_ImageIsSimulated); 4890 // Indicate whether we are generating class properties. 4891 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Class Properties
", 4892 eImageInfo_ClassProperties); 4895 // struct objc_module { 4896 // unsigned long version; 4897 // unsigned long size; 4898 // const char *name; 4902 // FIXME: Get from somewhere 4903 static const int ModuleVersion = 7; 4905 void CGObjCMac::EmitModuleInfo() { 4906 uint64_t Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ModuleTy); 4908 ConstantInitBuilder builder(CGM); 4909 auto values = builder.beginStruct(ObjCTypes.ModuleTy); 4910 values.addInt(ObjCTypes.LongTy, ModuleVersion); 4911 values.addInt(ObjCTypes.LongTy, Size); 4912 // This used to be the filename, now it is unused. <rdr://4327263> 4913 values.add(GetClassName(StringRef(""))); 4914 values.add(EmitModuleSymbols()); 4915 CreateMetadataVar("OBJC_MODULES
", values, 4916 "__OBJC,__module_info,regular,no_dead_strip
", 4917 CGM.getPointerAlign(), true); 4920 llvm::Constant *CGObjCMac::EmitModuleSymbols() { 4921 unsigned NumClasses = DefinedClasses.size(); 4922 unsigned NumCategories = DefinedCategories.size(); 4924 // Return null if no symbols were defined. 4925 if (!NumClasses && !NumCategories) 4926 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy); 4928 ConstantInitBuilder builder(CGM); 4929 auto values = builder.beginStruct(); 4930 values.addInt(ObjCTypes.LongTy, 0); 4931 values.addNullPointer(ObjCTypes.SelectorPtrTy); 4932 values.addInt(ObjCTypes.ShortTy, NumClasses); 4933 values.addInt(ObjCTypes.ShortTy, NumCategories); 4935 // The runtime expects exactly the list of defined classes followed 4936 // by the list of defined categories, in a single array. 4937 auto array = values.beginArray(ObjCTypes.Int8PtrTy); 4938 for (unsigned i=0; i<NumClasses; i++) { 4939 const ObjCInterfaceDecl *ID = ImplementedClasses[i]; 4941 if (ObjCImplementationDecl *IMP = ID->getImplementation()) 4942 // We are implementing a weak imported interface. Give it external linkage 4943 if (ID->isWeakImported() && !IMP->isWeakImported()) 4944 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage); 4946 array.addBitCast(DefinedClasses[i], ObjCTypes.Int8PtrTy); 4948 for (unsigned i=0; i<NumCategories; i++) 4949 array.addBitCast(DefinedCategories[i], ObjCTypes.Int8PtrTy); 4951 array.finishAndAddTo(values); 4953 llvm::GlobalVariable *GV = CreateMetadataVar( 4954 "OBJC_SYMBOLS
", values, "__OBJC,__symbols,regular,no_dead_strip
", 4955 CGM.getPointerAlign(), true); 4956 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy); 4959 llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF, 4960 IdentifierInfo *II) { 4961 LazySymbols.insert(II); 4963 llvm::GlobalVariable *&Entry = ClassReferences[II]; 4966 llvm::Constant *Casted = 4967 llvm::ConstantExpr::getBitCast(GetClassName(II->getName()), 4968 ObjCTypes.ClassPtrTy); 4969 Entry = CreateMetadataVar( 4970 "OBJC_CLASS_REFERENCES_
", Casted, 4971 "__OBJC,__cls_refs,literal_pointers,no_dead_strip
", 4972 CGM.getPointerAlign(), true); 4975 return CGF.Builder.CreateAlignedLoad(Entry, CGF.getPointerAlign()); 4978 llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF, 4979 const ObjCInterfaceDecl *ID) { 4980 // If the class has the objc_runtime_visible attribute, we need to 4981 // use the Objective-C runtime to get the class. 4982 if (ID->hasAttr<ObjCRuntimeVisibleAttr>()) 4983 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes); 4985 IdentifierInfo *RuntimeName = 4986 &CGM.getContext().Idents.get(ID->getObjCRuntimeNameAsString()); 4987 return EmitClassRefFromId(CGF, RuntimeName); 4990 llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) { 4991 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool
"); 4992 return EmitClassRefFromId(CGF, II); 4995 llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel) { 4996 return CGF.Builder.CreateLoad(EmitSelectorAddr(CGF, Sel)); 4999 Address CGObjCMac::EmitSelectorAddr(CodeGenFunction &CGF, Selector Sel) { 5000 CharUnits Align = CGF.getPointerAlign(); 5002 llvm::GlobalVariable *&Entry = SelectorReferences[Sel]; 5004 llvm::Constant *Casted = 5005 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel), 5006 ObjCTypes.SelectorPtrTy); 5007 Entry = CreateMetadataVar( 5008 "OBJC_SELECTOR_REFERENCES_
", Casted, 5009 "__OBJC,__message_refs,literal_pointers,no_dead_strip
", Align, true); 5010 Entry->setExternallyInitialized(true); 5013 return Address(Entry, Align); 5016 llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) { 5017 llvm::GlobalVariable *&Entry = ClassNames[RuntimeName]; 5019 Entry = CreateCStringLiteral(RuntimeName, ObjCLabelType::ClassName); 5020 return getConstantGEP(VMContext, Entry, 0, 0); 5023 llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) { 5024 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*>::iterator 5025 I = MethodDefinitions.find(MD); 5026 if (I != MethodDefinitions.end()) 5034 llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
5035 const ObjCCommonTypesHelper &ObjCTypes) {
5036 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
5039 void IvarLayoutBuilder::visitRecord(const RecordType *RT,
5041 const RecordDecl *RD = RT->getDecl();
5043 // If this is a union, remember that we had one, because it might mess
5044 // up the ordering of layout entries.
5046 IsDisordered = true;
5048 const ASTRecordLayout *recLayout = nullptr;
5049 visitAggregate(RD->field_begin(), RD->field_end(), offset,
5050 [&](const FieldDecl *field) -> CharUnits {
5052 recLayout = &CGM.getContext().getASTRecordLayout(RD);
5053 auto offsetInBits = recLayout->getFieldOffset(field->getFieldIndex());
5054 return CGM.getContext().toCharUnitsFromBits(offsetInBits);
5058 template <class Iterator, class GetOffsetFn>
5059 void IvarLayoutBuilder::visitAggregate(Iterator begin, Iterator end,
5060 CharUnits aggregateOffset,
5061 const GetOffsetFn &getOffset) {
5062 for (; begin != end; ++begin) {
5063 auto field = *begin;
5065 // Skip over bitfields.
5066 if (field->isBitField()) {
5070 // Compute the offset of the field within the aggregate.
5071 CharUnits fieldOffset = aggregateOffset + getOffset(field);
5073 visitField(field, fieldOffset);
5078 void IvarLayoutBuilder::visitField(const FieldDecl *field,
5079 CharUnits fieldOffset) {
5080 QualType fieldType = field->getType();
5082 // Drill down into arrays.
5083 uint64_t numElts = 1;
5084 if (auto arrayType = CGM.getContext().getAsIncompleteArrayType(fieldType)) {
5086 fieldType = arrayType->getElementType();
5088 // Unlike incomplete arrays, constant arrays can be nested.
5089 while (auto arrayType = CGM.getContext().getAsConstantArrayType(fieldType)) {
5090 numElts *= arrayType->getSize().getZExtValue();
5091 fieldType = arrayType->getElementType();
5094 assert(!fieldType->isArrayType() && "ivar of non-constant array
type?
"); 5096 // If we ended up with a zero-sized array, we've done what we can do within 5097 // the limits of this layout encoding. 5098 if (numElts == 0) return; 5100 // Recurse if the base element type is a record type. 5101 if (auto recType = fieldType->getAs<RecordType>()) { 5102 size_t oldEnd = IvarsInfo.size(); 5104 visitRecord(recType, fieldOffset); 5106 // If we have an array, replicate the first entry's layout information. 5107 auto numEltEntries = IvarsInfo.size() - oldEnd; 5108 if (numElts != 1 && numEltEntries != 0) { 5109 CharUnits eltSize = CGM.getContext().getTypeSizeInChars(recType); 5110 for (uint64_t eltIndex = 1; eltIndex != numElts; ++eltIndex) { 5111 // Copy the last numEltEntries onto the end of the array, adjusting 5112 // each for the element size. 5113 for (size_t i = 0; i != numEltEntries; ++i) { 5114 auto firstEntry = IvarsInfo[oldEnd + i]; 5115 IvarsInfo.push_back(IvarInfo(firstEntry.Offset + eltIndex * eltSize, 5116 firstEntry.SizeInWords)); 5124 // Classify the element type. 5125 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), fieldType); 5127 // If it matches what we're looking for, add an entry. 5128 if ((ForStrongLayout && GCAttr == Qualifiers::Strong) 5129 || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) { 5130 assert(CGM.getContext().getTypeSizeInChars(fieldType) 5131 == CGM.getPointerSize()); 5132 IvarsInfo.push_back(IvarInfo(fieldOffset, numElts)); 5139 llvm::Constant *IvarLayoutBuilder::buildBitmap(CGObjCCommonMac &CGObjC,
5140 llvm::SmallVectorImpl<unsigned char> &buffer) {
5141 // The bitmap is a series of skip/scan instructions, aligned to word
5142 // boundaries. The skip is performed first.
5143 const unsigned char MaxNibble = 0xF;
5144 const unsigned char SkipMask = 0xF0, SkipShift = 4;
5145 const unsigned char ScanMask = 0x0F, ScanShift = 0;
5147 assert(!IvarsInfo.empty() && "generating bitmap
for no data
"); 5149 // Sort the ivar info on byte position in case we encounterred a 5150 // union nested in the ivar list. 5152 // This isn't a stable sort, but our algorithm should handle it fine. 5153 llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end()); 5155 assert(std::is_sorted(IvarsInfo.begin(), IvarsInfo.end())); 5157 assert(IvarsInfo.back().Offset < InstanceEnd); 5159 assert(buffer.empty()); 5161 // Skip the next N words. 5162 auto skip = [&](unsigned numWords) { 5163 assert(numWords > 0); 5165 // Try to merge into the previous byte. Since scans happen second, we 5166 // can't do this if it includes a scan. 5167 if (!buffer.empty() && !(buffer.back() & ScanMask)) { 5168 unsigned lastSkip = buffer.back() >> SkipShift; 5169 if (lastSkip < MaxNibble) { 5170 unsigned claimed = std::min(MaxNibble - lastSkip, numWords); 5171 numWords -= claimed; 5172 lastSkip += claimed; 5173 buffer.back() = (lastSkip << SkipShift); 5177 while (numWords >= MaxNibble) { 5178 buffer.push_back(MaxNibble << SkipShift); 5179 numWords -= MaxNibble; 5182 buffer.push_back(numWords << SkipShift); 5186 // Scan the next N words. 5187 auto scan = [&](unsigned numWords) { 5188 assert(numWords > 0); 5190 // Try to merge into the previous byte. Since scans happen second, we can 5191 // do this even if it includes a skip. 5192 if (!buffer.empty()) { 5193 unsigned lastScan = (buffer.back() & ScanMask) >> ScanShift; 5194 if (lastScan < MaxNibble) { 5195 unsigned claimed = std::min(MaxNibble - lastScan, numWords); 5196 numWords -= claimed; 5197 lastScan += claimed; 5198 buffer.back() = (buffer.back() & SkipMask) | (lastScan << ScanShift); 5202 while (numWords >= MaxNibble) { 5203 buffer.push_back(MaxNibble << ScanShift); 5204 numWords -= MaxNibble; 5207 buffer.push_back(numWords << ScanShift); 5211 // One past the end of the last scan. 5212 unsigned endOfLastScanInWords = 0; 5213 const CharUnits WordSize = CGM.getPointerSize(); 5215 // Consider all the scan requests. 5216 for (auto &request : IvarsInfo) { 5217 CharUnits beginOfScan = request.Offset - InstanceBegin; 5219 // Ignore scan requests that don't start at an even multiple of the 5220 // word size. We can't encode them. 5221 if ((beginOfScan % WordSize) != 0) continue; 5223 // Ignore scan requests that start before the instance start. 5224 // This assumes that scans never span that boundary. The boundary 5225 // isn't the true start of the ivars, because in the fragile-ARC case 5226 // it's rounded up to word alignment, but the test above should leave 5227 // us ignoring that possibility. 5228 if (beginOfScan.isNegative()) { 5229 assert(request.Offset + request.SizeInWords * WordSize <= InstanceBegin); 5233 unsigned beginOfScanInWords = beginOfScan / WordSize; 5234 unsigned endOfScanInWords = beginOfScanInWords + request.SizeInWords; 5236 // If the scan starts some number of words after the last one ended, 5238 if (beginOfScanInWords > endOfLastScanInWords) { 5239 skip(beginOfScanInWords - endOfLastScanInWords); 5241 // Otherwise, start scanning where the last left off. 5243 beginOfScanInWords = endOfLastScanInWords; 5245 // If that leaves us with nothing to scan, ignore this request. 5246 if (beginOfScanInWords >= endOfScanInWords) continue; 5249 // Scan to the end of the request. 5250 assert(beginOfScanInWords < endOfScanInWords); 5251 scan(endOfScanInWords - beginOfScanInWords); 5252 endOfLastScanInWords = endOfScanInWords; 5256 return llvm::ConstantPointerNull::get(CGM.Int8PtrTy); 5258 // For GC layouts, emit a skip to the end of the allocation so that we 5259 // have precise information about the entire thing. This isn't useful 5260 // or necessary for the ARC-style layout strings. 5261 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) { 5262 unsigned lastOffsetInWords = 5263 (InstanceEnd - InstanceBegin + WordSize - CharUnits::One()) / WordSize; 5264 if (lastOffsetInWords > endOfLastScanInWords) { 5265 skip(lastOffsetInWords - endOfLastScanInWords); 5269 // Null terminate the string. 5270 buffer.push_back(0); 5272 auto *Entry = CGObjC.CreateCStringLiteral( 5273 reinterpret_cast<char *>(buffer.data()), ObjCLabelType::ClassName); 5274 return getConstantGEP(CGM.getLLVMContext(), Entry, 0, 0); 5294 CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD,
5295 CharUnits beginOffset, CharUnits endOffset,
5296 bool ForStrongLayout, bool HasMRCWeakIvars) {
5297 // If this is MRC, and we're either building a strong layout or there
5298 // are no weak ivars, bail out early.
5299 llvm::Type *PtrTy = CGM.Int8PtrTy;
5300 if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
5301 !CGM.getLangOpts().ObjCAutoRefCount &&
5302 (ForStrongLayout || !HasMRCWeakIvars))
5303 return llvm::Constant::getNullValue(PtrTy);
5305 const ObjCInterfaceDecl *OI = OMD->getClassInterface();
5306 SmallVector<const ObjCIvarDecl*, 32> ivars;
5308 // GC layout strings include the complete object layout, possibly
5309 // inaccurately in the non-fragile ABI; the runtime knows how to fix this
5312 // ARC layout strings only include the class's ivars. In non-fragile
5313 // runtimes, that means starting at InstanceStart, rounded up to word
5314 // alignment. In fragile runtimes, there's no InstanceStart, so it means
5315 // starting at the offset of the first ivar, rounded up to word alignment.
5317 // MRC weak layout strings follow the ARC style.
5318 CharUnits baseOffset;
5319 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
5320 for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();
5321 IVD; IVD = IVD->getNextIvar())
5322 ivars.push_back(IVD);
5324 if (isNonFragileABI()) {
5325 baseOffset = beginOffset; // InstanceStart
5326 } else if (!ivars.empty()) {
5328 CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivars[0]));
5330 baseOffset = CharUnits::Zero();
5333 baseOffset = baseOffset.alignTo(CGM.getPointerAlign());
5336 CGM.getContext().DeepCollectObjCIvars(OI, true, ivars);
5338 baseOffset = CharUnits::Zero();
5342 return llvm::Constant::getNullValue(PtrTy);
5344 IvarLayoutBuilder builder(CGM, baseOffset, endOffset, ForStrongLayout);
5346 builder.visitAggregate(ivars.begin(), ivars.end(), CharUnits::Zero(),
5347 [&](const ObjCIvarDecl *ivar) -> CharUnits {
5348 return CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivar));
5351 if (!builder.hasBitmapData())
5352 return llvm::Constant::getNullValue(PtrTy);
5354 llvm::SmallVector<unsigned char, 4> buffer;
5355 llvm::Constant *C = builder.buildBitmap(*this, buffer);
5357 if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
5358 printf("\n%s ivar layout
for class '%s':
", 5359 ForStrongLayout ? "strong
" : "weak
", 5360 OMD->getClassInterface()->getName().str().c_str()); 5361 builder.dump(buffer); 5366 llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) { 5367 llvm::GlobalVariable *&Entry = MethodVarNames[Sel]; 5368 // FIXME: Avoid std::string in "Sel.getAsString()
" 5370 Entry = CreateCStringLiteral(Sel.getAsString(), ObjCLabelType::MethodVarName); 5371 return getConstantGEP(VMContext, Entry, 0, 0); 5374 // FIXME: Merge into a single cstring creation function. 5375 llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) { 5376 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID)); 5379 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) { 5380 std::string TypeStr; 5381 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field); 5383 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr]; 5385 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType); 5386 return getConstantGEP(VMContext, Entry, 0, 0); 5389 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D, 5391 std::string TypeStr = 5392 CGM.getContext().getObjCEncodingForMethodDecl(D, Extended); 5394 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr]; 5396 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType); 5397 return getConstantGEP(VMContext, Entry, 0, 0); 5400 // FIXME: Merge into a single cstring creation function. 5401 llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) { 5402 llvm::GlobalVariable *&Entry = PropertyNames[Ident]; 5404 Entry = CreateCStringLiteral(Ident->getName(), ObjCLabelType::PropertyName); 5405 return getConstantGEP(VMContext, Entry, 0, 0); 5408 // FIXME: Merge into a single cstring creation function. 5409 // FIXME: This Decl should be more precise. 5411 CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD, 5412 const Decl *Container) { 5413 std::string TypeStr = 5414 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container); 5415 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr)); 5418 void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D, 5419 const ObjCContainerDecl *CD, 5420 SmallVectorImpl<char> &Name) { 5421 llvm::raw_svector_ostream OS(Name); 5422 assert (CD && "Missing container
decl in GetNameForMethod
"); 5423 OS << '\01' << (D->isInstanceMethod() ? '-' : '+') 5424 << '[' << CD->getName(); 5425 if (const ObjCCategoryImplDecl *CID = 5426 dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext())) 5427 OS << '(' << *CID << ')'; 5428 OS << ' ' << D->getSelector().getAsString() << ']'; 5431 void CGObjCMac::FinishModule() { 5434 // Emit the dummy bodies for any protocols which were referenced but 5436 for (auto &entry : Protocols) { 5437 llvm::GlobalVariable *global = entry.second; 5438 if (global->hasInitializer()) 5441 ConstantInitBuilder builder(CGM); 5442 auto values = builder.beginStruct(ObjCTypes.ProtocolTy); 5443 values.addNullPointer(ObjCTypes.ProtocolExtensionPtrTy); 5444 values.add(GetClassName(entry.first->getName())); 5445 values.addNullPointer(ObjCTypes.ProtocolListPtrTy); 5446 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy); 5447 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy); 5448 values.finishAndSetAsInitializer(global); 5449 CGM.addCompilerUsedGlobal(global); 5452 // Add assembler directives to add lazy undefined symbol references 5453 // for classes which are referenced but not defined. This is 5454 // important for correct linker interaction. 5456 // FIXME: It would be nice if we had an LLVM construct for this. 5457 if ((!LazySymbols.empty() || !DefinedSymbols.empty()) && 5458 CGM.getTriple().isOSBinFormatMachO()) { 5459 SmallString<256> Asm; 5460 Asm += CGM.getModule().getModuleInlineAsm(); 5461 if (!Asm.empty() && Asm.back() != '\n') 5464 llvm::raw_svector_ostream OS(Asm); 5465 for (const auto *Sym : DefinedSymbols) 5466 OS << "\t.objc_class_name_
" << Sym->getName() << "=0\n
" 5467 << "\t.globl .objc_class_name_
" << Sym->getName() << "\n
"; 5468 for (const auto *Sym : LazySymbols) 5469 OS << "\t.lazy_reference .objc_class_name_
" << Sym->getName() << "\n
"; 5470 for (const auto &Category : DefinedCategoryNames) 5471 OS << "\t.objc_category_name_
" << Category << "=0\n
" 5472 << "\t.globl .objc_category_name_
" << Category << "\n
"; 5474 CGM.getModule().setModuleInlineAsm(OS.str()); 5478 CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm) 5479 : CGObjCCommonMac(cgm), ObjCTypes(cgm), ObjCEmptyCacheVar(nullptr), 5480 ObjCEmptyVtableVar(nullptr) { 5486 ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm) 5487 : VMContext(cgm.getLLVMContext()), CGM(cgm), ExternalProtocolPtrTy(nullptr) 5489 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 5490 ASTContext &Ctx = CGM.getContext(); 5492 ShortTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.ShortTy)); 5494 LongTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.LongTy)); 5495 Int8PtrTy = CGM.Int8PtrTy; 5496 Int8PtrPtrTy = CGM.Int8PtrPtrTy; 5498 // arm64 targets use "int" ivar offset variables. All others, 5499 // including OS X x86_64 and Windows x86_64, use "long" ivar offsets. 5500 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::aarch64) 5501 IvarOffsetVarTy = IntTy; 5503 IvarOffsetVarTy = LongTy; 5506 cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCIdType())); 5508 llvm::PointerType::getUnqual(ObjectPtrTy); 5510 cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCSelType())); 5512 // I'm not sure I like this. The implicit coordination is a bit 5513 // gross. We should solve this in a reasonable fashion because this 5514 // is a pretty common task (match some runtime data structure with 5515 // an LLVM data structure). 5517 // FIXME: This is leaked. 5518 // FIXME: Merge with rewriter code? 5520 // struct _objc_super { 5524 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct, 5525 Ctx.getTranslationUnitDecl(), 5526 SourceLocation(), SourceLocation(), 5527 &Ctx.Idents.get("_objc_super
")); 5528 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 5529 nullptr, Ctx.getObjCIdType(), nullptr, nullptr, 5530 false, ICIS_NoInit)); 5531 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 5532 nullptr, Ctx.getObjCClassType(), nullptr, 5533 nullptr, false, ICIS_NoInit)); 5534 RD->completeDefinition(); 5536 SuperCTy = Ctx.getTagDeclType(RD); 5537 SuperPtrCTy = Ctx.getPointerType(SuperCTy); 5539 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy)); 5540 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy); 5544 // char *attributes; 5546 PropertyTy = llvm::StructType::create("struct._prop_t
", Int8PtrTy, Int8PtrTy); 5548 // struct _prop_list_t { 5549 // uint32_t entsize; // sizeof(struct _prop_t) 5550 // uint32_t count_of_properties; 5551 // struct _prop_t prop_list[count_of_properties]; 5553 PropertyListTy = llvm::StructType::create( 5554 "struct._prop_list_t
", IntTy, IntTy, llvm::ArrayType::get(PropertyTy, 0)); 5555 // struct _prop_list_t * 5556 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy); 5558 // struct _objc_method { 5560 // char *method_type; 5563 MethodTy = llvm::StructType::create("struct._objc_method
", SelectorPtrTy, 5564 Int8PtrTy, Int8PtrTy); 5566 // struct _objc_cache * 5567 CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache
"); 5568 CachePtrTy = llvm::PointerType::getUnqual(CacheTy); 5571 ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) 5572 : ObjCCommonTypesHelper(cgm) { 5573 // struct _objc_method_description { 5577 MethodDescriptionTy = llvm::StructType::create( 5578 "struct._objc_method_description
", SelectorPtrTy, Int8PtrTy); 5580 // struct _objc_method_description_list { 5582 // struct _objc_method_description[1]; 5584 MethodDescriptionListTy = 5585 llvm::StructType::create("struct._objc_method_description_list
", IntTy, 5586 llvm::ArrayType::get(MethodDescriptionTy, 0)); 5588 // struct _objc_method_description_list * 5589 MethodDescriptionListPtrTy = 5590 llvm::PointerType::getUnqual(MethodDescriptionListTy); 5592 // Protocol description structures 5594 // struct _objc_protocol_extension { 5595 // uint32_t size; // sizeof(struct _objc_protocol_extension) 5596 // struct _objc_method_description_list *optional_instance_methods; 5597 // struct _objc_method_description_list *optional_class_methods; 5598 // struct _objc_property_list *instance_properties; 5599 // const char ** extendedMethodTypes; 5600 // struct _objc_property_list *class_properties; 5602 ProtocolExtensionTy = llvm::StructType::create( 5603 "struct._objc_protocol_extension
", IntTy, MethodDescriptionListPtrTy, 5604 MethodDescriptionListPtrTy, PropertyListPtrTy, Int8PtrPtrTy, 5607 // struct _objc_protocol_extension * 5608 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy); 5610 // Handle recursive construction of Protocol and ProtocolList types 5613 llvm::StructType::create(VMContext, "struct._objc_protocol
"); 5616 llvm::StructType::create(VMContext, "struct._objc_protocol_list
"); 5617 ProtocolListTy->setBody(llvm::PointerType::getUnqual(ProtocolListTy), LongTy, 5618 llvm::ArrayType::get(ProtocolTy, 0)); 5620 // struct _objc_protocol { 5621 // struct _objc_protocol_extension *isa; 5622 // char *protocol_name; 5623 // struct _objc_protocol **_objc_protocol_list; 5624 // struct _objc_method_description_list *instance_methods; 5625 // struct _objc_method_description_list *class_methods; 5627 ProtocolTy->setBody(ProtocolExtensionPtrTy, Int8PtrTy, 5628 llvm::PointerType::getUnqual(ProtocolListTy), 5629 MethodDescriptionListPtrTy, MethodDescriptionListPtrTy); 5631 // struct _objc_protocol_list * 5632 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy); 5634 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy); 5636 // Class description structures 5638 // struct _objc_ivar { 5643 IvarTy = llvm::StructType::create("struct._objc_ivar
", Int8PtrTy, Int8PtrTy, 5646 // struct _objc_ivar_list * 5648 llvm::StructType::create(VMContext, "struct._objc_ivar_list
"); 5649 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy); 5651 // struct _objc_method_list * 5653 llvm::StructType::create(VMContext, "struct._objc_method_list
"); 5654 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy); 5656 // struct _objc_class_extension * 5657 ClassExtensionTy = llvm::StructType::create( 5658 "struct._objc_class_extension
", IntTy, Int8PtrTy, PropertyListPtrTy); 5659 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy); 5661 ClassTy = llvm::StructType::create(VMContext, "struct._objc_class
"); 5663 // struct _objc_class { 5665 // Class super_class; 5669 // long instance_size; 5670 // struct _objc_ivar_list *ivars; 5671 // struct _objc_method_list *methods; 5672 // struct _objc_cache *cache; 5673 // struct _objc_protocol_list *protocols; 5674 // char *ivar_layout; 5675 // struct _objc_class_ext *ext; 5677 ClassTy->setBody(llvm::PointerType::getUnqual(ClassTy), 5678 llvm::PointerType::getUnqual(ClassTy), Int8PtrTy, LongTy, 5679 LongTy, LongTy, IvarListPtrTy, MethodListPtrTy, CachePtrTy, 5680 ProtocolListPtrTy, Int8PtrTy, ClassExtensionPtrTy); 5682 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy); 5684 // struct _objc_category { 5685 // char *category_name; 5686 // char *class_name; 5687 // struct _objc_method_list *instance_method; 5688 // struct _objc_method_list *class_method; 5689 // struct _objc_protocol_list *protocols; 5690 // uint32_t size; // sizeof(struct _objc_category) 5691 // struct _objc_property_list *instance_properties;// category's @property 5692 // struct _objc_property_list *class_properties; 5694 CategoryTy = llvm::StructType::create( 5695 "struct._objc_category
", Int8PtrTy, Int8PtrTy, MethodListPtrTy, 5696 MethodListPtrTy, ProtocolListPtrTy, IntTy, PropertyListPtrTy, 5699 // Global metadata structures 5701 // struct _objc_symtab { 5702 // long sel_ref_cnt; 5704 // short cls_def_cnt; 5705 // short cat_def_cnt; 5706 // char *defs[cls_def_cnt + cat_def_cnt]; 5708 SymtabTy = llvm::StructType::create("struct._objc_symtab
", LongTy, 5709 SelectorPtrTy, ShortTy, ShortTy, 5710 llvm::ArrayType::get(Int8PtrTy, 0)); 5711 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy); 5713 // struct _objc_module { 5715 // long size; // sizeof(struct _objc_module) 5717 // struct _objc_symtab* symtab; 5719 ModuleTy = llvm::StructType::create("struct._objc_module
", LongTy, LongTy, 5720 Int8PtrTy, SymtabPtrTy); 5722 // FIXME: This is the size of the setjmp buffer and should be target 5723 // specific. 18 is what's used on 32-bit X86. 5724 uint64_t SetJmpBufferSize = 18; 5727 llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4); 5729 ExceptionDataTy = llvm::StructType::create( 5730 "struct._objc_exception_data
", 5731 llvm::ArrayType::get(CGM.Int32Ty, SetJmpBufferSize), StackPtrTy); 5734 ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm) 5735 : ObjCCommonTypesHelper(cgm) { 5736 // struct _method_list_t { 5737 // uint32_t entsize; // sizeof(struct _objc_method) 5738 // uint32_t method_count; 5739 // struct _objc_method method_list[method_count]; 5742 llvm::StructType::create("struct.__method_list_t
", IntTy, IntTy, 5743 llvm::ArrayType::get(MethodTy, 0)); 5744 // struct method_list_t * 5745 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy); 5747 // struct _protocol_t { 5749 // const char * const protocol_name; 5750 // const struct _protocol_list_t * protocol_list; // super protocols 5751 // const struct method_list_t * const instance_methods; 5752 // const struct method_list_t * const class_methods; 5753 // const struct method_list_t *optionalInstanceMethods; 5754 // const struct method_list_t *optionalClassMethods; 5755 // const struct _prop_list_t * properties; 5756 // const uint32_t size; // sizeof(struct _protocol_t) 5757 // const uint32_t flags; // = 0 5758 // const char ** extendedMethodTypes; 5759 // const char *demangledName; 5760 // const struct _prop_list_t * class_properties; 5763 // Holder for struct _protocol_list_t * 5764 ProtocolListnfABITy = 5765 llvm::StructType::create(VMContext, "struct._objc_protocol_list
"); 5767 ProtocolnfABITy = llvm::StructType::create( 5768 "struct._protocol_t
", ObjectPtrTy, Int8PtrTy, 5769 llvm::PointerType::getUnqual(ProtocolListnfABITy), MethodListnfABIPtrTy, 5770 MethodListnfABIPtrTy, MethodListnfABIPtrTy, MethodListnfABIPtrTy, 5771 PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy, Int8PtrTy, 5774 // struct _protocol_t* 5775 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy); 5777 // struct _protocol_list_t { 5778 // long protocol_count; // Note, this is 32/64 bit 5779 // struct _protocol_t *[protocol_count]; 5781 ProtocolListnfABITy->setBody(LongTy, 5782 llvm::ArrayType::get(ProtocolnfABIPtrTy, 0)); 5784 // struct _objc_protocol_list* 5785 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy); 5788 // unsigned [long] int *offset; // pointer to ivar offset location 5791 // uint32_t alignment; 5794 IvarnfABITy = llvm::StructType::create( 5795 "struct._ivar_t
", llvm::PointerType::getUnqual(IvarOffsetVarTy), 5796 Int8PtrTy, Int8PtrTy, IntTy, IntTy); 5798 // struct _ivar_list_t { 5799 // uint32 entsize; // sizeof(struct _ivar_t) 5801 // struct _iver_t list[count]; 5804 llvm::StructType::create("struct._ivar_list_t
", IntTy, IntTy, 5805 llvm::ArrayType::get(IvarnfABITy, 0)); 5807 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy); 5809 // struct _class_ro_t { 5810 // uint32_t const flags; 5811 // uint32_t const instanceStart; 5812 // uint32_t const instanceSize; 5813 // uint32_t const reserved; // only when building for 64bit targets 5814 // const uint8_t * const ivarLayout; 5815 // const char *const name; 5816 // const struct _method_list_t * const baseMethods; 5817 // const struct _objc_protocol_list *const baseProtocols; 5818 // const struct _ivar_list_t *const ivars; 5819 // const uint8_t * const weakIvarLayout; 5820 // const struct _prop_list_t * const properties; 5823 // FIXME. Add 'reserved' field in 64bit abi mode! 5824 ClassRonfABITy = llvm::StructType::create( 5825 "struct._class_ro_t
", IntTy, IntTy, IntTy, Int8PtrTy, Int8PtrTy, 5826 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, IvarListnfABIPtrTy, 5827 Int8PtrTy, PropertyListPtrTy); 5829 // ImpnfABITy - LLVM for id (*)(id, SEL, ...) 5830 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy }; 5831 ImpnfABITy = llvm::FunctionType::get(ObjectPtrTy, params, false) 5834 // struct _class_t { 5835 // struct _class_t *isa; 5836 // struct _class_t * const superclass; 5839 // struct class_ro_t *ro; 5842 ClassnfABITy = llvm::StructType::create(VMContext, "struct._class_t
"); 5843 ClassnfABITy->setBody(llvm::PointerType::getUnqual(ClassnfABITy), 5844 llvm::PointerType::getUnqual(ClassnfABITy), CachePtrTy, 5845 llvm::PointerType::getUnqual(ImpnfABITy), 5846 llvm::PointerType::getUnqual(ClassRonfABITy)); 5848 // LLVM for struct _class_t * 5849 ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy); 5851 // struct _category_t { 5852 // const char * const name; 5853 // struct _class_t *const cls; 5854 // const struct _method_list_t * const instance_methods; 5855 // const struct _method_list_t * const class_methods; 5856 // const struct _protocol_list_t * const protocols; 5857 // const struct _prop_list_t * const properties; 5858 // const struct _prop_list_t * const class_properties; 5859 // const uint32_t size; 5861 CategorynfABITy = llvm::StructType::create( 5862 "struct._category_t
", Int8PtrTy, ClassnfABIPtrTy, MethodListnfABIPtrTy, 5863 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, PropertyListPtrTy, 5864 PropertyListPtrTy, IntTy); 5866 // New types for nonfragile abi messaging. 5867 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 5868 ASTContext &Ctx = CGM.getContext(); 5870 // MessageRefTy - LLVM for: 5871 // struct _message_ref_t { 5876 // First the clang type for struct _message_ref_t 5877 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct, 5878 Ctx.getTranslationUnitDecl(), 5879 SourceLocation(), SourceLocation(), 5880 &Ctx.Idents.get("_message_ref_t
")); 5881 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 5882 nullptr, Ctx.VoidPtrTy, nullptr, nullptr, false, 5884 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 5885 nullptr, Ctx.getObjCSelType(), nullptr, nullptr, 5886 false, ICIS_NoInit)); 5887 RD->completeDefinition(); 5889 MessageRefCTy = Ctx.getTagDeclType(RD); 5890 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy); 5891 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy)); 5893 // MessageRefPtrTy - LLVM for struct _message_ref_t* 5894 MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy); 5896 // SuperMessageRefTy - LLVM for: 5897 // struct _super_message_ref_t { 5898 // SUPER_IMP messenger; 5901 SuperMessageRefTy = llvm::StructType::create("struct._super_message_ref_t
", 5902 ImpnfABITy, SelectorPtrTy); 5904 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t* 5905 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy); 5908 // struct objc_typeinfo { 5909 // const void** vtable; // objc_ehtype_vtable + 2 5910 // const char* name; // c++ typeinfo string 5913 EHTypeTy = llvm::StructType::create("struct._objc_typeinfo
", 5914 llvm::PointerType::getUnqual(Int8PtrTy), 5915 Int8PtrTy, ClassnfABIPtrTy); 5916 EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy); 5919 llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() { 5920 FinishNonFragileABIModule(); 5925 void CGObjCNonFragileABIMac::AddModuleClassList( 5926 ArrayRef<llvm::GlobalValue *> Container, StringRef SymbolName, 5927 StringRef SectionName) { 5928 unsigned NumClasses = Container.size(); 5933 SmallVector<llvm::Constant*, 8> Symbols(NumClasses); 5934 for (unsigned i=0; i<NumClasses; i++) 5935 Symbols[i] = llvm::ConstantExpr::getBitCast(Container[i], 5936 ObjCTypes.Int8PtrTy); 5937 llvm::Constant *Init = 5938 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy, 5942 llvm::GlobalVariable *GV = 5943 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, 5944 llvm::GlobalValue::PrivateLinkage, 5947 GV->setAlignment(CGM.getDataLayout().getABITypeAlignment(Init->getType())); 5948 GV->setSection(SectionName); 5949 CGM.addCompilerUsedGlobal(GV); 5952 void CGObjCNonFragileABIMac::FinishNonFragileABIModule() { 5953 // nonfragile abi has no module definition. 5955 // Build list of all implemented class addresses in array 5956 // L_OBJC_LABEL_CLASS_$. 5958 for (unsigned i=0, NumClasses=ImplementedClasses.size(); i<NumClasses; i++) { 5959 const ObjCInterfaceDecl *ID = ImplementedClasses[i]; 5961 if (ObjCImplementationDecl *IMP = ID->getImplementation()) 5962 // We are implementing a weak imported interface. Give it external linkage 5963 if (ID->isWeakImported() && !IMP->isWeakImported()) { 5964 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage); 5965 DefinedMetaClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage); 5969 AddModuleClassList(DefinedClasses, "OBJC_LABEL_CLASS_$
", 5970 GetSectionName("__objc_classlist
", 5971 "regular,no_dead_strip
")); 5973 AddModuleClassList(DefinedNonLazyClasses, "OBJC_LABEL_NONLAZY_CLASS_$
", 5974 GetSectionName("__objc_nlclslist
", 5975 "regular,no_dead_strip
")); 5977 // Build list of all implemented category addresses in array 5978 // L_OBJC_LABEL_CATEGORY_$. 5979 AddModuleClassList(DefinedCategories, "OBJC_LABEL_CATEGORY_$
", 5980 GetSectionName("__objc_catlist
", 5981 "regular,no_dead_strip
")); 5982 AddModuleClassList(DefinedNonLazyCategories, "OBJC_LABEL_NONLAZY_CATEGORY_$
", 5983 GetSectionName("__objc_nlcatlist
", 5984 "regular,no_dead_strip
")); 5993 bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
5994 // At various points we've experimented with using vtable-based
5995 // dispatch for all methods.
5996 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
5997 case CodeGenOptions::Legacy:
5999 case CodeGenOptions::NonLegacy:
6001 case CodeGenOptions::Mixed:
6005 // If so, see whether this selector is in the white-list of things which must
6006 // use the new dispatch convention. We lazily build a dense set for this.
6007 if (VTableDispatchMethods.empty()) {
6008 VTableDispatchMethods.insert(GetNullarySelector("alloc
")); 6009 VTableDispatchMethods.insert(GetNullarySelector("class")); 6010 VTableDispatchMethods.insert(GetNullarySelector("self")); 6011 VTableDispatchMethods.insert(GetNullarySelector("isFlipped
")); 6012 VTableDispatchMethods.insert(GetNullarySelector("length")); 6013 VTableDispatchMethods.insert(GetNullarySelector("count
")); 6015 // These are vtable-based if GC is disabled. 6016 // Optimistically use vtable dispatch for hybrid compiles. 6017 if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) { 6018 VTableDispatchMethods.insert(GetNullarySelector("retain
")); 6019 VTableDispatchMethods.insert(GetNullarySelector("release
")); 6020 VTableDispatchMethods.insert(GetNullarySelector("autorelease
")); 6023 VTableDispatchMethods.insert(GetUnarySelector("allocWithZone
")); 6024 VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass
")); 6025 VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector
")); 6026 VTableDispatchMethods.insert(GetUnarySelector("objectForKey
")); 6027 VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex
")); 6028 VTableDispatchMethods.insert(GetUnarySelector("isEqualToString
")); 6029 VTableDispatchMethods.insert(GetUnarySelector("isEqual
")); 6031 // These are vtable-based if GC is enabled. 6032 // Optimistically use vtable dispatch for hybrid compiles. 6033 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) { 6034 VTableDispatchMethods.insert(GetNullarySelector("hash
")); 6035 VTableDispatchMethods.insert(GetUnarySelector("addObject
")); 6037 // "countByEnumeratingWithState:objects:count
" 6038 IdentifierInfo *KeyIdents[] = { 6039 &CGM.getContext().Idents.get("countByEnumeratingWithState
"), 6040 &CGM.getContext().Idents.get("objects
"), 6041 &CGM.getContext().Idents.get("count
") 6043 VTableDispatchMethods.insert( 6044 CGM.getContext().Selectors.getSelector(3, KeyIdents)); 6048 return VTableDispatchMethods.count(Sel); 6066 llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
6068 unsigned InstanceStart,
6069 unsigned InstanceSize,
6070 const ObjCImplementationDecl *ID) {
6071 std::string ClassName = ID->getObjCRuntimeNameAsString();
6073 CharUnits beginInstance = CharUnits::fromQuantity(InstanceStart);
6074 CharUnits endInstance = CharUnits::fromQuantity(InstanceSize);
6076 bool hasMRCWeak = false;
6077 if (CGM.getLangOpts().ObjCAutoRefCount)
6078 flags |= NonFragileABI_Class_CompiledByARC;
6079 else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))
6080 flags |= NonFragileABI_Class_HasMRCWeakIvars;
6082 ConstantInitBuilder builder(CGM);
6083 auto values = builder.beginStruct(ObjCTypes.ClassRonfABITy);
6085 values.addInt(ObjCTypes.IntTy, flags);
6086 values.addInt(ObjCTypes.IntTy, InstanceStart);
6087 values.addInt(ObjCTypes.IntTy, InstanceSize);
6088 values.add((flags & NonFragileABI_Class_Meta)
6089 ? GetIvarLayoutName(nullptr, ObjCTypes)
6090 : BuildStrongIvarLayout(ID, beginInstance, endInstance));
6091 values.add(GetClassName(ID->getObjCRuntimeNameAsString()));
6093 // const struct _method_list_t * const baseMethods;
6094 SmallVector<const ObjCMethodDecl*, 16> methods;
6095 if (flags & NonFragileABI_Class_Meta) {
6096 for (const auto *MD : ID->class_methods())
6097 methods.push_back(MD);
6099 for (const auto *MD : ID->instance_methods())
6100 methods.push_back(MD);
6102 for (const auto *PID : ID->property_impls()) {
6103 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){
6104 ObjCPropertyDecl *PD = PID->getPropertyDecl();
6106 if (auto MD = PD->getGetterMethodDecl())
6107 if (GetMethodDefinition(MD))
6108 methods.push_back(MD);
6109 if (auto MD = PD->getSetterMethodDecl())
6110 if (GetMethodDefinition(MD))
6111 methods.push_back(MD);
6116 values.add(emitMethodList(ID->getObjCRuntimeNameAsString(),
6117 (flags & NonFragileABI_Class_Meta)
6118 ? MethodListType::ClassMethods
6119 : MethodListType::InstanceMethods,
6122 const ObjCInterfaceDecl *OID = ID->getClassInterface();
6123 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer
"); 6124 values.add(EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_
" 6125 + OID->getObjCRuntimeNameAsString(), 6126 OID->all_referenced_protocol_begin(), 6127 OID->all_referenced_protocol_end())); 6129 if (flags & NonFragileABI_Class_Meta) { 6130 values.addNullPointer(ObjCTypes.IvarListnfABIPtrTy); 6131 values.add(GetIvarLayoutName(nullptr, ObjCTypes)); 6132 values.add(EmitPropertyList( 6133 "\01l_OBJC_$_CLASS_PROP_LIST_
" + ID->getObjCRuntimeNameAsString(), 6134 ID, ID->getClassInterface(), ObjCTypes, true)); 6136 values.add(EmitIvarList(ID)); 6137 values.add(BuildWeakIvarLayout(ID, beginInstance, endInstance, hasMRCWeak)); 6138 values.add(EmitPropertyList( 6139 "\01l_OBJC_$_PROP_LIST_
" + ID->getObjCRuntimeNameAsString(), 6140 ID, ID->getClassInterface(), ObjCTypes, false)); 6143 llvm::SmallString<64> roLabel; 6144 llvm::raw_svector_ostream(roLabel) 6145 << ((flags & NonFragileABI_Class_Meta) ? "\01l_OBJC_METACLASS_RO_$_
" 6146 : "\01l_OBJC_CLASS_RO_$_
") 6149 llvm::GlobalVariable *CLASS_RO_GV = 6150 values.finishAndCreateGlobal(roLabel, CGM.getPointerAlign(), 6152 llvm::GlobalValue::PrivateLinkage); 6153 if (CGM.getTriple().isOSBinFormatMachO()) 6154 CLASS_RO_GV->setSection("__DATA, __objc_const
"); 6168 llvm::GlobalVariable *
6169 CGObjCNonFragileABIMac::BuildClassObject(const ObjCInterfaceDecl *CI,
6171 llvm::Constant *IsAGV,
6172 llvm::Constant *SuperClassGV,
6173 llvm::Constant *ClassRoGV,
6174 bool HiddenVisibility) {
6175 ConstantInitBuilder builder(CGM);
6176 auto values = builder.beginStruct(ObjCTypes.ClassnfABITy);
6179 values.add(SuperClassGV);
6181 values.addNullPointer(ObjCTypes.ClassnfABIPtrTy);
6183 values.add(ObjCEmptyCacheVar);
6184 values.add(ObjCEmptyVtableVar);
6185 values.add(ClassRoGV);
6187 llvm::GlobalVariable *GV =
6188 cast<llvm::GlobalVariable>(GetClassGlobal(CI, isMetaclass, ForDefinition));
6189 values.finishAndSetAsInitializer(GV);
6191 if (CGM.getTriple().isOSBinFormatMachO())
6192 GV->setSection("__DATA, __objc_data
"); 6194 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassnfABITy)); 6195 if (!CGM.getTriple().isOSBinFormatCOFF()) 6196 if (HiddenVisibility) 6197 GV->setVisibility(llvm::GlobalValue::HiddenVisibility); 6202 CGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const { 6203 return OD->getClassMethod(GetNullarySelector("load
")) != nullptr; 6206 void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID, 6207 uint32_t &InstanceStart, 6208 uint32_t &InstanceSize) { 6209 const ASTRecordLayout &RL = 6210 CGM.getContext().getASTObjCImplementationLayout(OID); 6212 // InstanceSize is really instance end. 6213 InstanceSize = RL.getDataSize().getQuantity(); 6215 // If there are no fields, the start is the same as the end. 6216 if (!RL.getFieldCount()) 6217 InstanceStart = InstanceSize; 6219 InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth(); 6222 static llvm::GlobalValue::DLLStorageClassTypes getStorage(CodeGenModule &CGM, 6224 IdentifierInfo &II = CGM.getContext().Idents.get(Name); 6225 TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl(); 6226 DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl); 6228 const VarDecl *VD = nullptr; 6229 for (const auto &Result : DC->lookup(&II)) 6230 if ((VD = dyn_cast<VarDecl>(Result))) 6234 return llvm::GlobalValue::DLLImportStorageClass; 6235 if (VD->hasAttr<DLLExportAttr>()) 6236 return llvm::GlobalValue::DLLExportStorageClass; 6237 if (VD->hasAttr<DLLImportAttr>()) 6238 return llvm::GlobalValue::DLLImportStorageClass; 6239 return llvm::GlobalValue::DefaultStorageClass; 6242 void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { 6243 if (!ObjCEmptyCacheVar) { 6245 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CacheTy, false, 6246 llvm::GlobalValue::ExternalLinkage, nullptr, 6247 "_objc_empty_cache
"); 6248 if (CGM.getTriple().isOSBinFormatCOFF()) 6249 ObjCEmptyCacheVar->setDLLStorageClass(getStorage(CGM, "_objc_empty_cache
")); 6251 // Only OS X with deployment version <10.9 use the empty vtable symbol 6252 const llvm::Triple &Triple = CGM.getTarget().getTriple(); 6253 if (Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 9)) 6254 ObjCEmptyVtableVar = 6255 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ImpnfABITy, false, 6256 llvm::GlobalValue::ExternalLinkage, nullptr, 6257 "_objc_empty_vtable
"); 6259 ObjCEmptyVtableVar = 6260 llvm::ConstantPointerNull::get(ObjCTypes.ImpnfABITy->getPointerTo()); 6263 // FIXME: Is this correct (that meta class size is never computed)? 6264 uint32_t InstanceStart = 6265 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy); 6266 uint32_t InstanceSize = InstanceStart; 6267 uint32_t flags = NonFragileABI_Class_Meta; 6269 llvm::Constant *SuperClassGV, *IsAGV; 6271 const auto *CI = ID->getClassInterface(); 6272 assert(CI && "CGObjCNonFragileABIMac::GenerateClass -
class is 0");
6275 bool classIsHidden = (CGM.
getTriple().isOSBinFormatCOFF())
6276 ? !CI->hasAttr<DLLExportAttr>()
6289 if (!CI->getSuperClass()) {
6306 llvm::GlobalVariable *CLASS_RO_GV =
6307 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
6309 llvm::GlobalVariable *MetaTClass =
6310 BuildClassObject(CI,
true,
6311 IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden);
6313 DefinedMetaClasses.push_back(MetaTClass);
6336 if (!CI->getSuperClass()) {
6338 SuperClassGV =
nullptr;
6341 const auto *Super = CI->getSuperClass();
6345 GetClassSizeInfo(ID, InstanceStart, InstanceSize);
6347 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
6349 llvm::GlobalVariable *ClassMD =
6350 BuildClassObject(CI,
false,
6351 MetaTClass, SuperClassGV, CLASS_RO_GV, classIsHidden);
6353 DefinedClasses.push_back(ClassMD);
6354 ImplementedClasses.push_back(CI);
6357 if (ImplementationIsNonLazy(ID))
6358 DefinedNonLazyClasses.push_back(ClassMD);
6364 MethodDefinitions.clear();
6381 llvm::Constant *Init =
6382 llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD),
6383 ObjCTypes.getExternalProtocolPtrTy());
6385 std::string ProtocolName(
"\01l_OBJC_PROTOCOL_REFERENCE_$_");
6390 llvm::GlobalVariable *PTGV = CGM.
getModule().getGlobalVariable(ProtocolName);
6393 PTGV =
new llvm::GlobalVariable(CGM.
getModule(), Init->getType(),
false,
6394 llvm::GlobalValue::WeakAnyLinkage, Init,
6396 PTGV->setSection(GetSectionName(
"__objc_protorefs",
6397 "coalesced,no_dead_strip"));
6400 if (!CGM.
getTriple().isOSBinFormatMachO())
6401 PTGV->setComdat(CGM.
getModule().getOrInsertComdat(ProtocolName));
6420 const char *Prefix =
"\01l_OBJC_$_CATEGORY_";
6424 ExtCatName +=
"_$_";
6428 auto values = builder.
beginStruct(ObjCTypes.CategorynfABITy);
6432 std::string listName =
6437 for (
const auto *MD : OCD->
methods()) {
6439 instanceMethods.push_back(MD);
6441 classMethods.push_back(MD);
6445 values.add(emitMethodList(listName, MethodListType::CategoryInstanceMethods,
6447 values.add(emitMethodList(listName, MethodListType::CategoryClassMethods,
6456 values.add(EmitProtocolList(
"\01l_OBJC_CATEGORY_PROTOCOLS_$_" 6461 values.add(EmitPropertyList(
"\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
6463 values.add(EmitPropertyList(
"\01l_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(),
6466 values.addNullPointer(ObjCTypes.ProtocolListnfABIPtrTy);
6467 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
6468 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
6471 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.CategorynfABITy);
6472 values.addInt(ObjCTypes.IntTy, Size);
6474 llvm::GlobalVariable *GCATV =
6477 llvm::GlobalValue::PrivateLinkage);
6478 if (CGM.
getTriple().isOSBinFormatMachO())
6479 GCATV->setSection(
"__DATA, __objc_const");
6481 DefinedCategories.push_back(GCATV);
6484 if (ImplementationIsNonLazy(OCD))
6485 DefinedNonLazyCategories.push_back(GCATV);
6487 MethodDefinitions.clear();
6502 auto method = builder.
beginStruct(ObjCTypes.MethodTy);
6503 method.addBitCast(GetMethodVarName(MD->
getSelector()),
6504 ObjCTypes.SelectorPtrTy);
6505 method.add(GetMethodVarType(MD));
6509 method.addNullPointer(ObjCTypes.Int8PtrTy);
6511 llvm::Function *fn = GetMethodDefinition(MD);
6512 assert(fn &&
"no definition for method?");
6513 method.addBitCast(fn, ObjCTypes.Int8PtrTy);
6516 method.finishAndAddTo(builder);
6531 if (methods.empty())
6532 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
6537 case MethodListType::CategoryInstanceMethods:
6538 prefix =
"\01l_OBJC_$_CATEGORY_INSTANCE_METHODS_";
6539 forProtocol =
false;
6541 case MethodListType::CategoryClassMethods:
6542 prefix =
"\01l_OBJC_$_CATEGORY_CLASS_METHODS_";
6543 forProtocol =
false;
6545 case MethodListType::InstanceMethods:
6546 prefix =
"\01l_OBJC_$_INSTANCE_METHODS_";
6547 forProtocol =
false;
6549 case MethodListType::ClassMethods:
6550 prefix =
"\01l_OBJC_$_CLASS_METHODS_";
6551 forProtocol =
false;
6554 case MethodListType::ProtocolInstanceMethods:
6555 prefix =
"\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_";
6558 case MethodListType::ProtocolClassMethods:
6559 prefix =
"\01l_OBJC_$_PROTOCOL_CLASS_METHODS_";
6562 case MethodListType::OptionalProtocolInstanceMethods:
6563 prefix =
"\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_";
6566 case MethodListType::OptionalProtocolClassMethods:
6567 prefix =
"\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_";
6576 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.MethodTy);
6577 values.addInt(ObjCTypes.IntTy, Size);
6579 values.addInt(ObjCTypes.IntTy, methods.size());
6580 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
6581 for (
auto MD : methods) {
6582 emitMethodConstant(methodArray, MD, forProtocol);
6584 methodArray.finishAndAddTo(values);
6586 auto *GV = values.finishAndCreateGlobal(prefix + name, CGM.
getPointerAlign(),
6588 llvm::GlobalValue::PrivateLinkage);
6589 if (CGM.
getTriple().isOSBinFormatMachO())
6590 GV->setSection(
"__DATA, __objc_const");
6592 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListnfABIPtrTy);
6597 llvm::GlobalVariable *
6605 llvm::GlobalVariable *IvarOffsetGV = CGM.
getModule().getGlobalVariable(Name);
6606 if (!IvarOffsetGV) {
6608 new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.IvarOffsetVarTy,
6610 nullptr, Name.str());
6611 if (CGM.
getTriple().isOSBinFormatCOFF()) {
6612 bool IsPrivateOrPackage =
6618 if (ContainingID->
hasAttr<DLLImportAttr>())
6620 ->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
6621 else if (ContainingID->
hasAttr<DLLExportAttr>() && !IsPrivateOrPackage)
6623 ->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
6626 return IvarOffsetGV;
6632 unsigned long int Offset) {
6633 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
6634 IvarOffsetGV->setInitializer(
6635 llvm::ConstantInt::get(ObjCTypes.IvarOffsetVarTy, Offset));
6636 IvarOffsetGV->setAlignment(
6637 CGM.
getDataLayout().getABITypeAlignment(ObjCTypes.IvarOffsetVarTy));
6639 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
6650 if (CGM.
getTriple().isOSBinFormatMachO())
6651 IvarOffsetGV->setSection(
"__DATA, __objc_ivar");
6652 return IvarOffsetGV;
6672 llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
6677 ivarList.addInt(ObjCTypes.IntTy,
6678 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.IvarnfABITy));
6679 auto ivarCountSlot = ivarList.addPlaceholder();
6680 auto ivars = ivarList.beginArray(ObjCTypes.IvarnfABITy);
6683 assert(OID &&
"CGObjCNonFragileABIMac::EmitIvarList - null interface");
6690 if (!IVD->getDeclName())
6693 auto ivar = ivars.beginStruct(ObjCTypes.IvarnfABITy);
6695 ComputeIvarBaseOffset(CGM, ID, IVD)));
6696 ivar.add(GetMethodVarName(IVD->getIdentifier()));
6697 ivar.add(GetMethodVarType(IVD));
6700 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(FieldTy);
6702 IVD->getType().getTypePtr()) >> 3;
6703 Align = llvm::Log2_32(Align);
6704 ivar.addInt(ObjCTypes.IntTy, Align);
6710 ivar.addInt(ObjCTypes.IntTy, Size);
6711 ivar.finishAndAddTo(ivars);
6714 if (ivars.empty()) {
6717 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
6720 auto ivarCount = ivars.size();
6721 ivars.finishAndAddTo(ivarList);
6722 ivarList.fillPlaceholderWithInt(ivarCountSlot, ObjCTypes.IntTy, ivarCount);
6724 const char *Prefix =
"\01l_OBJC_$_INSTANCE_VARIABLES_";
6725 llvm::GlobalVariable *GV =
6728 llvm::GlobalValue::PrivateLinkage);
6729 if (CGM.
getTriple().isOSBinFormatMachO())
6730 GV->setSection(
"__DATA, __objc_const");
6732 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy);
6735 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(
6737 llvm::GlobalVariable *&Entry = Protocols[PD->
getIdentifier()];
6744 llvm::raw_svector_ostream(Protocol) <<
"\01l_OBJC_PROTOCOL_$_" 6747 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolnfABITy,
6750 if (!CGM.
getTriple().isOSBinFormatMachO())
6751 Entry->setComdat(CGM.
getModule().getOrInsertComdat(Protocol));
6777 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
6779 llvm::GlobalVariable *Entry = Protocols[PD->
getIdentifier()];
6782 if (Entry && Entry->hasInitializer())
6789 auto methodLists = ProtocolMethodLists::get(PD);
6792 auto values = builder.
beginStruct(ObjCTypes.ProtocolnfABITy);
6795 values.addNullPointer(ObjCTypes.ObjectPtrTy);
6797 values.add(EmitProtocolList(
"\01l_OBJC_$_PROTOCOL_REFS_" 6801 values.add(methodLists.emitMethodList(
this, PD,
6802 ProtocolMethodLists::RequiredInstanceMethods));
6803 values.add(methodLists.emitMethodList(
this, PD,
6804 ProtocolMethodLists::RequiredClassMethods));
6805 values.add(methodLists.emitMethodList(
this, PD,
6806 ProtocolMethodLists::OptionalInstanceMethods));
6807 values.add(methodLists.emitMethodList(
this, PD,
6808 ProtocolMethodLists::OptionalClassMethods));
6809 values.add(EmitPropertyList(
6811 nullptr, PD, ObjCTypes,
false));
6813 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
6814 values.addInt(ObjCTypes.IntTy, Size);
6815 values.addInt(ObjCTypes.IntTy, 0);
6816 values.add(EmitProtocolMethodTypes(
"\01l_OBJC_$_PROTOCOL_METHOD_TYPES_" 6818 methodLists.emitExtendedTypesArray(
this),
6822 values.addNullPointer(ObjCTypes.Int8PtrTy);
6824 values.add(EmitPropertyList(
6826 nullptr, PD, ObjCTypes,
true));
6830 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
6831 values.finishAndSetAsInitializer(Entry);
6834 llvm::raw_svector_ostream(symbolName)
6837 Entry = values.finishAndCreateGlobal(symbolName, CGM.
getPointerAlign(),
6839 llvm::GlobalValue::WeakAnyLinkage);
6840 if (!CGM.
getTriple().isOSBinFormatMachO())
6841 Entry->setComdat(CGM.
getModule().getOrInsertComdat(symbolName));
6851 llvm::raw_svector_ostream(ProtocolRef) <<
"\01l_OBJC_LABEL_PROTOCOL_$_" 6854 llvm::GlobalVariable *PTGV =
6855 new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolnfABIPtrTy,
6856 false, llvm::GlobalValue::WeakAnyLinkage, Entry,
6858 if (!CGM.
getTriple().isOSBinFormatMachO())
6859 PTGV->setComdat(CGM.
getModule().getOrInsertComdat(ProtocolRef));
6861 CGM.
getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy));
6862 PTGV->setSection(GetSectionName(
"__objc_protolist",
6863 "coalesced,no_dead_strip"));
6878 CGObjCNonFragileABIMac::EmitProtocolList(Twine Name,
6885 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
6889 Name.toVector(TmpName);
6890 llvm::GlobalVariable *GV =
6891 CGM.
getModule().getGlobalVariable(TmpName.str(),
true);
6893 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy);
6897 auto countSlot = values.addPlaceholder();
6900 auto array = values.beginArray(ObjCTypes.ProtocolnfABIPtrTy);
6901 for (; begin != end; ++begin)
6902 array.add(GetProtocolRef(*begin));
6903 auto count = array.size();
6904 array.addNullPointer(ObjCTypes.ProtocolnfABIPtrTy);
6906 array.finishAndAddTo(values);
6907 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
6911 llvm::GlobalValue::PrivateLinkage);
6912 if (CGM.
getTriple().isOSBinFormatMachO())
6913 GV->setSection(
"__DATA, __objc_const");
6915 return llvm::ConstantExpr::getBitCast(GV,
6916 ObjCTypes.ProtocolListnfABIPtrTy);
6925 LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
6930 unsigned CVRQualifiers) {
6932 llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
6933 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
6937 llvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset(
6941 llvm::Value *IvarOffsetValue = ObjCIvarOffsetVariable(Interface, Ivar);
6944 if (IsIvarOffsetKnownIdempotent(CGF, Ivar))
6945 cast<llvm::LoadInst>(IvarOffsetValue)
6946 ->setMetadata(CGM.
getModule().getMDKindID(
"invariant.load"),
6947 llvm::MDNode::get(VMContext,
None));
6952 if (ObjCTypes.IvarOffsetVarTy == ObjCTypes.IntTy)
6953 IvarOffsetValue = CGF.
Builder.CreateIntCast(
6954 IvarOffsetValue, ObjCTypes.LongTy,
true,
"ivar.conv");
6955 return IvarOffsetValue;
6958 static void appendSelectorForMessageRefTable(std::string &buffer,
6965 for (
unsigned i = 0, e = selector.
getNumArgs(); i != e; ++i) {
7003 args.insert(args.end(), formalArgs.begin(), formalArgs.end());
7005 MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);
7007 NullReturnState nullReturn;
7016 llvm::Constant *fn =
nullptr;
7017 std::string messageRefName(
"\01l_");
7020 fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
7021 messageRefName +=
"objc_msgSendSuper2_stret_fixup";
7023 nullReturn.init(CGF, arg0);
7024 fn = ObjCTypes.getMessageSendStretFixupFn();
7025 messageRefName +=
"objc_msgSend_stret_fixup";
7028 fn = ObjCTypes.getMessageSendFpretFixupFn();
7029 messageRefName +=
"objc_msgSend_fpret_fixup";
7032 fn = ObjCTypes.getMessageSendSuper2FixupFn();
7033 messageRefName +=
"objc_msgSendSuper2_fixup";
7035 fn = ObjCTypes.getMessageSendFixupFn();
7036 messageRefName +=
"objc_msgSend_fixup";
7039 assert(fn &&
"CGObjCNonFragileABIMac::EmitMessageSend");
7040 messageRefName +=
'_';
7044 appendSelectorForMessageRefTable(messageRefName, selector);
7046 llvm::GlobalVariable *messageRef
7047 = CGM.
getModule().getGlobalVariable(messageRefName);
7053 values.add(GetMethodVarName(selector));
7054 messageRef = values.finishAndCreateGlobal(messageRefName,
7057 llvm::GlobalValue::WeakAnyLinkage);
7059 messageRef->setSection(GetSectionName(
"__objc_msgrefs",
"coalesced"));
7062 bool requiresnullCheck =
false;
7064 for (
const auto *ParamDecl : method->
parameters()) {
7065 if (ParamDecl->hasAttr<NSConsumedAttr>()) {
7066 if (!nullReturn.NullBB)
7067 nullReturn.init(CGF, arg0);
7068 requiresnullCheck =
true;
7088 RValue result = CGF.
EmitCall(MSI.CallInfo, callee, returnSlot, args);
7089 return nullReturn.complete(CGF, returnSlot, result, resultType, formalArgs,
7090 requiresnullCheck ? method :
nullptr);
7103 return isVTableDispatchedSelector(Sel)
7104 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
7106 false, CallArgs, Method)
7107 : EmitMessageSend(CGF, Return, ResultType,
7108 EmitSelector(CGF, Sel),
7110 false, CallArgs, Method, Class, ObjCTypes);
7118 (metaclass ? getMetaclassSymbolPrefix() : getClassSymbolPrefix());
7124 && ID->
hasAttr<DLLImportAttr>());
7128 CGObjCNonFragileABIMac::GetClassGlobal(StringRef Name,
7130 bool Weak,
bool DLLImport) {
7131 llvm::GlobalValue::LinkageTypes L =
7132 Weak ? llvm::GlobalValue::ExternalWeakLinkage
7137 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name);
7139 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassnfABITy,
7140 false, L,
nullptr, Name);
7143 GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
7146 assert(GV->getLinkage() == L);
7155 llvm::GlobalVariable *&Entry = ClassReferences[II];
7158 llvm::Constant *ClassGV;
7162 ClassGV = GetClassGlobal((getClassSymbolPrefix() + II->
getName()).str(),
7166 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassnfABIPtrTy,
7167 false, llvm::GlobalValue::PrivateLinkage,
7168 ClassGV,
"OBJC_CLASSLIST_REFERENCES_$_");
7170 Entry->setSection(GetSectionName(
"__objc_classrefs",
7171 "regular,no_dead_strip"));
7181 if (ID->
hasAttr<ObjCRuntimeVisibleAttr>())
7182 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
7187 llvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(
7190 return EmitClassRefFromId(CGF, II,
nullptr);
7197 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->
getIdentifier()];
7201 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassnfABIPtrTy,
7202 false, llvm::GlobalValue::PrivateLinkage,
7203 ClassGV,
"OBJC_CLASSLIST_SUP_REFS_$_");
7205 Entry->setSection(GetSectionName(
"__objc_superrefs",
7206 "regular,no_dead_strip"));
7219 llvm::GlobalVariable * &Entry = MetaClassReferences[ID->
getIdentifier()];
7223 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassnfABIPtrTy,
7224 false, llvm::GlobalValue::PrivateLinkage,
7225 MetaClassGV,
"OBJC_CLASSLIST_SUP_REFS_$_");
7228 Entry->setSection(GetSectionName(
"__objc_superrefs",
7229 "regular,no_dead_strip"));
7243 assert(!isa<llvm::GlobalVariable>(ClassGV) ||
7244 cast<llvm::GlobalVariable>(ClassGV)->hasExternalWeakLinkage());
7247 return EmitClassRef(CGF, ID);
7259 bool isCategoryImpl,
7261 bool IsClassMessage,
7282 Target = EmitSuperClassRef(CGF, Class);
7292 return (isVTableDispatchedSelector(Sel))
7293 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
7294 ObjCSuper.
getPointer(), ObjCTypes.SuperPtrCTy,
7295 true, CallArgs, Method)
7296 : EmitMessageSend(CGF, Return, ResultType,
7297 EmitSelector(CGF, Sel),
7298 ObjCSuper.
getPointer(), ObjCTypes.SuperPtrCTy,
7299 true, CallArgs, Method, Class, ObjCTypes);
7304 Address Addr = EmitSelectorAddr(CGF, Sel);
7307 LI->setMetadata(CGM.
getModule().getMDKindID(
"invariant.load"),
7308 llvm::MDNode::get(VMContext,
None));
7314 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
7318 llvm::Constant *Casted =
7319 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
7320 ObjCTypes.SelectorPtrTy);
7321 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.SelectorPtrTy,
7322 false, llvm::GlobalValue::PrivateLinkage,
7323 Casted,
"OBJC_SELECTOR_REFERENCES_");
7324 Entry->setExternallyInitialized(
true);
7325 Entry->setSection(GetSectionName(
"__objc_selrefs",
7326 "literal_pointers,no_dead_strip"));
7342 if (!isa<llvm::PointerType>(SrcTy)) {
7343 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(SrcTy);
7344 assert(Size <= 8 && "does not support size > 8
"); 7345 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 7346 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 7347 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 7349 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 7350 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 7351 llvm::Value *args[] = { src, dst.getPointer(), ivarOffset }; 7352 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args); 7358 void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
7359 CodeGen::CodeGenFunction &CGF,
7360 llvm::Value *src, Address dst) {
7361 llvm::Type * SrcTy = src->getType();
7362 if (!isa<llvm::PointerType>(SrcTy)) {
7363 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7364 assert(Size <= 8 && "does
not support size > 8
"); 7365 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 7366 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 7367 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 7369 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 7370 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 7371 llvm::Value *args[] = { src, dst.getPointer() }; 7372 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), 7373 args, "weakassign
"); 7376 void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable( 7377 CodeGen::CodeGenFunction &CGF, 7380 llvm::Value *Size) { 7381 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy); 7382 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy); 7383 llvm::Value *args[] = { DestPtr.getPointer(), SrcPtr.getPointer(), Size }; 7384 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args); 7390 llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(
7391 CodeGen::CodeGenFunction &CGF,
7392 Address AddrWeakObj) {
7393 llvm::Type *DestTy = AddrWeakObj.getElementType();
7394 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy);
7395 llvm::Value *read_weak =
7396 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(),
7397 AddrWeakObj.getPointer(), "weakread
"); 7398 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy); 7405 void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
7406 llvm::Value *src, Address dst) {
7407 llvm::Type * SrcTy = src->getType();
7408 if (!isa<llvm::PointerType>(SrcTy)) {
7409 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7410 assert(Size <= 8 && "does
not support size > 8
"); 7411 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 7412 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 7413 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 7415 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 7416 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 7417 llvm::Value *args[] = { src, dst.getPointer() }; 7418 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), 7419 args, "weakassign
"); 7425 void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
7426 llvm::Value *src, Address dst,
7428 llvm::Type * SrcTy = src->getType();
7429 if (!isa<llvm::PointerType>(SrcTy)) {
7430 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7431 assert(Size <= 8 && "does
not support size > 8
"); 7432 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 7433 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 7434 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 7436 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 7437 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 7438 llvm::Value *args[] = { src, dst.getPointer() }; 7440 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), 7441 args, "globalassign
"); 7443 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(), 7444 args, "threadlocalassign
"); 7448 CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 7449 const ObjCAtSynchronizedStmt &S) { 7450 EmitAtSynchronizedStmt(CGF, S, 7451 cast<llvm::Function>(ObjCTypes.getSyncEnterFn()), 7452 cast<llvm::Function>(ObjCTypes.getSyncExitFn())); 7456 CGObjCNonFragileABIMac::GetEHType(QualType T) { 7457 // There's a particular fixed type info for 'id'. 7458 if (T->isObjCIdType() || T->isObjCQualifiedIdType()) { 7459 auto *IDEHType = CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id
"); 7462 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false, 7463 llvm::GlobalValue::ExternalLinkage, nullptr, 7465 if (CGM.getTriple().isOSBinFormatCOFF()) 7466 IDEHType->setDLLStorageClass(getStorage(CGM, "OBJC_EHTYPE_id
")); 7471 // All other types should be Objective-C interface pointer types. 7472 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>(); 7473 assert(PT && "Invalid
@catch type.
"); 7475 const ObjCInterfaceType *IT = PT->getInterfaceType(); 7476 assert(IT && "Invalid
@catch type.
"); 7478 return GetInterfaceEHType(IT->getDecl(), NotForDefinition); 7481 void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, 7482 const ObjCAtTryStmt &S) { 7483 EmitTryCatchStmt(CGF, S, 7484 cast<llvm::Function>(ObjCTypes.getObjCBeginCatchFn()), 7485 cast<llvm::Function>(ObjCTypes.getObjCEndCatchFn()), 7486 cast<llvm::Function>(ObjCTypes.getExceptionRethrowFn())); 7490 void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
7491 const ObjCAtThrowStmt &S,
7492 bool ClearInsertionPoint) {
7493 if (const Expr *ThrowExpr = S.getThrowExpr()) {
7494 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
7495 Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
7496 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception)
7497 .setDoesNotReturn();
7499 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionRethrowFn())
7500 .setDoesNotReturn();
7503 CGF.Builder.CreateUnreachable();
7504 if (ClearInsertionPoint)
7505 CGF.Builder.ClearInsertionPoint();
7509 CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
7510 ForDefinition_t IsForDefinition) {
7511 llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
7512 StringRef ClassName = ID->getObjCRuntimeNameAsString();
7514 // If we don't need a definition, return the entry if found or check
7515 // if we use an external reference.
7516 if (!IsForDefinition) {
7520 // If this type (or a super class) has the __objc_exception__
7521 // attribute, emit an external reference.
7522 if (hasObjCExceptionAttribute(CGM.getContext(), ID)) {
7523 std::string EHTypeName = ("OBJC_EHTYPE_$_
" + ClassName).str(); 7524 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, 7525 false, llvm::GlobalValue::ExternalLinkage, 7526 nullptr, EHTypeName); 7527 CGM.setGVProperties(Entry, ID); 7532 // Otherwise we need to either make a new entry or fill in the initializer. 7533 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition
"); 7535 std::string VTableName = "objc_ehtype_vtable
"; 7536 auto *VTableGV = CGM.getModule().getGlobalVariable(VTableName); 7539 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy, false, 7540 llvm::GlobalValue::ExternalLinkage, nullptr, 7542 if (CGM.getTriple().isOSBinFormatCOFF()) 7543 VTableGV->setDLLStorageClass(getStorage(CGM, VTableName)); 7546 llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2); 7547 ConstantInitBuilder builder(CGM); 7548 auto values = builder.beginStruct(ObjCTypes.EHTypeTy); 7550 llvm::ConstantExpr::getInBoundsGetElementPtr(VTableGV->getValueType(), 7551 VTableGV, VTableIdx)); 7552 values.add(GetClassName(ClassName)); 7553 values.add(GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition)); 7555 llvm::GlobalValue::LinkageTypes L = IsForDefinition 7556 ? llvm::GlobalValue::ExternalLinkage 7557 : llvm::GlobalValue::WeakAnyLinkage; 7559 values.finishAndSetAsInitializer(Entry); 7560 Entry->setAlignment(CGM.getPointerAlign().getQuantity()); 7562 Entry = values.finishAndCreateGlobal("OBJC_EHTYPE_$_
" + ClassName, 7563 CGM.getPointerAlign(), 7566 if (hasObjCExceptionAttribute(CGM.getContext(), ID)) 7567 CGM.setGVProperties(Entry, ID); 7569 assert(Entry->getLinkage() == L); 7571 if (!CGM.getTriple().isOSBinFormatCOFF()) 7572 if (ID->getVisibility() == HiddenVisibility) 7573 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility); 7575 if (IsForDefinition) 7576 if (CGM.getTriple().isOSBinFormatMachO()) 7577 Entry->setSection("__DATA,__objc_const
"); 7584 CodeGen::CGObjCRuntime * 7585 CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) { 7586 switch (CGM.getLangOpts().ObjCRuntime.getKind()) { 7587 case ObjCRuntime::FragileMacOSX: 7588 return new CGObjCMac(CGM); 7590 case ObjCRuntime::MacOSX: 7591 case ObjCRuntime::iOS: 7592 case ObjCRuntime::WatchOS: 7593 return new CGObjCNonFragileABIMac(CGM); 7595 case ObjCRuntime::GNUstep: 7596 case ObjCRuntime::GCC: 7597 case ObjCRuntime::ObjFW: 7598 llvm_unreachable("these runtimes are
not Mac runtimes
"); 7600 llvm_unreachable("bad runtime
"); const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
const llvm::DataLayout & getDataLayout() const
ReturnValueSlot - Contains the address where the return value of a function can be stored...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
Defines the clang::ASTContext interface.
QualType withConst() const
Retrieves a version of this type with const applied.
bool isClassMethod() const
const Capture & getCapture(const VarDecl *var) const
llvm::IntegerType * IntTy
int
External linkage, which indicates that the entity can be referred to from other translation units...
CharUnits BlockHeaderForcedGapOffset
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
Smart pointer class that efficiently represents Objective-C method names.
QualType getObjCIdType() const
Represents the Objective-CC id type.
Class implementation was compiled under ARC.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
bool isBlockPointerType() const
bool ReturnTypeUsesSRet(const CGFunctionInfo &FI)
Return true iff the given type uses 'sret' when used as a return type.
CodeGenTypes & getTypes()
ObjCInterfaceDecl * getClassInterface()
__SIZE_TYPE__ size_t
The unsigned integer type of the result of the sizeof operator.
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
llvm::LLVMContext & getLLVMContext()
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
The standard implementation of ConstantInitBuilder used in Clang.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
Stmt - This represents one statement.
const ObjCAtFinallyStmt * getFinallyStmt() const
Retrieve the @finally statement, if any.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Implements runtime-specific code generation functions.
bool isRecordType() const
const ASTRecordLayout & getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const
Get or compute information about the layout of the specified Objective-C implementation.
Decl - This represents one declaration (or definition), e.g.
CharUnits getPointerSize() const
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
all_protocol_iterator all_referenced_protocol_begin() const
void EmitAutoVarDecl(const VarDecl &D)
EmitAutoVarDecl - Emit an auto variable declaration.
Has a non-trivial constructor or destructor.
The base class of the type hierarchy.
Represents Objective-C's @throw statement.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
bool hasDestructors() const
Do any of the ivars of this class (not counting its base classes) require non-trivial destruction...
static bool hasObjCExceptionAttribute(ASTContext &Context, const ObjCInterfaceDecl *OID)
hasObjCExceptionAttribute - Return true if this class or any super class has the objc_exception attri...
static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT, bool pointee=false)
unsigned getCharWidth() const
param_const_iterator param_end() const
QualType getElementType() const
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::Instruction **callOrInvoke, SourceLocation Loc)
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.
CanQualType getCanonicalParamType(QualType T) const
Return the canonical parameter type corresponding to the specific potentially non-canonical one...
Represents a variable declaration or definition.
Objects with "hidden" visibility are not seen by the dynamic linker.
const T * getAs() const
Member-template getAs<specific type>'.
llvm::GlobalVariable * finishAndCreateGlobal(As &&...args)
Given that this builder was created by beginning an array or struct directly on a ConstantInitBuilder...
ObjCMethodDecl - Represents an instance or class method declaration.
QualType getObjCClassType() const
Represents the Objective-C Class type.
llvm::Value * getPointer() const
Defines the Objective-C statement AST node classes.
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
protocol_range protocols() const
Represents a parameter to a function.
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have...
void add(RValue rvalue, QualType type)
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.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Represents a struct/union/class.
uint64_t getPointerWidth(unsigned AddrSpace) const
Return the width of pointers on this target, for the specified address space.
One of these records is kept for each identifier that is lexed.
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 ...
const ParmVarDecl *const * param_const_iterator
field_range fields() const
Class has non-trivial destructors, but zero-initialization is okay.
bool isObjCIdType() const
Represents a member of a struct/union/class.
protocol_iterator protocol_begin() const
CharUnits getSizeAlign() const
llvm::CallInst * EmitRuntimeCall(llvm::Value *callee, const Twine &name="")
method_range methods() const
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for protocol's metadata.
ObjCMethodDecl * getSetterMethodDecl() const
std::string getNameAsString() const
Get the name of the class associated with this interface.
Class implementation was compiled under MRC and has MRC weak ivars.
prop_range properties() const
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
bool isObjCQualifiedClassType() const
Has the exception attribute.
bool isUnarySelector() const
Objects with "default" visibility are seen by the dynamic linker and act like normal objects...
Represents Objective-C's @catch statement.
static bool isWeakLinkedClass(const ObjCInterfaceDecl *ID)
bool hasNonZeroConstructors() const
Do any of the ivars of this class (not counting its base classes) require construction other than zer...
bool isBitField() const
Determines whether this field is a bitfield.
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
ObjCContainerDecl - Represents a container for method declarations.
const Expr * getThrowExpr() const
CharUnits - This is an opaque type for sizes expressed in character units.
const BlockDecl * getBlockDecl() const
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
QualType getObjCClassRedefinitionType() const
Retrieve the type that Class has been defined to, which may be different from the built-in Class if C...
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
unsigned getBitWidthValue(const ASTContext &Ctx) const
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void addCompilerUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.compiler.used metadata.
void ForceCleanup(std::initializer_list< llvm::Value **> ValuesToReload={})
Force the emission of cleanups now, instead of waiting until this object is destroyed.
Represents an Objective-C protocol declaration.
llvm::Constant * CreateRuntimeVariable(llvm::Type *Ty, StringRef Name)
Create a new runtime global variable with the specified type and name.
CharUnits getPointerAlign() const
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
Represents an ObjC class declaration.
QualType getReturnType() const
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface...
Address NormalCleanupDest
i32s containing the indexes of the cleanup destinations.
all_protocol_iterator all_referenced_protocol_end() const
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
QualType getObjCProtoType() const
Retrieve the type of the Objective-C Protocol class.
This object can be modified without requiring retains or releases.
llvm::Constant * CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false)
Create a new runtime function with the specified type and name.
const ObjCAtCatchStmt * getCatchStmt(unsigned I) const
Retrieve a @catch statement.
unsigned getIndex() const
StringRef getString() const
static CharUnits One()
One - Construct a CharUnits quantity of one.
void addFrom(const CallArgList &other)
Add all the arguments from another CallArgList to this one.
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
ASTContext & getContext() const
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
CGBlockInfo - Information to generate a block literal.
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static llvm::StringMapEntry< llvm::GlobalVariable * > & GetConstantStringEntry(llvm::StringMap< llvm::GlobalVariable *> &Map, const StringLiteral *Literal, unsigned &StringLength)
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
llvm::CallingConv::ID getRuntimeCC() const
bool isObjCGCStrong() const
true when Type is objc's strong.
Pepresents a block literal declaration, which is like an unnamed FunctionDecl.
Expr - This represents one expression.
Defines the clang::LangOptions interface.
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
CharUnits getOffset() const
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
llvm::BasicBlock * getBlock() const
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
bool isObjCClassType() const
bool isObjCIdType() const
True if this is equivalent to the 'id' type, i.e.
Represents Objective-C's @synchronized statement.
ObjCInterfaceDecl * getSuperClass() const
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
llvm::LLVMContext & getLLVMContext()
bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI)
Return true iff the given type uses an argument slot when 'sret' is used as a return type...
llvm::IntegerType * Int32Ty
clang::ObjCRuntime ObjCRuntime
propimpl_range property_impls() const
bool isInstanceMethod() const
static llvm::Constant * getConstantGEP(llvm::LLVMContext &VMContext, llvm::GlobalVariable *C, unsigned idx0, unsigned idx1)
getConstantGEP() - Help routine to construct simple GEPs.
unsigned getNumArgs() const
const TargetInfo & getTarget() const
Selector getSelector() const
float __ovld __cnfn length(float p)
Return the length of vector p, i.e., sqrt(p.x2 + p.y 2 + ...)
const LangOptions & getLangOpts() const
ASTContext & getContext() const
(Obsolete) ARC-specific: this class has a .release_ivars method
CanQualType getCanonicalTypeUnqualified() const
The l-value was considered opaque, so the alignment was determined from a type.
RecordDecl * getDecl() const
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
There is no lifetime qualification on this type.
Address CreateBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
QualType getObjCIdRedefinitionType() const
Retrieve the type that id has been defined to, which may be different from the built-in id if id has ...
SelectorTable & Selectors
Assigning into this object requires the old value to be released and the new value to be retained...
bool ReturnTypeUsesFPRet(QualType ResultType)
Return true iff the given type uses 'fpret' when used as a return type.
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 Stmt * getCatchBody() const
ConstantAddress GetAddrOfConstantCFString(const StringLiteral *Literal)
Return a pointer to a constant CFString object for the given string.
llvm::StructType * StructureType
SmallVector< llvm::Value *, 8 > ObjCEHValueStack
ObjCEHValueStack - Stack of Objective-C exception values, used for rethrows.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const
Set visibility, dllimport/dllexport and dso_local.
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
const CGFunctionInfo & arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD)
Objective-C methods are C functions with some implicit parameters.
void EmitStmt(const Stmt *S, ArrayRef< const Attr *> Attrs=None)
EmitStmt - Emit the code for the statement.
static void PushProtocolProperties(llvm::SmallPtrSet< const IdentifierInfo *, 16 > &PropertySet, SmallVectorImpl< const ObjCPropertyDecl *> &Properties, const ObjCProtocolDecl *Proto, bool IsClassProperty)
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...
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
ObjCCategoryDecl - Represents a category declaration.
static bool hasWeakMember(QualType type)
bool isObjCObjectPointerType() const
Represents one property declaration in an Objective-C interface.
Class implementation was compiled under MRC and has MRC weak ivars.
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...
All available information about a concrete callee.
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...
Assigning into this object requires a lifetime extension.
unsigned getPreferredTypeAlign(const Type *T) const
Return the "preferred" alignment of the specified type T for the current target, in bits...
bool ReturnTypeUsesFP2Ret(QualType ResultType)
Return true iff the given type uses 'fp2ret' when used as a return type.
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
ConstantAddress GetAddrOfConstantCString(const std::string &Str, const char *GlobalName=nullptr)
Returns a pointer to a character array containing the literal and a terminating '\0' character...
StringRef getName() const
Return the actual identifier string.
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type, returning the result.
void addUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.used metadata.
ObjCIvarDecl * getNextIvar()
bool isObjCGCWeak() const
true when Type is objc's weak.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
This class organizes the cross-function state that is used while generating LLVM code.
protocol_iterator protocol_end() const
StructBuilder beginStruct(llvm::StructType *ty=nullptr)
const ObjCInterfaceDecl * getClassInterface() const
static void addIfPresent(llvm::DenseSet< llvm::Value *> &S, Address V)
Dataflow Directional Tag Classes.
CharUnits getSize() const
getSize - Get the record size in characters.
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
ArrayRef< Capture > captures() const
Address CreateStructGEP(Address Addr, unsigned Index, CharUnits Offset, const llvm::Twine &Name="")
llvm::LoadInst * CreateAlignedLoad(llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::IntegerType * IntPtrTy
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
int printf(__constant const char *st,...)
const ObjCInterfaceDecl * getContainingInterface() const
Return the class interface that this ivar is logically contained in; this is either the interface whe...
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::Module & getModule() const
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...
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for class's metadata.
StructBuilder beginStruct(llvm::StructType *structTy=nullptr)
Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV)
Can create any sort of selector.
llvm::Type * getElementType() const
Return the type of the values stored in this address.
const llvm::APInt & getSize() const
This class organizes the cross-module state that is used while lowering AST types to LLVM types...
protocol_iterator protocol_begin() const
llvm::PointerType * Int8PtrTy
bool isObjCQualifiedIdType() const
param_const_iterator param_begin() const
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for class's metadata.
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.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
llvm::IntegerType * PtrDiffTy
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
Reading or writing from this object requires a barrier call.
Selector GetUnarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing an unary selector.
llvm::Type * ConvertType(QualType T)
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.
A helper class of ConstantInitBuilder, used for building constant struct initializers.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
CharUnits BlockHeaderForcedGapSize
Has a non-trivial constructor or destructor.
Represents Objective-C's @try ... @catch ... @finally statement.
protocol_iterator protocol_end() const
unsigned getNumCatchStmts() const
Retrieve the number of @catch statements in this try-catch-finally block.
StringLiteral - This represents a string literal expression, e.g.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
StringRef getName() const
getName - Get the name of identifier for the class interface associated with this implementation as a...
static RValue get(llvm::Value *V)
Visibility getVisibility() const
Determines the visibility of this entity.
const internal::VariadicDynCastAllOfMatcher< Decl, BlockDecl > blockDecl
Matches block declarations.
const VarDecl * getCatchParamDecl() const
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
std::string ObjCConstantStringClass
LValue - This represents an lvalue references.
Information for lazily generating a cleanup.
ObjCMethodDecl * getGetterMethodDecl() const
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
AccessControl getAccessControl() const
ObjCProtocolList::iterator protocol_iterator
CallArgList - Type for representing both the value and type of arguments in a call.
const LangOptions & getLangOpts() const
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.
A helper class of ConstantInitBuilder, used for building constant array initializers.
Abstract information about a function or function prototype.
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
ArrayRef< ParmVarDecl * > parameters() const
ObjCCompatibleAliasDecl - Represents alias of a class.
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, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
ObjCCategoryDecl * FindCategoryDeclaration(IdentifierInfo *CategoryId) const
FindCategoryDeclaration - Finds category declaration in the list of categories for this class and ret...
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
const llvm::Triple & getTriple() const