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>()) {
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()) {
3410 llvm::Constant *Protocols =
3411 EmitProtocolList(
"OBJC_CLASS_PROTOCOLS_" + ID->
getName(),
3418 bool hasMRCWeak =
false;
3438 for (
const auto *MD : ID->
methods()) {
3439 Methods[unsigned(MD->isClassMethod())].push_back(MD);
3447 if (GetMethodDefinition(MD))
3448 Methods[InstanceMethods].push_back(MD);
3450 if (GetMethodDefinition(MD))
3451 Methods[InstanceMethods].push_back(MD);
3456 auto values = builder.
beginStruct(ObjCTypes.ClassTy);
3457 values.add(EmitMetaClass(ID, Protocols, Methods[ClassMethods]));
3460 LazySymbols.insert(Super->getIdentifier());
3462 values.addBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
3463 ObjCTypes.ClassPtrTy);
3465 values.addNullPointer(ObjCTypes.ClassPtrTy);
3469 values.addInt(ObjCTypes.LongTy, 0);
3470 values.addInt(ObjCTypes.LongTy, Flags);
3471 values.addInt(ObjCTypes.LongTy, Size.
getQuantity());
3472 values.add(EmitIvarList(ID,
false));
3473 values.add(emitMethodList(ID->
getName(), MethodListType::InstanceMethods,
3474 Methods[InstanceMethods]));
3476 values.addNullPointer(ObjCTypes.CachePtrTy);
3477 values.add(Protocols);
3479 values.add(EmitClassExtension(ID, Size, hasMRCWeak,
3482 std::string Name(
"OBJC_CLASS_");
3484 const char *Section =
"__OBJC,__class,regular,no_dead_strip";
3486 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3488 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3489 "Forward metaclass reference has incorrect type.");
3490 values.finishAndSetAsInitializer(GV);
3491 GV->setSection(Section);
3495 GV = CreateMetadataVar(Name, values, Section, CGM.
getPointerAlign(),
true);
3496 DefinedClasses.push_back(GV);
3497 ImplementedClasses.push_back(Interface);
3499 MethodDefinitions.clear();
3503 llvm::Constant *Protocols,
3506 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ClassTy);
3512 auto values = builder.
beginStruct(ObjCTypes.ClassTy);
3518 ObjCTypes.ClassPtrTy);
3523 values.addBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
3524 ObjCTypes.ClassPtrTy);
3526 values.addNullPointer(ObjCTypes.ClassPtrTy);
3530 values.addInt(ObjCTypes.LongTy, 0);
3531 values.addInt(ObjCTypes.LongTy, Flags);
3532 values.addInt(ObjCTypes.LongTy, Size);
3533 values.add(EmitIvarList(ID,
true));
3534 values.add(emitMethodList(ID->
getName(), MethodListType::ClassMethods,
3537 values.addNullPointer(ObjCTypes.CachePtrTy);
3538 values.add(Protocols);
3540 values.addNullPointer(ObjCTypes.Int8PtrTy);
3545 std::string Name(
"OBJC_METACLASS_");
3549 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3551 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3552 "Forward metaclass reference has incorrect type.");
3553 values.finishAndSetAsInitializer(GV);
3557 llvm::GlobalValue::PrivateLinkage);
3559 GV->setSection(
"__OBJC,__meta_class,regular,no_dead_strip");
3576 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3578 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
3579 llvm::GlobalValue::PrivateLinkage,
nullptr,
3582 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3583 "Forward metaclass reference has incorrect type.");
3589 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3592 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
3593 llvm::GlobalValue::PrivateLinkage,
nullptr,
3596 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3597 "Forward class metadata reference has incorrect type.");
3617 llvm::Constant *layout;
3619 layout = llvm::ConstantPointerNull::get(CGM.
Int8PtrTy);
3626 llvm::Constant *propertyList =
3627 EmitPropertyList((isMetaclass ? Twine(
"\01l_OBJC_$_CLASS_PROP_LIST_")
3628 : Twine(
"\01l_OBJC_$_PROP_LIST_"))
3633 if (layout->isNullValue() && propertyList->isNullValue()) {
3634 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
3638 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
3641 auto values = builder.
beginStruct(ObjCTypes.ClassExtensionTy);
3642 values.addInt(ObjCTypes.IntTy, size);
3644 values.add(propertyList);
3646 return CreateMetadataVar(
"OBJC_CLASSEXT_" + ID->
getName(), values,
3647 "__OBJC,__class_ext,regular,no_dead_strip",
3671 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3677 auto countSlot = ivarList.addPlaceholder();
3678 auto ivars = ivarList.beginArray(ObjCTypes.IvarTy);
3683 if (!IVD->getDeclName())
3686 auto ivar = ivars.beginStruct(ObjCTypes.IvarTy);
3687 ivar.add(GetMethodVarName(IVD->getIdentifier()));
3688 ivar.add(GetMethodVarType(IVD));
3689 ivar.addInt(ObjCTypes.IntTy, ComputeIvarBaseOffset(CGM, OID, IVD));
3690 ivar.finishAndAddTo(ivars);
3694 auto count = ivars.size();
3698 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3701 ivars.finishAndAddTo(ivarList);
3702 ivarList.fillPlaceholderWithInt(countSlot, ObjCTypes.IntTy, count);
3704 llvm::GlobalVariable *GV;
3707 CreateMetadataVar(
"OBJC_CLASS_VARIABLES_" + ID->
getName(), ivarList,
3708 "__OBJC,__class_vars,regular,no_dead_strip",
3711 GV = CreateMetadataVar(
"OBJC_INSTANCE_VARIABLES_" + ID->
getName(), ivarList,
3712 "__OBJC,__instance_vars,regular,no_dead_strip",
3714 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy);
3725 auto description = builder.
beginStruct(ObjCTypes.MethodDescriptionTy);
3726 description.addBitCast(GetMethodVarName(MD->
getSelector()),
3727 ObjCTypes.SelectorPtrTy);
3728 description.add(GetMethodVarType(MD));
3729 description.finishAndAddTo(builder);
3741 llvm::Function *fn = GetMethodDefinition(MD);
3742 assert(fn &&
"no definition registered for method");
3744 auto method = builder.
beginStruct(ObjCTypes.MethodTy);
3745 method.addBitCast(GetMethodVarName(MD->
getSelector()),
3746 ObjCTypes.SelectorPtrTy);
3747 method.add(GetMethodVarType(MD));
3748 method.addBitCast(fn, ObjCTypes.Int8PtrTy);
3749 method.finishAndAddTo(builder);
3765 llvm::Constant *CGObjCMac::emitMethodList(Twine name,
MethodListType MLT,
3769 bool forProtocol =
false;
3771 case MethodListType::CategoryInstanceMethods:
3772 prefix =
"OBJC_CATEGORY_INSTANCE_METHODS_";
3773 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
3774 forProtocol =
false;
3776 case MethodListType::CategoryClassMethods:
3777 prefix =
"OBJC_CATEGORY_CLASS_METHODS_";
3778 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3779 forProtocol =
false;
3781 case MethodListType::InstanceMethods:
3782 prefix =
"OBJC_INSTANCE_METHODS_";
3783 section =
"__OBJC,__inst_meth,regular,no_dead_strip";
3784 forProtocol =
false;
3786 case MethodListType::ClassMethods:
3787 prefix =
"OBJC_CLASS_METHODS_";
3788 section =
"__OBJC,__cls_meth,regular,no_dead_strip";
3789 forProtocol =
false;
3791 case MethodListType::ProtocolInstanceMethods:
3792 prefix =
"OBJC_PROTOCOL_INSTANCE_METHODS_";
3793 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
3796 case MethodListType::ProtocolClassMethods:
3797 prefix =
"OBJC_PROTOCOL_CLASS_METHODS_";
3798 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3801 case MethodListType::OptionalProtocolInstanceMethods:
3802 prefix =
"OBJC_PROTOCOL_INSTANCE_METHODS_OPT_";
3803 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
3806 case MethodListType::OptionalProtocolClassMethods:
3807 prefix =
"OBJC_PROTOCOL_CLASS_METHODS_OPT_";
3808 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3814 if (methods.empty())
3815 return llvm::Constant::getNullValue(forProtocol
3816 ? ObjCTypes.MethodDescriptionListPtrTy
3817 : ObjCTypes.MethodListPtrTy);
3824 values.addInt(ObjCTypes.IntTy, methods.size());
3825 auto methodArray = values.beginArray(ObjCTypes.MethodDescriptionTy);
3826 for (
auto MD : methods) {
3827 emitMethodDescriptionConstant(methodArray, MD);
3829 methodArray.finishAndAddTo(values);
3831 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
3833 return llvm::ConstantExpr::getBitCast(GV,
3834 ObjCTypes.MethodDescriptionListPtrTy);
3840 values.addNullPointer(ObjCTypes.Int8PtrTy);
3841 values.addInt(ObjCTypes.IntTy, methods.size());
3842 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
3843 for (
auto MD : methods) {
3844 emitMethodConstant(methodArray, MD);
3846 methodArray.finishAndAddTo(values);
3848 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
3850 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListPtrTy);
3853 llvm::Function *CGObjCCommonMac::GenerateMethod(
const ObjCMethodDecl *OMD,
3856 GetNameForMethod(OMD, CD, Name);
3859 llvm::FunctionType *MethodTy =
3861 llvm::Function *Method =
3866 MethodDefinitions.insert(std::make_pair(OMD, Method));
3871 llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
3876 llvm::GlobalVariable *GV =
3878 llvm::GlobalValue::PrivateLinkage);
3879 if (!Section.empty())
3880 GV->setSection(Section);
3886 llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
3887 llvm::Constant *Init,
3892 llvm::GlobalVariable *GV =
3893 new llvm::GlobalVariable(CGM.
getModule(), Ty,
false,
3894 llvm::GlobalValue::PrivateLinkage, Init, Name);
3895 if (!Section.empty())
3896 GV->setSection(Section);
3903 llvm::GlobalVariable *
3905 bool ForceNonFragileABI,
3906 bool NullTerminate) {
3909 case ObjCLabelType::ClassName: Label =
"OBJC_CLASS_NAME_";
break;
3910 case ObjCLabelType::MethodVarName: Label =
"OBJC_METH_VAR_NAME_";
break;
3911 case ObjCLabelType::MethodVarType: Label =
"OBJC_METH_VAR_TYPE_";
break;
3912 case ObjCLabelType::PropertyName: Label =
"OBJC_PROP_NAME_ATTR_";
break;
3915 bool NonFragile = ForceNonFragileABI || isNonFragileABI();
3919 case ObjCLabelType::ClassName:
3920 Section = NonFragile ?
"__TEXT,__objc_classname,cstring_literals" 3921 :
"__TEXT,__cstring,cstring_literals";
3923 case ObjCLabelType::MethodVarName:
3924 Section = NonFragile ?
"__TEXT,__objc_methname,cstring_literals" 3925 :
"__TEXT,__cstring,cstring_literals";
3927 case ObjCLabelType::MethodVarType:
3928 Section = NonFragile ?
"__TEXT,__objc_methtype,cstring_literals" 3929 :
"__TEXT,__cstring,cstring_literals";
3931 case ObjCLabelType::PropertyName:
3932 Section =
"__TEXT,__cstring,cstring_literals";
3936 llvm::Constant *
Value =
3937 llvm::ConstantDataArray::getString(VMContext, Name, NullTerminate);
3938 llvm::GlobalVariable *GV =
3939 new llvm::GlobalVariable(CGM.
getModule(), Value->getType(),
3941 llvm::GlobalValue::PrivateLinkage,
Value,
Label);
3942 if (CGM.
getTriple().isOSBinFormatMachO())
3943 GV->setSection(Section);
3944 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
3951 llvm::Function *CGObjCMac::ModuleInitFunction() {
3957 llvm::Constant *CGObjCMac::GetPropertyGetFunction() {
3958 return ObjCTypes.getGetPropertyFn();
3961 llvm::Constant *CGObjCMac::GetPropertySetFunction() {
3962 return ObjCTypes.getSetPropertyFn();
3965 llvm::Constant *CGObjCMac::GetOptimizedPropertySetFunction(
bool atomic,
3967 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
3970 llvm::Constant *CGObjCMac::GetGetStructFunction() {
3971 return ObjCTypes.getCopyStructFn();
3974 llvm::Constant *CGObjCMac::GetSetStructFunction() {
3975 return ObjCTypes.getCopyStructFn();
3978 llvm::Constant *CGObjCMac::GetCppAtomicObjectGetFunction() {
3979 return ObjCTypes.getCppAtomicObjectFunction();
3982 llvm::Constant *CGObjCMac::GetCppAtomicObjectSetFunction() {
3983 return ObjCTypes.getCppAtomicObjectFunction();
3986 llvm::Constant *CGObjCMac::EnumerationMutationFunction() {
3987 return ObjCTypes.getEnumerationMutationFn();
3991 return EmitTryOrSynchronizedStmt(CGF, S);
3996 return EmitTryOrSynchronizedStmt(CGF, S);
4005 ObjCTypesHelper &ObjCTypes;
4006 PerformFragileFinally(
const Stmt *S,
4010 ObjCTypesHelper *ObjCTypes)
4011 : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
4012 ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
4017 llvm::BasicBlock *FinallyCallExit =
4019 llvm::BasicBlock *FinallyNoCallExit =
4022 FinallyCallExit, FinallyNoCallExit);
4030 if (isa<ObjCAtTryStmt>(S)) {
4032 cast<ObjCAtTryStmt>(S).getFinallyStmt()) {
4034 if (flags.isForEHCleanup())
return;
4041 CGF.
EmitStmt(FinallyStmt->getFinallyBody());
4060 class FragileHazards {
4065 llvm::InlineAsm *ReadHazard;
4066 llvm::InlineAsm *WriteHazard;
4068 llvm::FunctionType *GetAsmFnType();
4070 void collectLocals();
4076 void emitWriteHazard();
4077 void emitHazardsInNewBlocks();
4089 if (Locals.empty())
return;
4092 for (llvm::Function::iterator
4093 I = CGF.
CurFn->begin(), E = CGF.
CurFn->end(); I != E; ++I)
4094 BlocksBeforeTry.insert(&*I);
4096 llvm::FunctionType *AsmFnTy = GetAsmFnType();
4104 std::string Constraint;
4105 for (
unsigned I = 0, E = Locals.size(); I != E; ++I) {
4106 if (I) Constraint +=
',';
4110 ReadHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
4118 std::string Constraint;
4119 for (
unsigned I = 0, E = Locals.size(); I != E; ++I) {
4120 if (I) Constraint +=
',';
4121 Constraint +=
"=*m";
4124 WriteHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
4129 void FragileHazards::emitWriteHazard() {
4130 if (Locals.empty())
return;
4135 void FragileHazards::emitReadHazard(
CGBuilderTy &Builder) {
4136 assert(!Locals.empty());
4137 llvm::CallInst *call = Builder.CreateCall(ReadHazard, Locals);
4138 call->setDoesNotThrow();
4144 void FragileHazards::emitHazardsInNewBlocks() {
4145 if (Locals.empty())
return;
4150 for (llvm::Function::iterator
4151 FI = CGF.
CurFn->begin(), FE = CGF.
CurFn->end(); FI != FE; ++FI) {
4152 llvm::BasicBlock &BB = *FI;
4153 if (BlocksBeforeTry.count(&BB))
continue;
4156 for (llvm::BasicBlock::iterator
4157 BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) {
4158 llvm::Instruction &I = *BI;
4162 if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I))
continue;
4163 if (isa<llvm::IntrinsicInst>(I))
4168 llvm::CallSite CS(&I);
4169 if (CS.doesNotThrow())
continue;
4176 Builder.SetInsertPoint(&BB, BI);
4177 emitReadHazard(Builder);
4190 void FragileHazards::collectLocals() {
4198 llvm::BasicBlock &Entry = CGF.
CurFn->getEntryBlock();
4199 for (llvm::BasicBlock::iterator
4200 I = Entry.begin(), E = Entry.end(); I != E; ++I)
4201 if (isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I))
4202 Locals.push_back(&*I);
4205 llvm::FunctionType *FragileHazards::GetAsmFnType() {
4207 for (
unsigned i = 0, e = Locals.size(); i != e; ++i)
4208 tys[i] = Locals[i]->getType();
4209 return llvm::FunctionType::get(CGF.
VoidTy, tys,
false);
4326 bool isTry = isa<ObjCAtTryStmt>(S);
4346 CGF.
EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
4359 "exceptiondata.ptr");
4365 FragileHazards Hazards(CGF);
4394 ExceptionData.getPointer());
4397 llvm::Constant *Zero = llvm::ConstantInt::get(CGF.
Builder.getInt32Ty(), 0);
4400 ObjCTypes.ExceptionDataTy, ExceptionData.getPointer(), GEPIndexes,
4403 ObjCTypes.getSetJmpFn(), SetJmpBuffer,
"setjmp_result");
4404 SetJmpResult->setCanReturnTwice();
4411 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
4412 CGF.
Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
4417 CGF.
EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
4418 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
4420 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.
Builder.saveAndClearIP();
4426 Hazards.emitWriteHazard();
4430 if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
4439 llvm::CallInst *Caught =
4441 ExceptionData.getPointer(),
"caught");
4451 llvm::BasicBlock *CatchBlock =
nullptr;
4452 llvm::BasicBlock *CatchHandler =
nullptr;
4458 "propagating_exception");
4464 ExceptionData.getPointer());
4466 llvm::CallInst *SetJmpResult =
4468 SetJmpBuffer,
"setjmp.result");
4469 SetJmpResult->setCanReturnTwice();
4472 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
4476 CGF.
Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
4486 bool AllMatched =
false;
4516 EmitInitOfCatchParam(CGF, Caught, CatchParam);
4528 assert(OPT &&
"Unexpected non-object pointer type in @catch");
4533 assert(IDecl &&
"Catch parameter must have Objective-C type!");
4539 llvm::CallInst *Match =
4541 matchArgs,
"match");
4546 CGF.
Builder.CreateCondBr(CGF.
Builder.CreateIsNotNull(Match,
"matched"),
4547 MatchedBlock, NextCatchBlock);
4563 EmitInitOfCatchParam(CGF, Tmp, CatchParam);
4579 if (Caught->use_empty())
4580 Caught->eraseFromParent();
4596 assert(PropagatingExnVar.
isValid());
4597 llvm::CallInst *NewCaught =
4599 ExceptionData.getPointer(),
"caught");
4609 Hazards.emitHazardsInNewBlocks();
4612 CGF.
Builder.restoreIP(TryFallthroughIP);
4616 CGF.
EmitBlock(FinallyEnd.getBlock(),
true);
4619 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
4624 if (PropagatingExnVar.
isValid()) {
4629 llvm::CallInst *Caught =
4631 ExceptionData.getPointer());
4632 PropagatingExn = Caught;
4637 CGF.
Builder.CreateUnreachable();
4640 CGF.
Builder.restoreIP(SavedIP);
4645 bool ClearInsertionPoint) {
4654 "Unexpected rethrow outside @catch block.");
4658 CGF.
EmitRuntimeCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
4659 ->setDoesNotReturn();
4660 CGF.
Builder.CreateUnreachable();
4663 if (ClearInsertionPoint)
4664 CGF.
Builder.ClearInsertionPoint();
4674 ObjCTypes.PtrObjectPtrTy);
4688 if (!isa<llvm::PointerType>(SrcTy)) {
4689 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(SrcTy);
4690 assert(Size <= 8 && "does not support size > 8
"); 4691 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty) 4692 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty); 4693 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 4695 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 4696 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 4697 llvm::Value *args[] = { src, dst.getPointer() }; 4698 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), 4699 args, "weakassign
"); 4705 void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
4706 llvm::Value *src, Address dst,
4708 llvm::Type * SrcTy = src->getType();
4709 if (!isa<llvm::PointerType>(SrcTy)) {
4710 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4711 assert(Size <= 8 && "does
not support size > 8
"); 4712 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty) 4713 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty); 4714 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 4716 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 4717 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 4718 llvm::Value *args[] = { src, dst.getPointer() }; 4720 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), 4721 args, "globalassign
"); 4723 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(), 4724 args, "threadlocalassign
"); 4730 void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
4731 llvm::Value *src, Address dst,
4732 llvm::Value *ivarOffset) {
4733 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is
NULL"); 4734 llvm::Type * SrcTy = src->getType(); 4735 if (!isa<llvm::PointerType>(SrcTy)) { 4736 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy); 4737 assert(Size <= 8 && "does
not support size > 8
"); 4738 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty) 4739 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty); 4740 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 4742 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 4743 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 4744 llvm::Value *args[] = { src, dst.getPointer(), ivarOffset }; 4745 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args); 4751 void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
4752 llvm::Value *src, Address dst) {
4753 llvm::Type * SrcTy = src->getType();
4754 if (!isa<llvm::PointerType>(SrcTy)) {
4755 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4756 assert(Size <= 8 && "does
not support size > 8
"); 4757 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty) 4758 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty); 4759 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 4761 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 4762 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 4763 llvm::Value *args[] = { src, dst.getPointer() }; 4764 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), 4765 args, "strongassign
"); 4768 void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, 4771 llvm::Value *size) { 4772 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy); 4773 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy); 4774 llvm::Value *args[] = { DestPtr.getPointer(), SrcPtr.getPointer(), size }; 4775 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args); 4780 LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
4782 llvm::Value *BaseValue,
4783 const ObjCIvarDecl *Ivar,
4784 unsigned CVRQualifiers) {
4785 const ObjCInterfaceDecl *ID =
4786 ObjectTy->getAs<ObjCObjectType>()->getInterface();
4787 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
4788 EmitIvarOffset(CGF, ID, Ivar));
4791 llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
4792 const ObjCInterfaceDecl *Interface,
4793 const ObjCIvarDecl *Ivar) {
4794 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
4795 return llvm::ConstantInt::get(
4796 CGM.getTypes().ConvertType(CGM.getContext().LongTy),
4800 /* *** Private Interface *** */
4802 std::string CGObjCCommonMac::GetSectionName(StringRef Section,
4803 StringRef MachOAttributes) {
4804 switch (CGM.getTriple().getObjectFormat()) {
4806 llvm_unreachable("unexpected
object file format
"); 4807 case llvm::Triple::MachO: { 4808 if (MachOAttributes.empty()) 4809 return ("__DATA,
" + Section).str(); 4810 return ("__DATA,
" + Section + ",
" + MachOAttributes).str(); 4812 case llvm::Triple::ELF: 4813 assert(Section.substr(0, 2) == "__
" && 4814 "expected the name to begin with __
"); 4815 return Section.substr(2).str(); 4816 case llvm::Triple::COFF: 4817 assert(Section.substr(0, 2) == "__
" && 4818 "expected the name to begin with __
"); 4819 return (".
" + Section.substr(2) + "$B
").str(); 4831 enum ImageInfoFlags {
4832 eImageInfo_FixAndContinue = (1 << 0), // This flag is no longer set by clang.
4833 eImageInfo_GarbageCollected = (1 << 1),
4834 eImageInfo_GCOnly = (1 << 2),
4835 eImageInfo_OptimizedByDyld = (1 << 3), // This flag is set by the dyld shared cache.
4837 // A flag indicating that the module has no instances of a @synthesize of a
4838 // superclass variable. <rdar://problem/6803242>
4839 eImageInfo_CorrectedSynthesize = (1 << 4), // This flag is no longer set by clang.
4840 eImageInfo_ImageIsSimulated = (1 << 5),
4841 eImageInfo_ClassProperties = (1 << 6)
4844 void CGObjCCommonMac::EmitImageInfo() {
4845 unsigned version = 0; // Version is unused?
4846 std::string Section =
4848 ? "__OBJC,__image_info,regular
" 4849 : GetSectionName("__objc_imageinfo
", "regular,no_dead_strip
"); 4851 // Generate module-level named metadata to convey this information to the 4852 // linker and code-gen. 4853 llvm::Module &Mod = CGM.getModule(); 4855 // Add the ObjC ABI version to the module flags. 4856 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Version
", ObjCABI); 4857 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Version
", 4859 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Section
", 4860 llvm::MDString::get(VMContext, Section)); 4862 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) { 4863 // Non-GC overrides those files which specify GC. 4864 Mod.addModuleFlag(llvm::Module::Override, 4865 "Objective-C Garbage Collection
", (uint32_t)0); 4867 // Add the ObjC garbage collection value. 4868 Mod.addModuleFlag(llvm::Module::Error, 4869 "Objective-C Garbage Collection
", 4870 eImageInfo_GarbageCollected); 4872 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) { 4873 // Add the ObjC GC Only value. 4874 Mod.addModuleFlag(llvm::Module::Error, "Objective-C GC Only
", 4877 // Require that GC be specified and set to eImageInfo_GarbageCollected. 4878 llvm::Metadata *Ops[2] = { 4879 llvm::MDString::get(VMContext, "Objective-C Garbage Collection
"), 4880 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( 4881 llvm::Type::getInt32Ty(VMContext), eImageInfo_GarbageCollected))}; 4882 Mod.addModuleFlag(llvm::Module::Require, "Objective-C GC Only
", 4883 llvm::MDNode::get(VMContext, Ops)); 4887 // Indicate whether we're compiling this to run on a simulator. 4888 if (CGM.getTarget().getTriple().isSimulatorEnvironment()) 4889 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Is Simulated
", 4890 eImageInfo_ImageIsSimulated); 4892 // Indicate whether we are generating class properties. 4893 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Class Properties
", 4894 eImageInfo_ClassProperties); 4897 // struct objc_module { 4898 // unsigned long version; 4899 // unsigned long size; 4900 // const char *name; 4904 // FIXME: Get from somewhere 4905 static const int ModuleVersion = 7; 4907 void CGObjCMac::EmitModuleInfo() { 4908 uint64_t Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ModuleTy); 4910 ConstantInitBuilder builder(CGM); 4911 auto values = builder.beginStruct(ObjCTypes.ModuleTy); 4912 values.addInt(ObjCTypes.LongTy, ModuleVersion); 4913 values.addInt(ObjCTypes.LongTy, Size); 4914 // This used to be the filename, now it is unused. <rdr://4327263> 4915 values.add(GetClassName(StringRef(""))); 4916 values.add(EmitModuleSymbols()); 4917 CreateMetadataVar("OBJC_MODULES
", values, 4918 "__OBJC,__module_info,regular,no_dead_strip
", 4919 CGM.getPointerAlign(), true); 4922 llvm::Constant *CGObjCMac::EmitModuleSymbols() { 4923 unsigned NumClasses = DefinedClasses.size(); 4924 unsigned NumCategories = DefinedCategories.size(); 4926 // Return null if no symbols were defined. 4927 if (!NumClasses && !NumCategories) 4928 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy); 4930 ConstantInitBuilder builder(CGM); 4931 auto values = builder.beginStruct(); 4932 values.addInt(ObjCTypes.LongTy, 0); 4933 values.addNullPointer(ObjCTypes.SelectorPtrTy); 4934 values.addInt(ObjCTypes.ShortTy, NumClasses); 4935 values.addInt(ObjCTypes.ShortTy, NumCategories); 4937 // The runtime expects exactly the list of defined classes followed 4938 // by the list of defined categories, in a single array. 4939 auto array = values.beginArray(ObjCTypes.Int8PtrTy); 4940 for (unsigned i=0; i<NumClasses; i++) { 4941 const ObjCInterfaceDecl *ID = ImplementedClasses[i]; 4943 if (ObjCImplementationDecl *IMP = ID->getImplementation()) 4944 // We are implementing a weak imported interface. Give it external linkage 4945 if (ID->isWeakImported() && !IMP->isWeakImported()) 4946 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage); 4948 array.addBitCast(DefinedClasses[i], ObjCTypes.Int8PtrTy); 4950 for (unsigned i=0; i<NumCategories; i++) 4951 array.addBitCast(DefinedCategories[i], ObjCTypes.Int8PtrTy); 4953 array.finishAndAddTo(values); 4955 llvm::GlobalVariable *GV = CreateMetadataVar( 4956 "OBJC_SYMBOLS
", values, "__OBJC,__symbols,regular,no_dead_strip
", 4957 CGM.getPointerAlign(), true); 4958 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy); 4961 llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF, 4962 IdentifierInfo *II) { 4963 LazySymbols.insert(II); 4965 llvm::GlobalVariable *&Entry = ClassReferences[II]; 4968 llvm::Constant *Casted = 4969 llvm::ConstantExpr::getBitCast(GetClassName(II->getName()), 4970 ObjCTypes.ClassPtrTy); 4971 Entry = CreateMetadataVar( 4972 "OBJC_CLASS_REFERENCES_
", Casted, 4973 "__OBJC,__cls_refs,literal_pointers,no_dead_strip
", 4974 CGM.getPointerAlign(), true); 4977 return CGF.Builder.CreateAlignedLoad(Entry, CGF.getPointerAlign()); 4980 llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF, 4981 const ObjCInterfaceDecl *ID) { 4982 // If the class has the objc_runtime_visible attribute, we need to 4983 // use the Objective-C runtime to get the class. 4984 if (ID->hasAttr<ObjCRuntimeVisibleAttr>()) 4985 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes); 4987 return EmitClassRefFromId(CGF, ID->getIdentifier()); 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);
6312 if (CGM.
getTriple().isOSBinFormatCOFF())
6313 if (CI->hasAttr<DLLExportAttr>())
6314 MetaTClass->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
6315 DefinedMetaClasses.push_back(MetaTClass);
6338 if (!CI->getSuperClass()) {
6340 SuperClassGV =
nullptr;
6343 const auto *Super = CI->getSuperClass();
6347 GetClassSizeInfo(ID, InstanceStart, InstanceSize);
6349 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
6351 llvm::GlobalVariable *ClassMD =
6352 BuildClassObject(CI,
false,
6353 MetaTClass, SuperClassGV, CLASS_RO_GV, classIsHidden);
6354 if (CGM.
getTriple().isOSBinFormatCOFF())
6355 if (CI->hasAttr<DLLExportAttr>())
6356 ClassMD->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
6357 DefinedClasses.push_back(ClassMD);
6358 ImplementedClasses.push_back(CI);
6361 if (ImplementationIsNonLazy(ID))
6362 DefinedNonLazyClasses.push_back(ClassMD);
6368 MethodDefinitions.clear();
6385 llvm::Constant *Init =
6386 llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD),
6387 ObjCTypes.getExternalProtocolPtrTy());
6389 std::string ProtocolName(
"\01l_OBJC_PROTOCOL_REFERENCE_$_");
6394 llvm::GlobalVariable *PTGV = CGM.
getModule().getGlobalVariable(ProtocolName);
6397 PTGV =
new llvm::GlobalVariable(CGM.
getModule(), Init->getType(),
false,
6398 llvm::GlobalValue::WeakAnyLinkage, Init,
6400 PTGV->setSection(GetSectionName(
"__objc_protorefs",
6401 "coalesced,no_dead_strip"));
6404 if (!CGM.
getTriple().isOSBinFormatMachO())
6405 PTGV->setComdat(CGM.
getModule().getOrInsertComdat(ProtocolName));
6424 const char *Prefix =
"\01l_OBJC_$_CATEGORY_";
6428 ExtCatName +=
"_$_";
6432 auto values = builder.
beginStruct(ObjCTypes.CategorynfABITy);
6436 std::string listName =
6441 for (
const auto *MD : OCD->
methods()) {
6443 instanceMethods.push_back(MD);
6445 classMethods.push_back(MD);
6449 values.add(emitMethodList(listName, MethodListType::CategoryInstanceMethods,
6451 values.add(emitMethodList(listName, MethodListType::CategoryClassMethods,
6460 values.add(EmitProtocolList(
"\01l_OBJC_CATEGORY_PROTOCOLS_$_" 6465 values.add(EmitPropertyList(
"\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
6467 values.add(EmitPropertyList(
"\01l_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(),
6470 values.addNullPointer(ObjCTypes.ProtocolListnfABIPtrTy);
6471 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
6472 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
6475 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.CategorynfABITy);
6476 values.addInt(ObjCTypes.IntTy, Size);
6478 llvm::GlobalVariable *GCATV =
6481 llvm::GlobalValue::PrivateLinkage);
6482 if (CGM.
getTriple().isOSBinFormatMachO())
6483 GCATV->setSection(
"__DATA, __objc_const");
6485 DefinedCategories.push_back(GCATV);
6488 if (ImplementationIsNonLazy(OCD))
6489 DefinedNonLazyCategories.push_back(GCATV);
6491 MethodDefinitions.clear();
6506 auto method = builder.
beginStruct(ObjCTypes.MethodTy);
6507 method.addBitCast(GetMethodVarName(MD->
getSelector()),
6508 ObjCTypes.SelectorPtrTy);
6509 method.add(GetMethodVarType(MD));
6513 method.addNullPointer(ObjCTypes.Int8PtrTy);
6515 llvm::Function *fn = GetMethodDefinition(MD);
6516 assert(fn &&
"no definition for method?");
6517 method.addBitCast(fn, ObjCTypes.Int8PtrTy);
6520 method.finishAndAddTo(builder);
6535 if (methods.empty())
6536 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
6541 case MethodListType::CategoryInstanceMethods:
6542 prefix =
"\01l_OBJC_$_CATEGORY_INSTANCE_METHODS_";
6543 forProtocol =
false;
6545 case MethodListType::CategoryClassMethods:
6546 prefix =
"\01l_OBJC_$_CATEGORY_CLASS_METHODS_";
6547 forProtocol =
false;
6549 case MethodListType::InstanceMethods:
6550 prefix =
"\01l_OBJC_$_INSTANCE_METHODS_";
6551 forProtocol =
false;
6553 case MethodListType::ClassMethods:
6554 prefix =
"\01l_OBJC_$_CLASS_METHODS_";
6555 forProtocol =
false;
6558 case MethodListType::ProtocolInstanceMethods:
6559 prefix =
"\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_";
6562 case MethodListType::ProtocolClassMethods:
6563 prefix =
"\01l_OBJC_$_PROTOCOL_CLASS_METHODS_";
6566 case MethodListType::OptionalProtocolInstanceMethods:
6567 prefix =
"\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_";
6570 case MethodListType::OptionalProtocolClassMethods:
6571 prefix =
"\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_";
6580 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.MethodTy);
6581 values.addInt(ObjCTypes.IntTy, Size);
6583 values.addInt(ObjCTypes.IntTy, methods.size());
6584 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
6585 for (
auto MD : methods) {
6586 emitMethodConstant(methodArray, MD, forProtocol);
6588 methodArray.finishAndAddTo(values);
6590 auto *GV = values.finishAndCreateGlobal(prefix + name, CGM.
getPointerAlign(),
6592 llvm::GlobalValue::PrivateLinkage);
6593 if (CGM.
getTriple().isOSBinFormatMachO())
6594 GV->setSection(
"__DATA, __objc_const");
6596 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListnfABIPtrTy);
6601 llvm::GlobalVariable *
6609 llvm::GlobalVariable *IvarOffsetGV = CGM.
getModule().getGlobalVariable(Name);
6610 if (!IvarOffsetGV) {
6612 new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.IvarOffsetVarTy,
6614 nullptr, Name.str());
6615 if (CGM.
getTriple().isOSBinFormatCOFF()) {
6616 bool IsPrivateOrPackage =
6622 if (ContainingID->
hasAttr<DLLImportAttr>())
6624 ->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
6625 else if (ContainingID->
hasAttr<DLLExportAttr>() && !IsPrivateOrPackage)
6627 ->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
6630 return IvarOffsetGV;
6636 unsigned long int Offset) {
6637 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
6638 IvarOffsetGV->setInitializer(
6639 llvm::ConstantInt::get(ObjCTypes.IvarOffsetVarTy, Offset));
6640 IvarOffsetGV->setAlignment(
6641 CGM.
getDataLayout().getABITypeAlignment(ObjCTypes.IvarOffsetVarTy));
6643 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
6654 if (CGM.
getTriple().isOSBinFormatMachO())
6655 IvarOffsetGV->setSection(
"__DATA, __objc_ivar");
6656 return IvarOffsetGV;
6676 llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
6681 ivarList.addInt(ObjCTypes.IntTy,
6682 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.IvarnfABITy));
6683 auto ivarCountSlot = ivarList.addPlaceholder();
6684 auto ivars = ivarList.beginArray(ObjCTypes.IvarnfABITy);
6687 assert(OID &&
"CGObjCNonFragileABIMac::EmitIvarList - null interface");
6694 if (!IVD->getDeclName())
6697 auto ivar = ivars.beginStruct(ObjCTypes.IvarnfABITy);
6699 ComputeIvarBaseOffset(CGM, ID, IVD)));
6700 ivar.add(GetMethodVarName(IVD->getIdentifier()));
6701 ivar.add(GetMethodVarType(IVD));
6704 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(FieldTy);
6706 IVD->getType().getTypePtr()) >> 3;
6707 Align = llvm::Log2_32(Align);
6708 ivar.addInt(ObjCTypes.IntTy, Align);
6714 ivar.addInt(ObjCTypes.IntTy, Size);
6715 ivar.finishAndAddTo(ivars);
6718 if (ivars.empty()) {
6721 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
6724 auto ivarCount = ivars.size();
6725 ivars.finishAndAddTo(ivarList);
6726 ivarList.fillPlaceholderWithInt(ivarCountSlot, ObjCTypes.IntTy, ivarCount);
6728 const char *Prefix =
"\01l_OBJC_$_INSTANCE_VARIABLES_";
6729 llvm::GlobalVariable *GV =
6732 llvm::GlobalValue::PrivateLinkage);
6733 if (CGM.
getTriple().isOSBinFormatMachO())
6734 GV->setSection(
"__DATA, __objc_const");
6736 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy);
6739 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(
6741 llvm::GlobalVariable *&Entry = Protocols[PD->
getIdentifier()];
6748 llvm::raw_svector_ostream(Protocol) <<
"\01l_OBJC_PROTOCOL_$_" 6751 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolnfABITy,
6754 if (!CGM.
getTriple().isOSBinFormatMachO())
6755 Entry->setComdat(CGM.
getModule().getOrInsertComdat(Protocol));
6781 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
6783 llvm::GlobalVariable *Entry = Protocols[PD->
getIdentifier()];
6786 if (Entry && Entry->hasInitializer())
6793 auto methodLists = ProtocolMethodLists::get(PD);
6796 auto values = builder.
beginStruct(ObjCTypes.ProtocolnfABITy);
6799 values.addNullPointer(ObjCTypes.ObjectPtrTy);
6801 values.add(EmitProtocolList(
"\01l_OBJC_$_PROTOCOL_REFS_" 6805 values.add(methodLists.emitMethodList(
this, PD,
6806 ProtocolMethodLists::RequiredInstanceMethods));
6807 values.add(methodLists.emitMethodList(
this, PD,
6808 ProtocolMethodLists::RequiredClassMethods));
6809 values.add(methodLists.emitMethodList(
this, PD,
6810 ProtocolMethodLists::OptionalInstanceMethods));
6811 values.add(methodLists.emitMethodList(
this, PD,
6812 ProtocolMethodLists::OptionalClassMethods));
6813 values.add(EmitPropertyList(
6815 nullptr, PD, ObjCTypes,
false));
6817 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
6818 values.addInt(ObjCTypes.IntTy, Size);
6819 values.addInt(ObjCTypes.IntTy, 0);
6820 values.add(EmitProtocolMethodTypes(
"\01l_OBJC_$_PROTOCOL_METHOD_TYPES_" 6822 methodLists.emitExtendedTypesArray(
this),
6826 values.addNullPointer(ObjCTypes.Int8PtrTy);
6828 values.add(EmitPropertyList(
6830 nullptr, PD, ObjCTypes,
true));
6834 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
6835 values.finishAndSetAsInitializer(Entry);
6838 llvm::raw_svector_ostream(symbolName)
6841 Entry = values.finishAndCreateGlobal(symbolName, CGM.
getPointerAlign(),
6843 llvm::GlobalValue::WeakAnyLinkage);
6844 if (!CGM.
getTriple().isOSBinFormatMachO())
6845 Entry->setComdat(CGM.
getModule().getOrInsertComdat(symbolName));
6855 llvm::raw_svector_ostream(ProtocolRef) <<
"\01l_OBJC_LABEL_PROTOCOL_$_" 6858 llvm::GlobalVariable *PTGV =
6859 new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolnfABIPtrTy,
6860 false, llvm::GlobalValue::WeakAnyLinkage, Entry,
6862 if (!CGM.
getTriple().isOSBinFormatMachO())
6863 PTGV->setComdat(CGM.
getModule().getOrInsertComdat(ProtocolRef));
6865 CGM.
getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy));
6866 PTGV->setSection(GetSectionName(
"__objc_protolist",
6867 "coalesced,no_dead_strip"));
6882 CGObjCNonFragileABIMac::EmitProtocolList(Twine Name,
6889 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
6893 Name.toVector(TmpName);
6894 llvm::GlobalVariable *GV =
6895 CGM.
getModule().getGlobalVariable(TmpName.str(),
true);
6897 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy);
6901 auto countSlot = values.addPlaceholder();
6904 auto array = values.beginArray(ObjCTypes.ProtocolnfABIPtrTy);
6905 for (; begin != end; ++begin)
6906 array.add(GetProtocolRef(*begin));
6907 auto count = array.size();
6908 array.addNullPointer(ObjCTypes.ProtocolnfABIPtrTy);
6910 array.finishAndAddTo(values);
6911 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
6915 llvm::GlobalValue::PrivateLinkage);
6916 if (CGM.
getTriple().isOSBinFormatMachO())
6917 GV->setSection(
"__DATA, __objc_const");
6919 return llvm::ConstantExpr::getBitCast(GV,
6920 ObjCTypes.ProtocolListnfABIPtrTy);
6929 LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
6934 unsigned CVRQualifiers) {
6936 llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
6937 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
6941 llvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset(
6945 llvm::Value *IvarOffsetValue = ObjCIvarOffsetVariable(Interface, Ivar);
6948 if (IsIvarOffsetKnownIdempotent(CGF, Ivar))
6949 cast<llvm::LoadInst>(IvarOffsetValue)
6950 ->setMetadata(CGM.
getModule().getMDKindID(
"invariant.load"),
6951 llvm::MDNode::get(VMContext,
None));
6956 if (ObjCTypes.IvarOffsetVarTy == ObjCTypes.IntTy)
6957 IvarOffsetValue = CGF.
Builder.CreateIntCast(
6958 IvarOffsetValue, ObjCTypes.LongTy,
true,
"ivar.conv");
6959 return IvarOffsetValue;
6962 static void appendSelectorForMessageRefTable(std::string &buffer,
6969 for (
unsigned i = 0, e = selector.
getNumArgs(); i != e; ++i) {
7007 args.insert(args.end(), formalArgs.begin(), formalArgs.end());
7009 MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);
7011 NullReturnState nullReturn;
7020 llvm::Constant *fn =
nullptr;
7021 std::string messageRefName(
"\01l_");
7024 fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
7025 messageRefName +=
"objc_msgSendSuper2_stret_fixup";
7027 nullReturn.init(CGF, arg0);
7028 fn = ObjCTypes.getMessageSendStretFixupFn();
7029 messageRefName +=
"objc_msgSend_stret_fixup";
7032 fn = ObjCTypes.getMessageSendFpretFixupFn();
7033 messageRefName +=
"objc_msgSend_fpret_fixup";
7036 fn = ObjCTypes.getMessageSendSuper2FixupFn();
7037 messageRefName +=
"objc_msgSendSuper2_fixup";
7039 fn = ObjCTypes.getMessageSendFixupFn();
7040 messageRefName +=
"objc_msgSend_fixup";
7043 assert(fn &&
"CGObjCNonFragileABIMac::EmitMessageSend");
7044 messageRefName +=
'_';
7048 appendSelectorForMessageRefTable(messageRefName, selector);
7050 llvm::GlobalVariable *messageRef
7051 = CGM.
getModule().getGlobalVariable(messageRefName);
7057 values.add(GetMethodVarName(selector));
7058 messageRef = values.finishAndCreateGlobal(messageRefName,
7061 llvm::GlobalValue::WeakAnyLinkage);
7063 messageRef->setSection(GetSectionName(
"__objc_msgrefs",
"coalesced"));
7066 bool requiresnullCheck =
false;
7068 for (
const auto *ParamDecl : method->
parameters()) {
7069 if (ParamDecl->hasAttr<NSConsumedAttr>()) {
7070 if (!nullReturn.NullBB)
7071 nullReturn.init(CGF, arg0);
7072 requiresnullCheck =
true;
7092 RValue result = CGF.
EmitCall(MSI.CallInfo, callee, returnSlot, args);
7093 return nullReturn.complete(CGF, returnSlot, result, resultType, formalArgs,
7094 requiresnullCheck ? method :
nullptr);
7107 return isVTableDispatchedSelector(Sel)
7108 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
7110 false, CallArgs, Method)
7111 : EmitMessageSend(CGF, Return, ResultType,
7112 EmitSelector(CGF, Sel),
7114 false, CallArgs, Method, Class, ObjCTypes);
7122 (metaclass ? getMetaclassSymbolPrefix() : getClassSymbolPrefix());
7128 && ID->
hasAttr<DLLImportAttr>());
7132 CGObjCNonFragileABIMac::GetClassGlobal(StringRef Name,
7134 bool Weak,
bool DLLImport) {
7135 llvm::GlobalValue::LinkageTypes L =
7136 Weak ? llvm::GlobalValue::ExternalWeakLinkage
7141 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name);
7143 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassnfABITy,
7144 false, L,
nullptr, Name);
7147 GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
7150 assert(GV->getLinkage() == L);
7159 llvm::GlobalVariable *&Entry = ClassReferences[II];
7162 llvm::Constant *ClassGV;
7166 ClassGV = GetClassGlobal((getClassSymbolPrefix() + II->
getName()).str(),
7170 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassnfABIPtrTy,
7171 false, llvm::GlobalValue::PrivateLinkage,
7172 ClassGV,
"OBJC_CLASSLIST_REFERENCES_$_");
7174 Entry->setSection(GetSectionName(
"__objc_classrefs",
7175 "regular,no_dead_strip"));
7185 if (ID->
hasAttr<ObjCRuntimeVisibleAttr>())
7186 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
7191 llvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(
7194 return EmitClassRefFromId(CGF, II,
nullptr);
7201 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->
getIdentifier()];
7205 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassnfABIPtrTy,
7206 false, llvm::GlobalValue::PrivateLinkage,
7207 ClassGV,
"OBJC_CLASSLIST_SUP_REFS_$_");
7209 Entry->setSection(GetSectionName(
"__objc_superrefs",
7210 "regular,no_dead_strip"));
7223 llvm::GlobalVariable * &Entry = MetaClassReferences[ID->
getIdentifier()];
7227 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassnfABIPtrTy,
7228 false, llvm::GlobalValue::PrivateLinkage,
7229 MetaClassGV,
"OBJC_CLASSLIST_SUP_REFS_$_");
7232 Entry->setSection(GetSectionName(
"__objc_superrefs",
7233 "regular,no_dead_strip"));
7247 assert(!isa<llvm::GlobalVariable>(ClassGV) ||
7248 cast<llvm::GlobalVariable>(ClassGV)->hasExternalWeakLinkage());
7251 return EmitClassRef(CGF, ID);
7263 bool isCategoryImpl,
7265 bool IsClassMessage,
7286 Target = EmitSuperClassRef(CGF, Class);
7296 return (isVTableDispatchedSelector(Sel))
7297 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
7298 ObjCSuper.
getPointer(), ObjCTypes.SuperPtrCTy,
7299 true, CallArgs, Method)
7300 : EmitMessageSend(CGF, Return, ResultType,
7301 EmitSelector(CGF, Sel),
7302 ObjCSuper.
getPointer(), ObjCTypes.SuperPtrCTy,
7303 true, CallArgs, Method, Class, ObjCTypes);
7308 Address Addr = EmitSelectorAddr(CGF, Sel);
7311 LI->setMetadata(CGM.
getModule().getMDKindID(
"invariant.load"),
7312 llvm::MDNode::get(VMContext,
None));
7318 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
7322 llvm::Constant *Casted =
7323 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
7324 ObjCTypes.SelectorPtrTy);
7325 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.SelectorPtrTy,
7326 false, llvm::GlobalValue::PrivateLinkage,
7327 Casted,
"OBJC_SELECTOR_REFERENCES_");
7328 Entry->setExternallyInitialized(
true);
7329 Entry->setSection(GetSectionName(
"__objc_selrefs",
7330 "literal_pointers,no_dead_strip"));
7346 if (!isa<llvm::PointerType>(SrcTy)) {
7347 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(SrcTy);
7348 assert(Size <= 8 && "does not support size > 8
"); 7349 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 7350 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 7351 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 7353 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 7354 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 7355 llvm::Value *args[] = { src, dst.getPointer(), ivarOffset }; 7356 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args); 7362 void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
7363 CodeGen::CodeGenFunction &CGF,
7364 llvm::Value *src, Address dst) {
7365 llvm::Type * SrcTy = src->getType();
7366 if (!isa<llvm::PointerType>(SrcTy)) {
7367 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7368 assert(Size <= 8 && "does
not support size > 8
"); 7369 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 7370 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 7371 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 7373 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 7374 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 7375 llvm::Value *args[] = { src, dst.getPointer() }; 7376 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), 7377 args, "weakassign
"); 7380 void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable( 7381 CodeGen::CodeGenFunction &CGF, 7384 llvm::Value *Size) { 7385 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy); 7386 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy); 7387 llvm::Value *args[] = { DestPtr.getPointer(), SrcPtr.getPointer(), Size }; 7388 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args); 7394 llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(
7395 CodeGen::CodeGenFunction &CGF,
7396 Address AddrWeakObj) {
7397 llvm::Type *DestTy = AddrWeakObj.getElementType();
7398 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy);
7399 llvm::Value *read_weak =
7400 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(),
7401 AddrWeakObj.getPointer(), "weakread
"); 7402 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy); 7409 void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
7410 llvm::Value *src, Address dst) {
7411 llvm::Type * SrcTy = src->getType();
7412 if (!isa<llvm::PointerType>(SrcTy)) {
7413 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7414 assert(Size <= 8 && "does
not support size > 8
"); 7415 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 7416 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 7417 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 7419 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 7420 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 7421 llvm::Value *args[] = { src, dst.getPointer() }; 7422 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), 7423 args, "weakassign
"); 7429 void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
7430 llvm::Value *src, Address dst,
7432 llvm::Type * SrcTy = src->getType();
7433 if (!isa<llvm::PointerType>(SrcTy)) {
7434 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7435 assert(Size <= 8 && "does
not support size > 8
"); 7436 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 7437 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 7438 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 7440 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 7441 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 7442 llvm::Value *args[] = { src, dst.getPointer() }; 7444 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), 7445 args, "globalassign
"); 7447 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(), 7448 args, "threadlocalassign
"); 7452 CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 7453 const ObjCAtSynchronizedStmt &S) { 7454 EmitAtSynchronizedStmt(CGF, S, 7455 cast<llvm::Function>(ObjCTypes.getSyncEnterFn()), 7456 cast<llvm::Function>(ObjCTypes.getSyncExitFn())); 7460 CGObjCNonFragileABIMac::GetEHType(QualType T) { 7461 // There's a particular fixed type info for 'id'. 7462 if (T->isObjCIdType() || T->isObjCQualifiedIdType()) { 7463 auto *IDEHType = CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id
"); 7466 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false, 7467 llvm::GlobalValue::ExternalLinkage, nullptr, 7469 if (CGM.getTriple().isOSBinFormatCOFF()) 7470 IDEHType->setDLLStorageClass(getStorage(CGM, "OBJC_EHTYPE_id
")); 7475 // All other types should be Objective-C interface pointer types. 7476 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>(); 7477 assert(PT && "Invalid
@catch type.
"); 7479 const ObjCInterfaceType *IT = PT->getInterfaceType(); 7480 assert(IT && "Invalid
@catch type.
"); 7482 return GetInterfaceEHType(IT->getDecl(), NotForDefinition); 7485 void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, 7486 const ObjCAtTryStmt &S) { 7487 EmitTryCatchStmt(CGF, S, 7488 cast<llvm::Function>(ObjCTypes.getObjCBeginCatchFn()), 7489 cast<llvm::Function>(ObjCTypes.getObjCEndCatchFn()), 7490 cast<llvm::Function>(ObjCTypes.getExceptionRethrowFn())); 7494 void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
7495 const ObjCAtThrowStmt &S,
7496 bool ClearInsertionPoint) {
7497 if (const Expr *ThrowExpr = S.getThrowExpr()) {
7498 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
7499 Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
7500 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception)
7501 .setDoesNotReturn();
7503 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionRethrowFn())
7504 .setDoesNotReturn();
7507 CGF.Builder.CreateUnreachable();
7508 if (ClearInsertionPoint)
7509 CGF.Builder.ClearInsertionPoint();
7513 CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
7514 ForDefinition_t IsForDefinition) {
7515 llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
7516 StringRef ClassName = ID->getObjCRuntimeNameAsString();
7518 // If we don't need a definition, return the entry if found or check
7519 // if we use an external reference.
7520 if (!IsForDefinition) {
7524 // If this type (or a super class) has the __objc_exception__
7525 // attribute, emit an external reference.
7526 if (hasObjCExceptionAttribute(CGM.getContext(), ID)) {
7527 std::string EHTypeName = ("OBJC_EHTYPE_$_
" + ClassName).str(); 7528 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, 7529 false, llvm::GlobalValue::ExternalLinkage, 7530 nullptr, EHTypeName); 7531 if (CGM.getTriple().isOSBinFormatCOFF()) { 7532 if (ID->hasAttr<DLLExportAttr>()) 7533 Entry->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); 7534 else if (ID->hasAttr<DLLImportAttr>()) 7535 Entry->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); 7541 // Otherwise we need to either make a new entry or fill in the initializer. 7542 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition
"); 7544 std::string VTableName = "objc_ehtype_vtable
"; 7545 auto *VTableGV = CGM.getModule().getGlobalVariable(VTableName); 7548 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy, false, 7549 llvm::GlobalValue::ExternalLinkage, nullptr, 7551 if (CGM.getTriple().isOSBinFormatCOFF()) 7552 VTableGV->setDLLStorageClass(getStorage(CGM, VTableName)); 7555 llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2); 7556 ConstantInitBuilder builder(CGM); 7557 auto values = builder.beginStruct(ObjCTypes.EHTypeTy); 7559 llvm::ConstantExpr::getInBoundsGetElementPtr(VTableGV->getValueType(), 7560 VTableGV, VTableIdx)); 7561 values.add(GetClassName(ClassName)); 7562 values.add(GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition)); 7564 llvm::GlobalValue::LinkageTypes L = IsForDefinition 7565 ? llvm::GlobalValue::ExternalLinkage 7566 : llvm::GlobalValue::WeakAnyLinkage; 7568 values.finishAndSetAsInitializer(Entry); 7569 Entry->setAlignment(CGM.getPointerAlign().getQuantity()); 7571 Entry = values.finishAndCreateGlobal("OBJC_EHTYPE_$_
" + ClassName, 7572 CGM.getPointerAlign(), 7575 if (CGM.getTriple().isOSBinFormatCOFF()) 7576 if (hasObjCExceptionAttribute(CGM.getContext(), ID)) 7577 if (ID->hasAttr<DLLExportAttr>()) 7578 Entry->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); 7580 assert(Entry->getLinkage() == L); 7582 if (!CGM.getTriple().isOSBinFormatCOFF()) 7583 if (ID->getVisibility() == HiddenVisibility) 7584 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility); 7586 if (IsForDefinition) 7587 if (CGM.getTriple().isOSBinFormatMachO()) 7588 Entry->setSection("__DATA,__objc_const
"); 7595 CodeGen::CGObjCRuntime * 7596 CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) { 7597 switch (CGM.getLangOpts().ObjCRuntime.getKind()) { 7598 case ObjCRuntime::FragileMacOSX: 7599 return new CGObjCMac(CGM); 7601 case ObjCRuntime::MacOSX: 7602 case ObjCRuntime::iOS: 7603 case ObjCRuntime::WatchOS: 7604 return new CGObjCNonFragileABIMac(CGM); 7606 case ObjCRuntime::GNUstep: 7607 case ObjCRuntime::GCC: 7608 case ObjCRuntime::ObjFW: 7609 llvm_unreachable("these runtimes are
not Mac runtimes
"); 7611 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...
VarDecl - An instance of this class is created to represent a variable declaration or definition...
Objects with "hidden" visibility are not seen by the dynamic linker.
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
ParmVarDecl - 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...
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
getIdentifier - Get the identifier that names this declaration, if there is one.
RecordDecl - 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
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
protocol_iterator protocol_begin() const
CharUnits getSizeAlign() const
llvm::CallInst * EmitRuntimeCall(llvm::Value *callee, const Twine &name="")
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names the class interface associated with this implementation...
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.
static void addIfPresent(llvm::DenseSet< llvm::Value *> &S, llvm::Value *V)
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...
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.
BlockDecl - This represents 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...
const FunctionProtoType * T
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.
llvm::AllocaInst * NormalCleanupDest
i32s containing the indexes of the cleanup destinations.
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.
void add(RValue rvalue, QualType type, bool needscopy=false)
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
getNameAsString - Get a human-readable name for the declaration, even if it is one of the special kin...
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.
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
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
getName - 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 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