28 #include "llvm/ADT/CachedHashString.h" 29 #include "llvm/ADT/DenseSet.h" 30 #include "llvm/ADT/SetVector.h" 31 #include "llvm/ADT/SmallPtrSet.h" 32 #include "llvm/ADT/SmallString.h" 33 #include "llvm/IR/DataLayout.h" 34 #include "llvm/IR/InlineAsm.h" 35 #include "llvm/IR/IntrinsicInst.h" 36 #include "llvm/IR/LLVMContext.h" 37 #include "llvm/IR/Module.h" 38 #include "llvm/Support/ScopedPrinter.h" 39 #include "llvm/Support/raw_ostream.h" 42 using namespace clang;
43 using namespace CodeGen;
50 class ObjCCommonTypesHelper {
52 llvm::LLVMContext &VMContext;
62 llvm::FunctionCallee getMessageSendFn()
const {
65 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
66 return CGM.CreateRuntimeFunction(
67 llvm::FunctionType::get(ObjectPtrTy, params,
true),
"objc_msgSend",
68 llvm::AttributeList::get(CGM.getLLVMContext(),
69 llvm::AttributeList::FunctionIndex,
70 llvm::Attribute::NonLazyBind));
78 llvm::FunctionCallee getMessageSendStretFn()
const {
79 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
80 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy,
82 "objc_msgSend_stret");
90 llvm::FunctionCallee getMessageSendFpretFn()
const {
91 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
92 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.DoubleTy,
94 "objc_msgSend_fpret");
102 llvm::FunctionCallee getMessageSendFp2retFn()
const {
103 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
104 llvm::Type *longDoubleType = llvm::Type::getX86_FP80Ty(VMContext);
106 llvm::StructType::get(longDoubleType, longDoubleType);
108 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(resultType,
110 "objc_msgSend_fp2ret");
118 llvm::FunctionCallee getMessageSendSuperFn()
const {
119 llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
120 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
122 "objc_msgSendSuper");
129 llvm::FunctionCallee getMessageSendSuperFn2()
const {
130 llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
131 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
133 "objc_msgSendSuper2");
140 llvm::FunctionCallee getMessageSendSuperStretFn()
const {
141 llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
142 return CGM.CreateRuntimeFunction(
143 llvm::FunctionType::get(CGM.VoidTy, params,
true),
144 "objc_msgSendSuper_stret");
151 llvm::FunctionCallee getMessageSendSuperStretFn2()
const {
152 llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
153 return CGM.CreateRuntimeFunction(
154 llvm::FunctionType::get(CGM.VoidTy, params,
true),
155 "objc_msgSendSuper2_stret");
158 llvm::FunctionCallee getMessageSendSuperFpretFn()
const {
160 return getMessageSendSuperFn();
163 llvm::FunctionCallee getMessageSendSuperFpretFn2()
const {
165 return getMessageSendSuperFn2();
172 llvm::IntegerType *ShortTy, *IntTy, *LongTy;
173 llvm::PointerType *Int8PtrTy, *Int8PtrPtrTy;
177 llvm::PointerType *ObjectPtrTy;
180 llvm::PointerType *PtrObjectPtrTy;
183 llvm::PointerType *SelectorPtrTy;
192 if (!ExternalProtocolPtrTy) {
198 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
201 return ExternalProtocolPtrTy;
210 llvm::StructType *SuperTy;
212 llvm::PointerType *SuperPtrTy;
216 llvm::StructType *PropertyTy;
220 llvm::StructType *PropertyListTy;
222 llvm::PointerType *PropertyListPtrTy;
225 llvm::StructType *MethodTy;
230 llvm::PointerType *CachePtrTy;
232 llvm::FunctionCallee getGetPropertyFn() {
241 llvm::FunctionType *FTy =
247 llvm::FunctionCallee getSetPropertyFn() {
260 llvm::FunctionType *FTy =
266 llvm::FunctionCallee getOptimizedSetPropertyFn(
bool atomic,
bool copy) {
281 Params.push_back(IdType);
282 Params.push_back(SelType);
283 Params.push_back(IdType);
285 llvm::FunctionType *FTy =
290 name =
"objc_setProperty_atomic_copy";
291 else if (atomic && !copy)
292 name =
"objc_setProperty_atomic";
293 else if (!atomic && copy)
294 name =
"objc_setProperty_nonatomic_copy";
296 name =
"objc_setProperty_nonatomic";
301 llvm::FunctionCallee getCopyStructFn() {
309 Params.push_back(Ctx.
BoolTy);
310 Params.push_back(Ctx.
BoolTy);
311 llvm::FunctionType *FTy =
321 llvm::FunctionCallee getCppAtomicObjectFunction() {
329 llvm::FunctionType *FTy =
335 llvm::FunctionCallee getEnumerationMutationFn() {
341 llvm::FunctionType *FTy =
347 llvm::FunctionCallee getLookUpClassFn() {
354 llvm::FunctionType *FTy =
362 llvm::FunctionCallee getGcReadWeakFn() {
364 llvm::Type *args[] = { ObjectPtrTy->getPointerTo() };
365 llvm::FunctionType *FTy =
366 llvm::FunctionType::get(ObjectPtrTy, args,
false);
371 llvm::FunctionCallee getGcAssignWeakFn() {
373 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
374 llvm::FunctionType *FTy =
375 llvm::FunctionType::get(ObjectPtrTy, args,
false);
380 llvm::FunctionCallee getGcAssignGlobalFn() {
382 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
383 llvm::FunctionType *FTy =
384 llvm::FunctionType::get(ObjectPtrTy, args,
false);
389 llvm::FunctionCallee getGcAssignThreadLocalFn() {
391 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
392 llvm::FunctionType *FTy =
393 llvm::FunctionType::get(ObjectPtrTy, args,
false);
398 llvm::FunctionCallee getGcAssignIvarFn() {
400 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo(),
402 llvm::FunctionType *FTy =
403 llvm::FunctionType::get(ObjectPtrTy, args,
false);
408 llvm::FunctionCallee GcMemmoveCollectableFn() {
410 llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, LongTy };
411 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, args,
false);
416 llvm::FunctionCallee getGcAssignStrongCastFn() {
418 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
419 llvm::FunctionType *FTy =
420 llvm::FunctionType::get(ObjectPtrTy, args,
false);
425 llvm::FunctionCallee getExceptionThrowFn() {
428 llvm::FunctionType *FTy =
429 llvm::FunctionType::get(CGM.
VoidTy, args,
false);
434 llvm::FunctionCallee getExceptionRethrowFn() {
436 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
441 llvm::FunctionCallee getSyncEnterFn() {
444 llvm::FunctionType *FTy =
445 llvm::FunctionType::get(CGM.
IntTy, args,
false);
450 llvm::FunctionCallee getSyncExitFn() {
453 llvm::FunctionType *FTy =
454 llvm::FunctionType::get(CGM.
IntTy, args,
false);
458 llvm::FunctionCallee getSendFn(
bool IsSuper)
const {
459 return IsSuper ? getMessageSendSuperFn() : getMessageSendFn();
462 llvm::FunctionCallee getSendFn2(
bool IsSuper)
const {
463 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();
466 llvm::FunctionCallee getSendStretFn(
bool IsSuper)
const {
467 return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();
470 llvm::FunctionCallee getSendStretFn2(
bool IsSuper)
const {
471 return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();
474 llvm::FunctionCallee getSendFpretFn(
bool IsSuper)
const {
475 return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();
478 llvm::FunctionCallee getSendFpretFn2(
bool IsSuper)
const {
479 return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();
482 llvm::FunctionCallee getSendFp2retFn(
bool IsSuper)
const {
483 return IsSuper ? getMessageSendSuperFn() : getMessageSendFp2retFn();
486 llvm::FunctionCallee getSendFp2RetFn2(
bool IsSuper)
const {
487 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFp2retFn();
495 class ObjCTypesHelper :
public ObjCCommonTypesHelper {
498 llvm::StructType *SymtabTy;
500 llvm::PointerType *SymtabPtrTy;
502 llvm::StructType *ModuleTy;
505 llvm::StructType *ProtocolTy;
507 llvm::PointerType *ProtocolPtrTy;
510 llvm::StructType *ProtocolExtensionTy;
513 llvm::PointerType *ProtocolExtensionPtrTy;
516 llvm::StructType *MethodDescriptionTy;
519 llvm::StructType *MethodDescriptionListTy;
522 llvm::PointerType *MethodDescriptionListPtrTy;
524 llvm::StructType *ProtocolListTy;
526 llvm::PointerType *ProtocolListPtrTy;
528 llvm::StructType *CategoryTy;
530 llvm::StructType *ClassTy;
532 llvm::PointerType *ClassPtrTy;
534 llvm::StructType *ClassExtensionTy;
536 llvm::PointerType *ClassExtensionPtrTy;
538 llvm::StructType *IvarTy;
540 llvm::StructType *IvarListTy;
542 llvm::PointerType *IvarListPtrTy;
544 llvm::StructType *MethodListTy;
546 llvm::PointerType *MethodListPtrTy;
549 llvm::StructType *ExceptionDataTy;
552 llvm::FunctionCallee getExceptionTryEnterFn() {
553 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
555 llvm::FunctionType::get(CGM.
VoidTy, params,
false),
556 "objc_exception_try_enter");
560 llvm::FunctionCallee getExceptionTryExitFn() {
561 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
563 llvm::FunctionType::get(CGM.
VoidTy, params,
false),
564 "objc_exception_try_exit");
568 llvm::FunctionCallee getExceptionExtractFn() {
569 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
572 "objc_exception_extract");
576 llvm::FunctionCallee getExceptionMatchFn() {
577 llvm::Type *params[] = { ClassPtrTy, ObjectPtrTy };
579 llvm::FunctionType::get(CGM.
Int32Ty, params,
false),
580 "objc_exception_match");
584 llvm::FunctionCallee getSetJmpFn() {
588 llvm::FunctionType::get(CGM.
Int32Ty, params,
false),
"_setjmp",
590 llvm::AttributeList::FunctionIndex,
591 llvm::Attribute::NonLazyBind));
600 class ObjCNonFragileABITypesHelper :
public ObjCCommonTypesHelper {
603 llvm::StructType *MethodListnfABITy;
606 llvm::PointerType *MethodListnfABIPtrTy;
609 llvm::StructType *ProtocolnfABITy;
612 llvm::PointerType *ProtocolnfABIPtrTy;
615 llvm::StructType *ProtocolListnfABITy;
618 llvm::PointerType *ProtocolListnfABIPtrTy;
621 llvm::StructType *ClassnfABITy;
624 llvm::PointerType *ClassnfABIPtrTy;
627 llvm::StructType *IvarnfABITy;
630 llvm::StructType *IvarListnfABITy;
633 llvm::PointerType *IvarListnfABIPtrTy;
636 llvm::StructType *ClassRonfABITy;
639 llvm::PointerType *ImpnfABITy;
642 llvm::StructType *CategorynfABITy;
651 llvm::StructType *MessageRefTy;
665 llvm::StructType *SuperMessageRefTy;
668 llvm::PointerType *SuperMessageRefPtrTy;
670 llvm::FunctionCallee getMessageSendFixupFn() {
672 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
675 "objc_msgSend_fixup");
678 llvm::FunctionCallee getMessageSendFpretFixupFn() {
680 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
683 "objc_msgSend_fpret_fixup");
686 llvm::FunctionCallee getMessageSendStretFixupFn() {
688 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
691 "objc_msgSend_stret_fixup");
694 llvm::FunctionCallee getMessageSendSuper2FixupFn() {
697 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
700 "objc_msgSendSuper2_fixup");
703 llvm::FunctionCallee getMessageSendSuper2StretFixupFn() {
706 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
709 "objc_msgSendSuper2_stret_fixup");
712 llvm::FunctionCallee getObjCEndCatchFn() {
717 llvm::FunctionCallee getObjCBeginCatchFn() {
729 llvm::FunctionCallee getLoadClassrefFn()
const {
737 llvm::FunctionType::get(ClassnfABIPtrTy, params,
false),
740 llvm::AttributeList::FunctionIndex,
741 {llvm::Attribute::NonLazyBind,
742 llvm::Attribute::ReadNone,
743 llvm::Attribute::NoUnwind}));
744 if (!CGM.
getTriple().isOSBinFormatCOFF())
745 cast<llvm::Function>(F.getCallee())->setLinkage(
746 llvm::Function::ExternalWeakLinkage);
751 llvm::StructType *EHTypeTy;
770 SKIP_SCAN(
unsigned _skip = 0,
unsigned _scan = 0)
771 : skip(_skip), scan(_scan) {}
778 enum BLOCK_LAYOUT_OPCODE {
785 BLOCK_LAYOUT_OPERATOR = 0,
791 BLOCK_LAYOUT_NON_OBJECT_BYTES = 1,
796 BLOCK_LAYOUT_NON_OBJECT_WORDS = 2,
800 BLOCK_LAYOUT_STRONG = 3,
803 BLOCK_LAYOUT_BYREF = 4,
807 BLOCK_LAYOUT_WEAK = 5,
811 BLOCK_LAYOUT_UNRETAINED = 6
828 enum BLOCK_LAYOUT_OPCODE opcode;
831 RUN_SKIP(
enum BLOCK_LAYOUT_OPCODE Opcode = BLOCK_LAYOUT_OPERATOR,
834 : opcode(Opcode), block_var_bytepos(BytePos), block_var_size(Size) {}
838 return block_var_bytepos < b.block_var_bytepos;
843 llvm::LLVMContext &VMContext;
852 llvm::SetVector<IdentifierInfo*> LazySymbols;
858 llvm::SetVector<IdentifierInfo*> DefinedSymbols;
861 llvm::StringMap<llvm::GlobalVariable*> ClassNames;
864 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
871 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
875 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
878 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
881 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
884 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
889 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
915 llvm::WeakTrackingVH ConstantStringClassRef;
918 llvm::StructType *NSConstantStringType =
nullptr;
920 llvm::StringMap<llvm::GlobalVariable *> NSConstantStringMap;
930 llvm::Constant *GetMethodVarName(
Selector Sel);
938 bool Extended =
false);
939 llvm::Constant *GetMethodVarType(
const FieldDecl *D);
947 const Decl *Container);
952 llvm::Constant *GetClassName(StringRef RuntimeName);
966 bool forStrongLayout,
972 return BuildIvarLayout(OI, beginOffset, endOffset,
true,
false);
978 bool hasMRCWeakIvars) {
979 return BuildIvarLayout(OI, beginOffset, endOffset,
false, hasMRCWeakIvars);
984 void UpdateRunSkipBlockVars(
bool IsByref,
989 void BuildRCBlockVarRecordLayout(
const RecordType *RT,
991 bool ByrefLayout=
false);
993 void BuildRCRecordLayout(
const llvm::StructLayout *RecLayout,
1001 llvm::Constant *getBitmapBlockLayout(
bool ComputeByrefLayout);
1006 const ObjCCommonTypesHelper &ObjCTypes);
1010 llvm::Constant *EmitPropertyList(Twine Name,
1011 const Decl *Container,
1013 const ObjCCommonTypesHelper &ObjCTypes,
1014 bool IsClassProperty);
1018 llvm::Constant *EmitProtocolMethodTypes(Twine Name,
1020 const ObjCCommonTypesHelper &ObjCTypes);
1031 ObjCCommonTypesHelper &ObjCTypes);
1033 std::string GetSectionName(StringRef Section, StringRef MachOAttributes);
1050 llvm::GlobalVariable *CreateMetadataVar(Twine Name,
1054 llvm::GlobalVariable *CreateMetadataVar(Twine Name,
1055 llvm::Constant *Init,
1059 llvm::GlobalVariable *CreateCStringLiteral(StringRef Name,
1061 bool ForceNonFragileABI =
false,
1062 bool NullTerminate =
true);
1075 const ObjCCommonTypesHelper &ObjCTypes);
1079 void EmitImageInfo();
1085 bool isNonFragileABI()
const {
1086 return ObjCABI == 2;
1106 virtual llvm::Constant *GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD)=0;
1108 virtual llvm::Constant *getNSConstantStringClassRef() = 0;
1127 CategoryInstanceMethods,
1128 CategoryClassMethods,
1131 ProtocolInstanceMethods,
1132 ProtocolClassMethods,
1133 OptionalProtocolInstanceMethods,
1134 OptionalProtocolClassMethods,
1139 class ProtocolMethodLists {
1142 RequiredInstanceMethods,
1143 RequiredClassMethods,
1144 OptionalInstanceMethods,
1145 OptionalClassMethods
1148 NumProtocolMethodLists = 4
1153 case RequiredInstanceMethods:
1154 return MethodListType::ProtocolInstanceMethods;
1155 case RequiredClassMethods:
1156 return MethodListType::ProtocolClassMethods;
1157 case OptionalInstanceMethods:
1158 return MethodListType::OptionalProtocolInstanceMethods;
1159 case OptionalClassMethods:
1160 return MethodListType::OptionalProtocolClassMethods;
1162 llvm_unreachable(
"bad kind");
1168 ProtocolMethodLists
result;
1170 for (
auto MD : PD->methods()) {
1171 size_t index = (2 *
size_t(MD->isOptional()))
1172 + (
size_t(MD->isClassMethod()));
1173 result.Methods[index].push_back(MD);
1179 template <
class Self>
1190 for (
auto &list : Methods) {
1191 for (
auto MD : list) {
1192 result.push_back(self->GetMethodVarType(MD,
true));
1199 template <
class Self>
1203 getMethodListKind(kind), Methods[
kind]);
1209 class CGObjCMac :
public CGObjCCommonMac {
1211 friend ProtocolMethodLists;
1213 ObjCTypesHelper ObjCTypes;
1217 void EmitModuleInfo();
1221 llvm::Constant *EmitModuleSymbols();
1225 void FinishModule();
1264 llvm::Constant *Protocols,
1295 const ProtocolMethodLists &methodLists);
1299 llvm::Constant *EmitProtocolList(Twine Name,
1311 llvm::Constant *getNSConstantStringClassRef()
override;
1313 llvm::Function *ModuleInitFunction()
override;
1342 llvm::Constant *GetEHType(
QualType T)
override;
1353 llvm::FunctionCallee GetPropertyGetFunction()
override;
1354 llvm::FunctionCallee GetPropertySetFunction()
override;
1355 llvm::FunctionCallee GetOptimizedPropertySetFunction(
bool atomic,
1356 bool copy)
override;
1357 llvm::FunctionCallee GetGetStructFunction()
override;
1358 llvm::FunctionCallee GetSetStructFunction()
override;
1359 llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override;
1360 llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override;
1361 llvm::FunctionCallee EnumerationMutationFunction()
override;
1369 bool ClearInsertionPoint=
true)
override;
1371 Address AddrWeakObj)
override;
1376 bool threadlocal =
false)
override;
1388 unsigned CVRQualifiers)
override;
1394 class CGObjCNonFragileABIMac :
public CGObjCCommonMac {
1396 friend ProtocolMethodLists;
1397 ObjCNonFragileABITypesHelper ObjCTypes;
1398 llvm::GlobalVariable* ObjCEmptyCacheVar;
1399 llvm::Constant* ObjCEmptyVtableVar;
1402 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences;
1405 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences;
1408 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences;
1415 std::vector<llvm::GlobalValue*> DefinedMetaClasses;
1419 bool isVTableDispatchedSelector(
Selector Sel);
1423 void FinishNonFragileABIModule();
1428 StringRef SymbolName, StringRef SectionName);
1430 llvm::GlobalVariable * BuildClassRoTInitializer(
unsigned flags,
1431 unsigned InstanceStart,
1432 unsigned InstanceSize,
1436 llvm::Constant *IsAGV,
1437 llvm::Constant *SuperClassGV,
1438 llvm::Constant *ClassRoGV,
1459 unsigned long int offset);
1474 llvm::Constant *EmitProtocolList(Twine Name,
1490 llvm::Constant *GetClassGlobal(StringRef Name,
1492 bool Weak =
false,
bool DLLImport =
false);
1501 llvm::GlobalVariable *Entry);
1527 llvm::GlobalVariable * ObjCIvarOffsetVariable(
1541 StringRef getMetaclassSymbolPrefix()
const {
return "OBJC_METACLASS_$_"; }
1543 StringRef getClassSymbolPrefix()
const {
return "OBJC_CLASS_$_"; }
1546 uint32_t &InstanceStart,
1547 uint32_t &InstanceSize);
1562 bool ImplementationIsNonLazy(
const ObjCImplDecl *OD)
const;
1577 dyn_cast_or_null<ObjCMethodDecl>(CGF.
CurFuncDecl))
1596 llvm::Constant *getNSConstantStringClassRef()
override;
1598 llvm::Function *ModuleInitFunction()
override;
1620 {
return EmitSelector(CGF, Sel); }
1622 {
return EmitSelectorAddr(CGF, Sel); }
1628 {
return EmitSelector(CGF, Method->
getSelector()); }
1639 llvm::Constant *GetEHType(
QualType T)
override;
1641 llvm::FunctionCallee GetPropertyGetFunction()
override {
1642 return ObjCTypes.getGetPropertyFn();
1644 llvm::FunctionCallee GetPropertySetFunction()
override {
1645 return ObjCTypes.getSetPropertyFn();
1648 llvm::FunctionCallee GetOptimizedPropertySetFunction(
bool atomic,
1649 bool copy)
override {
1650 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
1653 llvm::FunctionCallee GetSetStructFunction()
override {
1654 return ObjCTypes.getCopyStructFn();
1657 llvm::FunctionCallee GetGetStructFunction()
override {
1658 return ObjCTypes.getCopyStructFn();
1661 llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override {
1662 return ObjCTypes.getCppAtomicObjectFunction();
1665 llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override {
1666 return ObjCTypes.getCppAtomicObjectFunction();
1669 llvm::FunctionCallee EnumerationMutationFunction()
override {
1670 return ObjCTypes.getEnumerationMutationFn();
1678 bool ClearInsertionPoint=
true)
override;
1680 Address AddrWeakObj)
override;
1685 bool threadlocal =
false)
override;
1696 unsigned CVRQualifiers)
override;
1704 struct NullReturnState {
1705 llvm::BasicBlock *NullBB;
1706 NullReturnState() : NullBB(
nullptr) {}
1719 CGF.
Builder.CreateCondBr(isNull, NullBB, callBB);
1734 if (!NullBB)
return result;
1738 llvm::BasicBlock *contBB =
nullptr;
1741 llvm::BasicBlock *callBB = CGF.
Builder.GetInsertBlock();
1752 CallArgList::const_iterator I = CallArgs.begin();
1756 if (ParamDecl->
hasAttr<NSConsumedAttr>()) {
1757 RValue RV = I->getRValue(CGF);
1759 "NullReturnState::complete - arg not on object");
1766 assert(CGF.
Builder.GetInsertBlock() == NullBB);
1785 llvm::PHINode *phi = CGF.
Builder.CreatePHI(null->getType(), 2);
1787 phi->addIncoming(null, NullBB);
1796 assert(result.
isAggregate() &&
"null init of non-aggregate result?");
1808 llvm::Type *scalarTy = callResult.first->getType();
1809 llvm::Constant *scalarZero = llvm::Constant::getNullValue(scalarTy);
1812 llvm::PHINode *real = CGF.
Builder.CreatePHI(scalarTy, 2);
1813 real->addIncoming(callResult.first, callBB);
1814 real->addIncoming(scalarZero, NullBB);
1815 llvm::PHINode *imag = CGF.
Builder.CreatePHI(scalarTy, 2);
1816 imag->addIncoming(callResult.second, callBB);
1817 imag->addIncoming(scalarZero, NullBB);
1828 llvm::GlobalVariable *C,
unsigned idx0,
1831 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),
1832 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)
1834 return llvm::ConstantExpr::getGetElementPtr(C->getValueType(), C, Idxs);
1841 if (OID->
hasAttr<ObjCExceptionAttr>())
1848 static llvm::GlobalValue::LinkageTypes
1850 if (CGM.
getTriple().isOSBinFormatMachO() &&
1851 (Section.empty() || Section.startswith(
"__DATA")))
1853 return llvm::GlobalValue::PrivateLinkage;
1857 static llvm::GlobalVariable *
1860 std::string SectionName;
1861 if (CGM.
getTriple().isOSBinFormatMachO())
1862 SectionName =
"__DATA, __objc_const";
1863 auto *GV = Builder.finishAndCreateGlobal(
1866 GV->setSection(SectionName);
1882 return EmitClassRef(CGF, ID);
1887 return EmitSelector(CGF, Sel);
1890 return EmitSelectorAddr(CGF, Sel);
1897 llvm::Constant *CGObjCMac::GetEHType(
QualType T) {
1911 llvm_unreachable(
"asking for catch type for ObjC type in fragile runtime");
1934 CGObjCCommonMac::GenerateConstantString(
const StringLiteral *SL) {
1937 : GenerateConstantNSString(SL));
1940 static llvm::StringMapEntry<llvm::GlobalVariable *> &
1943 StringRef String = Literal->
getString();
1944 StringLength = String.size();
1945 return *Map.insert(std::make_pair(String,
nullptr)).first;
1948 llvm::Constant *CGObjCMac::getNSConstantStringClassRef() {
1950 return cast<llvm::Constant>(
V);
1954 StringClass.empty() ?
"_NSConstantStringClassReference" 1955 :
"_" + StringClass +
"ClassReference";
1959 auto V = llvm::ConstantExpr::getBitCast(GV, CGM.
IntTy->getPointerTo());
1960 ConstantStringClassRef =
V;
1964 llvm::Constant *CGObjCNonFragileABIMac::getNSConstantStringClassRef() {
1966 return cast<llvm::Constant>(
V);
1970 StringClass.empty() ?
"OBJC_CLASS_$_NSConstantString" 1971 :
"OBJC_CLASS_$_" + StringClass;
1975 auto V = llvm::ConstantExpr::getBitCast(GV, CGM.
IntTy->getPointerTo());
1977 ConstantStringClassRef =
V;
1982 CGObjCCommonMac::GenerateConstantNSString(
const StringLiteral *Literal) {
1983 unsigned StringLength = 0;
1984 llvm::StringMapEntry<llvm::GlobalVariable *> &Entry =
1987 if (
auto *C = Entry.second)
1991 llvm::Constant *Class = getNSConstantStringClassRef();
1994 if (!NSConstantStringType) {
1995 NSConstantStringType =
2000 },
"struct.__builtin_NSString");
2004 auto Fields = Builder.beginStruct(NSConstantStringType);
2011 llvm::ConstantDataArray::getString(VMContext, Entry.first());
2013 llvm::GlobalValue::LinkageTypes
Linkage = llvm::GlobalValue::PrivateLinkage;
2014 bool isConstant = !CGM.
getLangOpts().WritableStrings;
2016 auto *GV =
new llvm::GlobalVariable(CGM.
getModule(), C->getType(), isConstant,
2018 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2021 GV->setAlignment(1);
2025 Fields.addInt(CGM.
IntTy, StringLength);
2029 GV = Fields.finishAndCreateGlobal(
"_unnamed_nsstring_", Alignment,
2031 llvm::GlobalVariable::PrivateLinkage);
2032 const char *NSStringSection =
"__OBJC,__cstring_object,regular,no_dead_strip";
2033 const char *NSStringNonFragileABISection =
2034 "__DATA,__objc_stringobj,regular,no_dead_strip";
2037 ? NSStringNonFragileABISection
2057 bool isCategoryImpl,
2059 bool IsClassMessage,
2074 if (IsClassMessage) {
2075 if (isCategoryImpl) {
2086 llvm::Constant *MetaClassPtr = EmitMetaClassRef(Class);
2093 }
else if (isCategoryImpl)
2106 return EmitMessageSend(CGF, Return, ResultType,
2107 EmitSelector(CGF, Sel),
2108 ObjCSuper.
getPointer(), ObjCTypes.SuperPtrCTy,
2109 true, CallArgs, Method, Class, ObjCTypes);
2121 return EmitMessageSend(CGF, Return, ResultType,
2122 EmitSelector(CGF, Sel),
2124 false, CallArgs, Method, Class, ObjCTypes);
2147 const ObjCCommonTypesHelper &ObjCTypes) {
2156 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2161 "Result type mismatch!");
2163 bool ReceiverCanBeNull =
true;
2168 ReceiverCanBeNull =
false;
2172 }
else if (ClassReceiver && Method && Method->
isClassMethod()) {
2177 }
else if (
auto CurMethod =
2178 dyn_cast_or_null<ObjCMethodDecl>(CGF.
CurCodeDecl)) {
2179 auto Self = CurMethod->getSelfDecl();
2180 if (Self->getType().isConstQualified()) {
2181 if (
auto LI = dyn_cast<llvm::LoadInst>(Arg0->stripPointerCasts())) {
2183 if (SelfAddr == LI->getPointerOperand()) {
2184 ReceiverCanBeNull =
false;
2190 bool RequiresNullCheck =
false;
2192 llvm::FunctionCallee Fn =
nullptr;
2194 if (ReceiverCanBeNull) RequiresNullCheck =
true;
2195 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
2196 : ObjCTypes.getSendStretFn(IsSuper);
2198 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
2199 : ObjCTypes.getSendFpretFn(IsSuper);
2201 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)
2202 : ObjCTypes.getSendFp2retFn(IsSuper);
2207 RequiresNullCheck =
true;
2208 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
2209 : ObjCTypes.getSendFn(IsSuper);
2213 llvm::Constant *BitcastFn = cast<llvm::Constant>(
2219 RequiresNullCheck =
false;
2222 if (!RequiresNullCheck && CGM.
getLangOpts().ObjCAutoRefCount && Method) {
2223 for (
const auto *ParamDecl : Method->
parameters()) {
2224 if (ParamDecl->hasAttr<NSConsumedAttr>()) {
2225 RequiresNullCheck =
true;
2231 NullReturnState nullReturn;
2232 if (RequiresNullCheck) {
2233 nullReturn.init(CGF, Arg0);
2236 llvm::CallBase *CallSite;
2238 RValue rvalue = CGF.
EmitCall(MSI.CallInfo, Callee, Return, ActualArgs,
2243 if (Method && Method->
hasAttr<NoReturnAttr>() && !ReceiverCanBeNull) {
2244 CallSite->setDoesNotReturn();
2247 return nullReturn.complete(CGF, Return, rvalue, ResultType, CallArgs,
2248 RequiresNullCheck ? Method :
nullptr);
2252 bool pointee =
false) {
2265 switch (ownership) {
2272 llvm_unreachable(
"bad objc ownership");
2291 uint64_t SizeInWords;
2292 IvarInfo(
CharUnits offset, uint64_t sizeInWords)
2293 :
Offset(offset), SizeInWords(sizeInWords) {}
2296 bool operator<(
const IvarInfo &other)
const {
2297 return Offset < other.Offset;
2302 class IvarLayoutBuilder {
2313 bool ForStrongLayout;
2316 bool IsDisordered =
false;
2322 CharUnits instanceEnd,
bool forStrongLayout)
2323 : CGM(CGM), InstanceBegin(instanceBegin), InstanceEnd(instanceEnd),
2324 ForStrongLayout(forStrongLayout) {
2329 template <
class Iterator,
class GetOffsetFn>
2330 void visitAggregate(Iterator begin, Iterator end,
2332 const GetOffsetFn &getOffset);
2340 bool hasBitmapData()
const {
return !IvarsInfo.empty(); }
2342 llvm::Constant *buildBitmap(CGObjCCommonMac &CGObjC,
2346 const unsigned char *s = buffer.data();
2347 for (
unsigned i = 0, e = buffer.size();
i < e;
i++)
2349 printf(
"0x0%x%s", s[
i], s[i] != 0 ?
", " :
"");
2351 printf(
"0x%x%s", s[i], s[i] != 0 ?
", " :
"");
2357 llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(
CodeGenModule &CGM,
2360 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2367 builder.visitBlock(blockInfo);
2369 if (!builder.hasBitmapData())
2373 llvm::Constant *C = builder.buildBitmap(*
this, buffer);
2374 if (CGM.
getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
2375 printf(
"\n block variable layout for block: ");
2376 builder.dump(buffer);
2382 void IvarLayoutBuilder::visitBlock(
const CGBlockInfo &blockInfo) {
2395 for (
const auto &CI : blockDecl->
captures()) {
2396 const VarDecl *variable = CI.getVariable();
2408 if (fieldOffset < lastFieldOffset)
2409 IsDisordered =
true;
2410 lastFieldOffset = fieldOffset;
2414 IvarsInfo.push_back(IvarInfo(fieldOffset, 1));
2418 assert(!type->
isArrayType() &&
"array variable should not be caught");
2420 visitRecord(record, fieldOffset);
2429 IvarsInfo.push_back(IvarInfo(fieldOffset, 1));
2454 void CGObjCCommonMac::UpdateRunSkipBlockVars(
bool IsByref,
2460 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset,
2463 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset,
2466 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset,
2469 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset,
2472 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES,
2477 void CGObjCCommonMac::BuildRCRecordLayout(
const llvm::StructLayout *RecLayout,
2482 bool IsUnion = (RD && RD->
isUnion());
2485 const FieldDecl *LastFieldBitfieldOrUnnamed =
nullptr;
2489 if (RecFields.empty())
2493 for (
unsigned i = 0, e = RecFields.size();
i != e; ++
i) {
2503 LastFieldBitfieldOrUnnamed = Field;
2504 LastBitfieldOrUnnamedOffset = FieldOffset;
2508 LastFieldBitfieldOrUnnamed =
nullptr;
2515 BytePos + FieldOffset, HasUnion);
2521 dyn_cast_or_null<ConstantArrayType>(Array);
2522 uint64_t ElCount = CArray->
getSize().getZExtValue();
2523 assert(CArray &&
"only array with known element size is supported");
2527 dyn_cast_or_null<ConstantArrayType>(Array);
2528 ElCount *= CArray->
getSize().getZExtValue();
2532 int OldIndex = RunSkipBlockVars.size() - 1;
2534 BuildRCBlockVarRecordLayout(RT, BytePos + FieldOffset,
2540 for (
int FirstIndex = RunSkipBlockVars.size() - 1 ;ElIx < ElCount; ElIx++) {
2542 for (
int i = OldIndex+1;
i <= FirstIndex; ++
i)
2543 RunSkipBlockVars.push_back(
2544 RUN_SKIP(RunSkipBlockVars[
i].opcode,
2545 RunSkipBlockVars[
i].block_var_bytepos + Size*ElIx,
2546 RunSkipBlockVars[
i].block_var_size));
2554 if (UnionIvarSize > MaxUnionSize) {
2555 MaxUnionSize = UnionIvarSize;
2557 MaxFieldOffset = FieldOffset;
2560 UpdateRunSkipBlockVars(
false,
2561 getBlockCaptureLifetime(FQT, ByrefLayout),
2562 BytePos + FieldOffset,
2567 if (LastFieldBitfieldOrUnnamed) {
2568 if (LastFieldBitfieldOrUnnamed->
isBitField()) {
2570 uint64_t BitFieldSize
2572 unsigned UnsSize = (BitFieldSize / ByteSizeInBits) +
2573 ((BitFieldSize % ByteSizeInBits) != 0);
2575 Size += LastBitfieldOrUnnamedOffset;
2576 UpdateRunSkipBlockVars(
false,
2577 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
2579 BytePos + LastBitfieldOrUnnamedOffset,
2582 assert(!LastFieldBitfieldOrUnnamed->
getIdentifier() &&
"Expected unnamed");
2586 UpdateRunSkipBlockVars(
false,
2587 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
2589 BytePos + LastBitfieldOrUnnamedOffset,
2595 UpdateRunSkipBlockVars(
false,
2596 getBlockCaptureLifetime(MaxField->
getType(), ByrefLayout),
2597 BytePos + MaxFieldOffset,
2601 void CGObjCCommonMac::BuildRCBlockVarRecordLayout(
const RecordType *RT,
2608 const llvm::StructLayout *RecLayout =
2609 CGM.
getDataLayout().getStructLayout(cast<llvm::StructType>(Ty));
2611 BuildRCRecordLayout(RecLayout, RD, Fields, BytePos, HasUnion, ByrefLayout);
2623 uint64_t CGObjCCommonMac::InlineLayoutInstruction(
2625 uint64_t Result = 0;
2626 if (Layout.size() <= 3) {
2627 unsigned size = Layout.size();
2628 unsigned strong_word_count = 0, byref_word_count=0, weak_word_count=0;
2630 enum BLOCK_LAYOUT_OPCODE opcode ;
2634 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2635 if (opcode == BLOCK_LAYOUT_STRONG)
2636 strong_word_count = (inst & 0xF)+1;
2640 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2641 if (opcode == BLOCK_LAYOUT_BYREF)
2642 byref_word_count = (inst & 0xF)+1;
2646 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2647 if (opcode == BLOCK_LAYOUT_WEAK)
2648 weak_word_count = (inst & 0xF)+1;
2655 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2656 if (opcode == BLOCK_LAYOUT_STRONG) {
2657 strong_word_count = (inst & 0xF)+1;
2659 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2660 if (opcode == BLOCK_LAYOUT_BYREF)
2661 byref_word_count = (inst & 0xF)+1;
2662 else if (opcode == BLOCK_LAYOUT_WEAK)
2663 weak_word_count = (inst & 0xF)+1;
2667 else if (opcode == BLOCK_LAYOUT_BYREF) {
2668 byref_word_count = (inst & 0xF)+1;
2670 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2671 if (opcode == BLOCK_LAYOUT_WEAK)
2672 weak_word_count = (inst & 0xF)+1;
2682 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2683 if (opcode == BLOCK_LAYOUT_STRONG)
2684 strong_word_count = (inst & 0xF)+1;
2685 else if (opcode == BLOCK_LAYOUT_BYREF)
2686 byref_word_count = (inst & 0xF)+1;
2687 else if (opcode == BLOCK_LAYOUT_WEAK)
2688 weak_word_count = (inst & 0xF)+1;
2700 if (strong_word_count == 16 || byref_word_count == 16 || weak_word_count == 16)
2704 (strong_word_count != 0) + (byref_word_count != 0) + (weak_word_count != 0);
2706 if (size == count) {
2707 if (strong_word_count)
2708 Result = strong_word_count;
2710 if (byref_word_count)
2711 Result += byref_word_count;
2713 if (weak_word_count)
2714 Result += weak_word_count;
2720 llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(
bool ComputeByrefLayout) {
2721 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2722 if (RunSkipBlockVars.empty())
2726 unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2730 llvm::array_pod_sort(RunSkipBlockVars.begin(), RunSkipBlockVars.end());
2733 unsigned size = RunSkipBlockVars.size();
2734 for (
unsigned i = 0;
i < size;
i++) {
2735 enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[
i].opcode;
2736 CharUnits start_byte_pos = RunSkipBlockVars[
i].block_var_bytepos;
2737 CharUnits end_byte_pos = start_byte_pos;
2740 if (opcode == RunSkipBlockVars[j].opcode) {
2741 end_byte_pos = RunSkipBlockVars[j++].block_var_bytepos;
2748 end_byte_pos - start_byte_pos + RunSkipBlockVars[j-1].block_var_size;
2751 RunSkipBlockVars[j].block_var_bytepos -
2752 RunSkipBlockVars[j-1].block_var_bytepos - RunSkipBlockVars[j-1].block_var_size;
2753 size_in_bytes += gap;
2756 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) {
2757 residue_in_bytes = size_in_bytes % WordSizeInBytes;
2758 size_in_bytes -= residue_in_bytes;
2759 opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS;
2762 unsigned size_in_words = size_in_bytes.
getQuantity() / WordSizeInBytes;
2763 while (size_in_words >= 16) {
2766 unsigned char inst = (opcode << 4) | 0xf;
2767 Layout.push_back(inst);
2768 size_in_words -= 16;
2770 if (size_in_words > 0) {
2773 unsigned char inst = (opcode << 4) | (size_in_words-1);
2774 Layout.push_back(inst);
2777 unsigned char inst =
2778 (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) | (residue_in_bytes.
getQuantity()-1);
2779 Layout.push_back(inst);
2783 while (!Layout.empty()) {
2784 unsigned char inst = Layout.back();
2785 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2786 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES || opcode == BLOCK_LAYOUT_NON_OBJECT_WORDS)
2792 uint64_t Result = InlineLayoutInstruction(Layout);
2796 if (ComputeByrefLayout)
2797 printf(
"\n Inline BYREF variable layout: ");
2799 printf(
"\n Inline block variable layout: ");
2800 printf(
"0x0%" PRIx64
"", Result);
2801 if (
auto numStrong = (Result & 0xF00) >> 8)
2802 printf(
", BL_STRONG:%d", (
int) numStrong);
2803 if (
auto numByref = (Result & 0x0F0) >> 4)
2804 printf(
", BL_BYREF:%d", (
int) numByref);
2805 if (
auto numWeak = (Result & 0x00F) >> 0)
2806 printf(
", BL_WEAK:%d", (
int) numWeak);
2807 printf(
", BL_OPERATOR:0\n");
2809 return llvm::ConstantInt::get(CGM.
IntPtrTy, Result);
2812 unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0;
2813 Layout.push_back(inst);
2815 for (
unsigned i = 0, e = Layout.size();
i != e;
i++)
2816 BitMap += Layout[
i];
2819 if (ComputeByrefLayout)
2820 printf(
"\n Byref variable layout: ");
2822 printf(
"\n Block variable layout: ");
2823 for (
unsigned i = 0, e = BitMap.size();
i != e;
i++) {
2824 unsigned char inst = BitMap[
i];
2825 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2828 case BLOCK_LAYOUT_OPERATOR:
2832 case BLOCK_LAYOUT_NON_OBJECT_BYTES:
2833 printf(
"BL_NON_OBJECT_BYTES:");
2835 case BLOCK_LAYOUT_NON_OBJECT_WORDS:
2836 printf(
"BL_NON_OBJECT_WORD:");
2838 case BLOCK_LAYOUT_STRONG:
2841 case BLOCK_LAYOUT_BYREF:
2844 case BLOCK_LAYOUT_WEAK:
2847 case BLOCK_LAYOUT_UNRETAINED:
2848 printf(
"BL_UNRETAINED:");
2853 printf(
"%d", (inst & 0xf) + delta);
2861 auto *Entry = CreateCStringLiteral(BitMap, ObjCLabelType::ClassName,
2869 bool HasCopyDisposeHelpers) {
2871 for (
const CGObjCCommonMac::RUN_SKIP &R : RunSkipBlockVars) {
2872 if (R.opcode == CGObjCCommonMac::BLOCK_LAYOUT_UNRETAINED) {
2876 }
else if (HasCopyDisposeHelpers) {
2884 case CGObjCCommonMac::BLOCK_LAYOUT_STRONG:
2887 case CGObjCCommonMac::BLOCK_LAYOUT_BYREF:
2890 case CGObjCCommonMac::BLOCK_LAYOUT_WEAK:
2897 Str += llvm::to_string(R.block_var_bytepos.getQuantity());
2898 Str +=
"l" + llvm::to_string(R.block_var_size.getQuantity());
2903 void CGObjCCommonMac::fillRunSkipBlockVars(
CodeGenModule &CGM,
2907 RunSkipBlockVars.clear();
2908 bool hasUnion =
false;
2912 unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2917 const llvm::StructLayout *layout =
2927 for (
const auto &CI : blockDecl->
captures()) {
2928 const VarDecl *variable = CI.getVariable();
2939 assert(!type->
isArrayType() &&
"array variable should not be caught");
2942 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion);
2950 UpdateRunSkipBlockVars(CI.isByRef(), getBlockCaptureLifetime(type,
false),
2951 fieldOffset, fieldSize);
2958 fillRunSkipBlockVars(CGM, blockInfo);
2959 return getBitmapBlockLayout(
false);
2962 std::string CGObjCCommonMac::getRCBlockLayoutStr(
CodeGenModule &CGM,
2964 fillRunSkipBlockVars(CGM, blockInfo);
2972 assert(!T->
isArrayType() &&
"__block array variable should not be caught");
2974 RunSkipBlockVars.clear();
2975 bool hasUnion =
false;
2977 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion,
true );
2978 llvm::Constant *Result = getBitmapBlockLayout(
true);
2979 if (isa<llvm::ConstantInt>(Result))
2980 Result = llvm::ConstantExpr::getIntToPtr(Result, CGM.
Int8PtrTy);
2983 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2993 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
2994 ObjCTypes.getExternalProtocolPtrTy());
3006 GetOrEmitProtocol(PD);
3009 llvm::Constant *CGObjCCommonMac::GetProtocolRef(
const ObjCProtocolDecl *PD) {
3011 return GetOrEmitProtocol(PD);
3013 return GetOrEmitProtocolRef(PD);
3016 llvm::Value *CGObjCCommonMac::EmitClassRefViaRuntime(
3019 ObjCCommonTypesHelper &ObjCTypes) {
3020 llvm::FunctionCallee lookUpClassFn = ObjCTypes.getLookUpClassFn();
3030 llvm::CallInst *call = CGF.
Builder.CreateCall(lookUpClassFn, className);
3031 call->setDoesNotThrow();
3048 llvm::GlobalVariable *Entry = Protocols[PD->
getIdentifier()];
3051 if (Entry && Entry->hasInitializer())
3063 auto methodLists = ProtocolMethodLists::get(PD);
3066 auto values = builder.
beginStruct(ObjCTypes.ProtocolTy);
3067 values.add(EmitProtocolExtension(PD, methodLists));
3069 values.add(EmitProtocolList(
"OBJC_PROTOCOL_REFS_" + PD->
getName(),
3071 values.add(methodLists.emitMethodList(
this, PD,
3072 ProtocolMethodLists::RequiredInstanceMethods));
3073 values.add(methodLists.emitMethodList(
this, PD,
3074 ProtocolMethodLists::RequiredClassMethods));
3078 assert(Entry->hasPrivateLinkage());
3079 values.finishAndSetAsInitializer(Entry);
3081 Entry = values.finishAndCreateGlobal(
"OBJC_PROTOCOL_" + PD->
getName(),
3084 llvm::GlobalValue::PrivateLinkage);
3085 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
3094 llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD) {
3095 llvm::GlobalVariable *&Entry = Protocols[PD->
getIdentifier()];
3101 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolTy,
3102 false, llvm::GlobalValue::PrivateLinkage,
3103 nullptr,
"OBJC_PROTOCOL_" + PD->
getName());
3104 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
3106 Entry->setAlignment(4);
3124 const ProtocolMethodLists &methodLists) {
3125 auto optInstanceMethods =
3126 methodLists.emitMethodList(
this, PD,
3127 ProtocolMethodLists::OptionalInstanceMethods);
3128 auto optClassMethods =
3129 methodLists.emitMethodList(
this, PD,
3130 ProtocolMethodLists::OptionalClassMethods);
3132 auto extendedMethodTypes =
3133 EmitProtocolMethodTypes(
"OBJC_PROTOCOL_METHOD_TYPES_" + PD->
getName(),
3134 methodLists.emitExtendedTypesArray(
this),
3137 auto instanceProperties =
3138 EmitPropertyList(
"OBJC_$_PROP_PROTO_LIST_" + PD->
getName(),
nullptr, PD,
3140 auto classProperties =
3141 EmitPropertyList(
"OBJC_$_CLASS_PROP_PROTO_LIST_" + PD->
getName(),
nullptr,
3142 PD, ObjCTypes,
true);
3145 if (optInstanceMethods->isNullValue() &&
3146 optClassMethods->isNullValue() &&
3147 extendedMethodTypes->isNullValue() &&
3148 instanceProperties->isNullValue() &&
3149 classProperties->isNullValue()) {
3150 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
3154 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
3157 auto values = builder.
beginStruct(ObjCTypes.ProtocolExtensionTy);
3158 values.addInt(ObjCTypes.IntTy, size);
3159 values.add(optInstanceMethods);
3160 values.add(optClassMethods);
3161 values.add(instanceProperties);
3162 values.add(extendedMethodTypes);
3163 values.add(classProperties);
3166 return CreateMetadataVar(
"_OBJC_PROTOCOLEXT_" + PD->
getName(), values,
3178 CGObjCMac::EmitProtocolList(Twine name,
3183 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
3189 values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
3192 auto countSlot = values.addPlaceholder();
3194 auto refsArray = values.beginArray(ObjCTypes.ProtocolPtrTy);
3195 for (; begin != end; ++begin) {
3196 refsArray.add(GetProtocolRef(*begin));
3198 auto count = refsArray.size();
3201 refsArray.addNullPointer(ObjCTypes.ProtocolPtrTy);
3203 refsArray.finishAndAddTo(values);
3204 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
3207 if (CGM.
getTriple().isOSBinFormatMachO())
3208 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3210 llvm::GlobalVariable *GV =
3211 CreateMetadataVar(name, values, section, CGM.
getPointerAlign(),
false);
3212 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
3219 bool IsClassProperty) {
3224 if (IsClassProperty != PD->isClassProperty())
3228 Properties.push_back(PD);
3244 llvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name,
3245 const Decl *Container,
3247 const ObjCCommonTypesHelper &ObjCTypes,
3248 bool IsClassProperty) {
3249 if (IsClassProperty) {
3253 if ((Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 11)) ||
3254 (Triple.isiOS() && Triple.isOSVersionLT(9)))
3255 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3259 llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
3264 if (IsClassProperty != PD->isClassProperty())
3267 Properties.push_back(PD);
3271 if (IsClassProperty != PD->isClassProperty())
3277 Properties.push_back(PD);
3281 for (
const auto *
P : OID->all_referenced_protocols())
3285 for (
const auto *
P : CD->protocols())
3290 if (Properties.empty())
3291 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3293 unsigned propertySize =
3298 values.addInt(ObjCTypes.IntTy, propertySize);
3299 values.addInt(ObjCTypes.IntTy, Properties.size());
3300 auto propertiesArray = values.beginArray(ObjCTypes.PropertyTy);
3301 for (
auto PD : Properties) {
3302 auto property = propertiesArray.beginStruct(ObjCTypes.PropertyTy);
3304 property.add(GetPropertyTypeString(PD, Container));
3305 property.finishAndAddTo(propertiesArray);
3307 propertiesArray.finishAndAddTo(values);
3310 if (CGM.
getTriple().isOSBinFormatMachO())
3311 Section = (ObjCABI == 2) ?
"__DATA, __objc_const" 3312 :
"__OBJC,__property,regular,no_dead_strip";
3314 llvm::GlobalVariable *GV =
3315 CreateMetadataVar(Name, values, Section, CGM.
getPointerAlign(),
true);
3316 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy);
3320 CGObjCCommonMac::EmitProtocolMethodTypes(Twine Name,
3322 const ObjCCommonTypesHelper &ObjCTypes) {
3324 if (MethodTypes.empty())
3325 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy);
3327 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
3328 MethodTypes.size());
3329 llvm::Constant *Init = llvm::ConstantArray::get(AT, MethodTypes);
3332 if (CGM.
getTriple().isOSBinFormatMachO() && ObjCABI == 2)
3333 Section =
"__DATA, __objc_const";
3335 llvm::GlobalVariable *GV =
3337 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.Int8PtrPtrTy);
3353 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.CategoryTy);
3364 llvm::raw_svector_ostream(ExtName) << Interface->
getName() <<
'_' 3368 auto Values = Builder.
beginStruct(ObjCTypes.CategoryTy);
3376 for (
const auto *MD : OCD->
methods()) {
3377 Methods[unsigned(MD->isClassMethod())].push_back(MD);
3380 Values.add(GetClassName(OCD->
getName()));
3384 Values.add(emitMethodList(ExtName, MethodListType::CategoryInstanceMethods,
3385 Methods[InstanceMethods]));
3386 Values.add(emitMethodList(ExtName, MethodListType::CategoryClassMethods,
3387 Methods[ClassMethods]));
3390 EmitProtocolList(
"OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
3393 Values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
3395 Values.addInt(ObjCTypes.IntTy, Size);
3399 Values.add(EmitPropertyList(
"_OBJC_$_PROP_LIST_" + ExtName.str(),
3401 Values.add(EmitPropertyList(
"_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(),
3404 Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
3405 Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
3408 llvm::GlobalVariable *GV =
3409 CreateMetadataVar(
"OBJC_CATEGORY_" + ExtName.str(), Values,
3410 "__OBJC,__category,regular,no_dead_strip",
3412 DefinedCategories.push_back(GV);
3413 DefinedCategoryNames.insert(llvm::CachedHashString(ExtName));
3415 MethodDefinitions.clear();
3475 for (
auto field : recType->getDecl()->fields()) {
3524 DefinedSymbols.insert(RuntimeName);
3530 llvm::Constant *Protocols =
3531 EmitProtocolList(
"OBJC_CLASS_PROTOCOLS_" + ID->
getName(),
3538 bool hasMRCWeak =
false;
3558 for (
const auto *MD : ID->
methods()) {
3559 Methods[unsigned(MD->isClassMethod())].push_back(MD);
3567 if (GetMethodDefinition(MD))
3568 Methods[InstanceMethods].push_back(MD);
3570 if (GetMethodDefinition(MD))
3571 Methods[InstanceMethods].push_back(MD);
3576 auto values = builder.
beginStruct(ObjCTypes.ClassTy);
3577 values.add(EmitMetaClass(ID, Protocols, Methods[ClassMethods]));
3580 LazySymbols.insert(Super->getIdentifier());
3582 values.addBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
3583 ObjCTypes.ClassPtrTy);
3585 values.addNullPointer(ObjCTypes.ClassPtrTy);
3589 values.addInt(ObjCTypes.LongTy, 0);
3590 values.addInt(ObjCTypes.LongTy, Flags);
3591 values.addInt(ObjCTypes.LongTy, Size.
getQuantity());
3592 values.add(EmitIvarList(ID,
false));
3593 values.add(emitMethodList(ID->
getName(), MethodListType::InstanceMethods,
3594 Methods[InstanceMethods]));
3596 values.addNullPointer(ObjCTypes.CachePtrTy);
3597 values.add(Protocols);
3599 values.add(EmitClassExtension(ID, Size, hasMRCWeak,
3602 std::string Name(
"OBJC_CLASS_");
3604 const char *Section =
"__OBJC,__class,regular,no_dead_strip";
3606 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3608 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3609 "Forward metaclass reference has incorrect type.");
3610 values.finishAndSetAsInitializer(GV);
3611 GV->setSection(Section);
3615 GV = CreateMetadataVar(Name, values, Section, CGM.
getPointerAlign(),
true);
3616 DefinedClasses.push_back(GV);
3617 ImplementedClasses.push_back(Interface);
3619 MethodDefinitions.clear();
3623 llvm::Constant *Protocols,
3626 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ClassTy);
3632 auto values = builder.
beginStruct(ObjCTypes.ClassTy);
3638 ObjCTypes.ClassPtrTy);
3643 values.addBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
3644 ObjCTypes.ClassPtrTy);
3646 values.addNullPointer(ObjCTypes.ClassPtrTy);
3650 values.addInt(ObjCTypes.LongTy, 0);
3651 values.addInt(ObjCTypes.LongTy, Flags);
3652 values.addInt(ObjCTypes.LongTy, Size);
3653 values.add(EmitIvarList(ID,
true));
3654 values.add(emitMethodList(ID->
getName(), MethodListType::ClassMethods,
3657 values.addNullPointer(ObjCTypes.CachePtrTy);
3658 values.add(Protocols);
3660 values.addNullPointer(ObjCTypes.Int8PtrTy);
3665 std::string Name(
"OBJC_METACLASS_");
3669 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3671 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3672 "Forward metaclass reference has incorrect type.");
3673 values.finishAndSetAsInitializer(GV);
3677 llvm::GlobalValue::PrivateLinkage);
3679 GV->setSection(
"__OBJC,__meta_class,regular,no_dead_strip");
3696 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3698 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
3699 llvm::GlobalValue::PrivateLinkage,
nullptr,
3702 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3703 "Forward metaclass reference has incorrect type.");
3709 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3712 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
3713 llvm::GlobalValue::PrivateLinkage,
nullptr,
3716 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3717 "Forward class metadata reference has incorrect type.");
3737 llvm::Constant *layout;
3739 layout = llvm::ConstantPointerNull::get(CGM.
Int8PtrTy);
3746 llvm::Constant *propertyList =
3747 EmitPropertyList((isMetaclass ? Twine(
"_OBJC_$_CLASS_PROP_LIST_")
3748 : Twine(
"_OBJC_$_PROP_LIST_"))
3753 if (layout->isNullValue() && propertyList->isNullValue()) {
3754 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
3758 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
3761 auto values = builder.
beginStruct(ObjCTypes.ClassExtensionTy);
3762 values.addInt(ObjCTypes.IntTy, size);
3764 values.add(propertyList);
3766 return CreateMetadataVar(
"OBJC_CLASSEXT_" + ID->
getName(), values,
3767 "__OBJC,__class_ext,regular,no_dead_strip",
3791 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3797 auto countSlot = ivarList.addPlaceholder();
3798 auto ivars = ivarList.beginArray(ObjCTypes.IvarTy);
3803 if (!IVD->getDeclName())
3806 auto ivar = ivars.beginStruct(ObjCTypes.IvarTy);
3807 ivar.add(GetMethodVarName(IVD->getIdentifier()));
3808 ivar.add(GetMethodVarType(IVD));
3809 ivar.addInt(ObjCTypes.IntTy, ComputeIvarBaseOffset(CGM, OID, IVD));
3810 ivar.finishAndAddTo(ivars);
3814 auto count = ivars.size();
3818 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3821 ivars.finishAndAddTo(ivarList);
3822 ivarList.fillPlaceholderWithInt(countSlot, ObjCTypes.IntTy, count);
3824 llvm::GlobalVariable *GV;
3827 CreateMetadataVar(
"OBJC_CLASS_VARIABLES_" + ID->
getName(), ivarList,
3828 "__OBJC,__class_vars,regular,no_dead_strip",
3831 GV = CreateMetadataVar(
"OBJC_INSTANCE_VARIABLES_" + ID->
getName(), ivarList,
3832 "__OBJC,__instance_vars,regular,no_dead_strip",
3834 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy);
3845 auto description = builder.
beginStruct(ObjCTypes.MethodDescriptionTy);
3846 description.addBitCast(GetMethodVarName(MD->
getSelector()),
3847 ObjCTypes.SelectorPtrTy);
3848 description.add(GetMethodVarType(MD));
3849 description.finishAndAddTo(builder);
3861 llvm::Function *fn = GetMethodDefinition(MD);
3862 assert(fn &&
"no definition registered for method");
3864 auto method = builder.
beginStruct(ObjCTypes.MethodTy);
3865 method.addBitCast(GetMethodVarName(MD->
getSelector()),
3866 ObjCTypes.SelectorPtrTy);
3867 method.add(GetMethodVarType(MD));
3868 method.addBitCast(fn, ObjCTypes.Int8PtrTy);
3869 method.finishAndAddTo(builder);
3885 llvm::Constant *CGObjCMac::emitMethodList(Twine name,
MethodListType MLT,
3889 bool forProtocol =
false;
3891 case MethodListType::CategoryInstanceMethods:
3892 prefix =
"OBJC_CATEGORY_INSTANCE_METHODS_";
3893 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
3894 forProtocol =
false;
3896 case MethodListType::CategoryClassMethods:
3897 prefix =
"OBJC_CATEGORY_CLASS_METHODS_";
3898 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3899 forProtocol =
false;
3901 case MethodListType::InstanceMethods:
3902 prefix =
"OBJC_INSTANCE_METHODS_";
3903 section =
"__OBJC,__inst_meth,regular,no_dead_strip";
3904 forProtocol =
false;
3906 case MethodListType::ClassMethods:
3907 prefix =
"OBJC_CLASS_METHODS_";
3908 section =
"__OBJC,__cls_meth,regular,no_dead_strip";
3909 forProtocol =
false;
3911 case MethodListType::ProtocolInstanceMethods:
3912 prefix =
"OBJC_PROTOCOL_INSTANCE_METHODS_";
3913 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
3916 case MethodListType::ProtocolClassMethods:
3917 prefix =
"OBJC_PROTOCOL_CLASS_METHODS_";
3918 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3921 case MethodListType::OptionalProtocolInstanceMethods:
3922 prefix =
"OBJC_PROTOCOL_INSTANCE_METHODS_OPT_";
3923 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
3926 case MethodListType::OptionalProtocolClassMethods:
3927 prefix =
"OBJC_PROTOCOL_CLASS_METHODS_OPT_";
3928 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3934 if (methods.empty())
3935 return llvm::Constant::getNullValue(forProtocol
3936 ? ObjCTypes.MethodDescriptionListPtrTy
3937 : ObjCTypes.MethodListPtrTy);
3944 values.addInt(ObjCTypes.IntTy, methods.size());
3945 auto methodArray = values.beginArray(ObjCTypes.MethodDescriptionTy);
3946 for (
auto MD : methods) {
3947 emitMethodDescriptionConstant(methodArray, MD);
3949 methodArray.finishAndAddTo(values);
3951 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
3953 return llvm::ConstantExpr::getBitCast(GV,
3954 ObjCTypes.MethodDescriptionListPtrTy);
3960 values.addNullPointer(ObjCTypes.Int8PtrTy);
3961 values.addInt(ObjCTypes.IntTy, methods.size());
3962 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
3963 for (
auto MD : methods) {
3964 emitMethodConstant(methodArray, MD);
3966 methodArray.finishAndAddTo(values);
3968 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
3970 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListPtrTy);
3973 llvm::Function *CGObjCCommonMac::GenerateMethod(
const ObjCMethodDecl *OMD,
3976 GetNameForMethod(OMD, CD, Name);
3979 llvm::FunctionType *MethodTy =
3981 llvm::Function *Method =
3986 MethodDefinitions.insert(std::make_pair(OMD, Method));
3991 llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
3996 llvm::GlobalValue::LinkageTypes
LT =
3998 llvm::GlobalVariable *GV =
4000 if (!Section.empty())
4001 GV->setSection(Section);
4007 llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
4008 llvm::Constant *Init,
4013 llvm::GlobalValue::LinkageTypes
LT =
4015 llvm::GlobalVariable *GV =
4016 new llvm::GlobalVariable(CGM.
getModule(), Ty,
false,
LT, Init, Name);
4017 if (!Section.empty())
4018 GV->setSection(Section);
4025 llvm::GlobalVariable *
4027 bool ForceNonFragileABI,
4028 bool NullTerminate) {
4031 case ObjCLabelType::ClassName: Label =
"OBJC_CLASS_NAME_";
break;
4032 case ObjCLabelType::MethodVarName: Label =
"OBJC_METH_VAR_NAME_";
break;
4033 case ObjCLabelType::MethodVarType: Label =
"OBJC_METH_VAR_TYPE_";
break;
4034 case ObjCLabelType::PropertyName: Label =
"OBJC_PROP_NAME_ATTR_";
break;
4037 bool NonFragile = ForceNonFragileABI || isNonFragileABI();
4041 case ObjCLabelType::ClassName:
4042 Section = NonFragile ?
"__TEXT,__objc_classname,cstring_literals" 4043 :
"__TEXT,__cstring,cstring_literals";
4045 case ObjCLabelType::MethodVarName:
4046 Section = NonFragile ?
"__TEXT,__objc_methname,cstring_literals" 4047 :
"__TEXT,__cstring,cstring_literals";
4049 case ObjCLabelType::MethodVarType:
4050 Section = NonFragile ?
"__TEXT,__objc_methtype,cstring_literals" 4051 :
"__TEXT,__cstring,cstring_literals";
4053 case ObjCLabelType::PropertyName:
4054 Section =
"__TEXT,__cstring,cstring_literals";
4058 llvm::Constant *
Value =
4059 llvm::ConstantDataArray::getString(VMContext, Name, NullTerminate);
4060 llvm::GlobalVariable *GV =
4061 new llvm::GlobalVariable(CGM.
getModule(), Value->getType(),
4063 llvm::GlobalValue::PrivateLinkage,
Value,
Label);
4064 if (CGM.
getTriple().isOSBinFormatMachO())
4065 GV->setSection(Section);
4066 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4073 llvm::Function *CGObjCMac::ModuleInitFunction() {
4079 llvm::FunctionCallee CGObjCMac::GetPropertyGetFunction() {
4080 return ObjCTypes.getGetPropertyFn();
4083 llvm::FunctionCallee CGObjCMac::GetPropertySetFunction() {
4084 return ObjCTypes.getSetPropertyFn();
4087 llvm::FunctionCallee CGObjCMac::GetOptimizedPropertySetFunction(
bool atomic,
4089 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
4092 llvm::FunctionCallee CGObjCMac::GetGetStructFunction() {
4093 return ObjCTypes.getCopyStructFn();
4096 llvm::FunctionCallee CGObjCMac::GetSetStructFunction() {
4097 return ObjCTypes.getCopyStructFn();
4100 llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectGetFunction() {
4101 return ObjCTypes.getCppAtomicObjectFunction();
4104 llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectSetFunction() {
4105 return ObjCTypes.getCppAtomicObjectFunction();
4108 llvm::FunctionCallee CGObjCMac::EnumerationMutationFunction() {
4109 return ObjCTypes.getEnumerationMutationFn();
4113 return EmitTryOrSynchronizedStmt(CGF, S);
4118 return EmitTryOrSynchronizedStmt(CGF, S);
4127 ObjCTypesHelper &ObjCTypes;
4128 PerformFragileFinally(
const Stmt *S,
4132 ObjCTypesHelper *ObjCTypes)
4133 : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
4134 ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
4139 llvm::BasicBlock *FinallyCallExit =
4141 llvm::BasicBlock *FinallyNoCallExit =
4144 FinallyCallExit, FinallyNoCallExit);
4152 if (isa<ObjCAtTryStmt>(S)) {
4154 cast<ObjCAtTryStmt>(S).getFinallyStmt()) {
4156 if (flags.isForEHCleanup())
return;
4163 CGF.
EmitStmt(FinallyStmt->getFinallyBody());
4182 class FragileHazards {
4187 llvm::InlineAsm *ReadHazard;
4188 llvm::InlineAsm *WriteHazard;
4190 llvm::FunctionType *GetAsmFnType();
4192 void collectLocals();
4198 void emitWriteHazard();
4199 void emitHazardsInNewBlocks();
4211 if (Locals.empty())
return;
4214 for (llvm::Function::iterator
4215 I = CGF.
CurFn->begin(), E = CGF.
CurFn->end(); I != E; ++I)
4216 BlocksBeforeTry.insert(&*I);
4218 llvm::FunctionType *AsmFnTy = GetAsmFnType();
4226 std::string Constraint;
4227 for (
unsigned I = 0, E = Locals.size(); I != E; ++I) {
4228 if (I) Constraint +=
',';
4232 ReadHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
4240 std::string Constraint;
4241 for (
unsigned I = 0, E = Locals.size(); I != E; ++I) {
4242 if (I) Constraint +=
',';
4243 Constraint +=
"=*m";
4246 WriteHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
4251 void FragileHazards::emitWriteHazard() {
4252 if (Locals.empty())
return;
4257 void FragileHazards::emitReadHazard(
CGBuilderTy &Builder) {
4258 assert(!Locals.empty());
4259 llvm::CallInst *call = Builder.CreateCall(ReadHazard, Locals);
4260 call->setDoesNotThrow();
4266 void FragileHazards::emitHazardsInNewBlocks() {
4267 if (Locals.empty())
return;
4272 for (llvm::Function::iterator
4273 FI = CGF.
CurFn->begin(), FE = CGF.
CurFn->end(); FI != FE; ++FI) {
4274 llvm::BasicBlock &BB = *FI;
4275 if (BlocksBeforeTry.count(&BB))
continue;
4278 for (llvm::BasicBlock::iterator
4279 BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) {
4280 llvm::Instruction &I = *BI;
4284 if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I))
4286 if (isa<llvm::IntrinsicInst>(I))
4291 if (cast<llvm::CallBase>(I).doesNotThrow())
4299 Builder.SetInsertPoint(&BB, BI);
4300 emitReadHazard(Builder);
4309 void FragileHazards::collectLocals() {
4317 llvm::BasicBlock &Entry = CGF.
CurFn->getEntryBlock();
4318 for (llvm::BasicBlock::iterator
4319 I = Entry.begin(), E = Entry.end(); I != E; ++I)
4320 if (isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I))
4321 Locals.push_back(&*I);
4324 llvm::FunctionType *FragileHazards::GetAsmFnType() {
4326 for (
unsigned i = 0, e = Locals.size();
i != e; ++
i)
4327 tys[
i] = Locals[
i]->getType();
4328 return llvm::FunctionType::get(CGF.
VoidTy, tys,
false);
4445 bool isTry = isa<ObjCAtTryStmt>(S);
4465 CGF.
EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
4478 "exceptiondata.ptr");
4484 FragileHazards Hazards(CGF);
4513 ExceptionData.getPointer());
4516 llvm::Constant *Zero = llvm::ConstantInt::get(CGF.
Builder.getInt32Ty(), 0);
4519 ObjCTypes.ExceptionDataTy, ExceptionData.getPointer(), GEPIndexes,
4522 ObjCTypes.getSetJmpFn(), SetJmpBuffer,
"setjmp_result");
4523 SetJmpResult->setCanReturnTwice();
4530 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
4531 CGF.
Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
4536 CGF.
EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
4537 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
4539 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.
Builder.saveAndClearIP();
4545 Hazards.emitWriteHazard();
4549 if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
4558 llvm::CallInst *Caught =
4560 ExceptionData.getPointer(),
"caught");
4570 llvm::BasicBlock *CatchBlock =
nullptr;
4571 llvm::BasicBlock *CatchHandler =
nullptr;
4577 "propagating_exception");
4583 ExceptionData.getPointer());
4585 llvm::CallInst *SetJmpResult =
4587 SetJmpBuffer,
"setjmp.result");
4588 SetJmpResult->setCanReturnTwice();
4591 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
4595 CGF.
Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
4605 bool AllMatched =
false;
4635 EmitInitOfCatchParam(CGF, Caught, CatchParam);
4647 assert(OPT &&
"Unexpected non-object pointer type in @catch");
4652 assert(IDecl &&
"Catch parameter must have Objective-C type!");
4658 llvm::CallInst *Match =
4660 matchArgs,
"match");
4665 CGF.
Builder.CreateCondBr(CGF.
Builder.CreateIsNotNull(Match,
"matched"),
4666 MatchedBlock, NextCatchBlock);
4682 EmitInitOfCatchParam(CGF, Tmp, CatchParam);
4698 if (Caught->use_empty())
4699 Caught->eraseFromParent();
4715 assert(PropagatingExnVar.
isValid());
4716 llvm::CallInst *NewCaught =
4718 ExceptionData.getPointer(),
"caught");
4728 Hazards.emitHazardsInNewBlocks();
4731 CGF.
Builder.restoreIP(TryFallthroughIP);
4735 CGF.
EmitBlock(FinallyEnd.getBlock(),
true);
4738 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
4743 if (PropagatingExnVar.
isValid()) {
4748 llvm::CallInst *Caught =
4750 ExceptionData.getPointer());
4751 PropagatingExn = Caught;
4756 CGF.
Builder.CreateUnreachable();
4759 CGF.
Builder.restoreIP(SavedIP);
4764 bool ClearInsertionPoint) {
4773 "Unexpected rethrow outside @catch block.");
4777 CGF.
EmitRuntimeCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
4778 ->setDoesNotReturn();
4779 CGF.
Builder.CreateUnreachable();
4782 if (ClearInsertionPoint)
4783 CGF.
Builder.ClearInsertionPoint();
4793 ObjCTypes.PtrObjectPtrTy);
4807 if (!isa<llvm::PointerType>(SrcTy)) {
4808 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(SrcTy);
4809 assert(Size <= 8 && "does not support size > 8
"); 4810 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty) 4811 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty); 4812 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 4814 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 4815 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 4816 llvm::Value *args[] = { src, dst.getPointer() }; 4817 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), 4818 args, "weakassign
"); 4824 void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
4825 llvm::Value *src, Address dst,
4827 llvm::Type * SrcTy = src->getType();
4828 if (!isa<llvm::PointerType>(SrcTy)) {
4829 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4830 assert(Size <= 8 && "does
not support size > 8
"); 4831 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty) 4832 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty); 4833 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 4835 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 4836 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 4837 llvm::Value *args[] = { src, dst.getPointer() }; 4839 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), 4840 args, "globalassign
"); 4842 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(), 4843 args, "threadlocalassign
"); 4849 void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
4850 llvm::Value *src, Address dst,
4851 llvm::Value *ivarOffset) {
4852 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is
NULL"); 4853 llvm::Type * SrcTy = src->getType(); 4854 if (!isa<llvm::PointerType>(SrcTy)) { 4855 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy); 4856 assert(Size <= 8 && "does
not support size > 8
"); 4857 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty) 4858 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty); 4859 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 4861 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 4862 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 4863 llvm::Value *args[] = { src, dst.getPointer(), ivarOffset }; 4864 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args); 4870 void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
4871 llvm::Value *src, Address dst) {
4872 llvm::Type * SrcTy = src->getType();
4873 if (!isa<llvm::PointerType>(SrcTy)) {
4874 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4875 assert(Size <= 8 && "does
not support size > 8
"); 4876 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty) 4877 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty); 4878 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 4880 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 4881 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 4882 llvm::Value *args[] = { src, dst.getPointer() }; 4883 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), 4884 args, "strongassign
"); 4887 void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, 4890 llvm::Value *size) { 4891 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy); 4892 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy); 4893 llvm::Value *args[] = { DestPtr.getPointer(), SrcPtr.getPointer(), size }; 4894 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args); 4899 LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
4901 llvm::Value *BaseValue,
4902 const ObjCIvarDecl *Ivar,
4903 unsigned CVRQualifiers) {
4904 const ObjCInterfaceDecl *ID =
4905 ObjectTy->getAs<ObjCObjectType>()->getInterface();
4906 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
4907 EmitIvarOffset(CGF, ID, Ivar));
4910 llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
4911 const ObjCInterfaceDecl *Interface,
4912 const ObjCIvarDecl *Ivar) {
4913 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
4914 return llvm::ConstantInt::get(
4915 CGM.getTypes().ConvertType(CGM.getContext().LongTy),
4919 /* *** Private Interface *** */
4921 std::string CGObjCCommonMac::GetSectionName(StringRef Section,
4922 StringRef MachOAttributes) {
4923 switch (CGM.getTriple().getObjectFormat()) {
4924 case llvm::Triple::UnknownObjectFormat:
4925 llvm_unreachable("unexpected
object file format
"); 4926 case llvm::Triple::MachO: { 4927 if (MachOAttributes.empty()) 4928 return ("__DATA,
" + Section).str(); 4929 return ("__DATA,
" + Section + ",
" + MachOAttributes).str(); 4931 case llvm::Triple::ELF: 4932 assert(Section.substr(0, 2) == "__
" && 4933 "expected the name to begin with __
"); 4934 return Section.substr(2).str(); 4935 case llvm::Triple::COFF: 4936 assert(Section.substr(0, 2) == "__
" && 4937 "expected the name to begin with __
"); 4938 return (".
" + Section.substr(2) + "$B
").str(); 4939 case llvm::Triple::Wasm: 4940 case llvm::Triple::XCOFF: 4941 llvm::report_fatal_error( 4942 "Objective-C support is unimplemented
for object file format.
"); 4945 llvm_unreachable("Unhandled llvm::Triple::ObjectFormatType
enum"); 4956 enum ImageInfoFlags {
4957 eImageInfo_FixAndContinue = (1 << 0), // This flag is no longer set by clang.
4958 eImageInfo_GarbageCollected = (1 << 1),
4959 eImageInfo_GCOnly = (1 << 2),
4960 eImageInfo_OptimizedByDyld = (1 << 3), // This flag is set by the dyld shared cache.
4962 // A flag indicating that the module has no instances of a @synthesize of a
4963 // superclass variable. <rdar://problem/6803242>
4964 eImageInfo_CorrectedSynthesize = (1 << 4), // This flag is no longer set by clang.
4965 eImageInfo_ImageIsSimulated = (1 << 5),
4966 eImageInfo_ClassProperties = (1 << 6)
4969 void CGObjCCommonMac::EmitImageInfo() {
4970 unsigned version = 0; // Version is unused?
4971 std::string Section =
4973 ? "__OBJC,__image_info,regular
" 4974 : GetSectionName("__objc_imageinfo
", "regular,no_dead_strip
"); 4976 // Generate module-level named metadata to convey this information to the 4977 // linker and code-gen. 4978 llvm::Module &Mod = CGM.getModule(); 4980 // Add the ObjC ABI version to the module flags. 4981 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Version
", ObjCABI); 4982 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Version
", 4984 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Section
", 4985 llvm::MDString::get(VMContext, Section)); 4987 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) { 4988 // Non-GC overrides those files which specify GC. 4989 Mod.addModuleFlag(llvm::Module::Override, 4990 "Objective-C Garbage Collection
", (uint32_t)0); 4992 // Add the ObjC garbage collection value. 4993 Mod.addModuleFlag(llvm::Module::Error, 4994 "Objective-C Garbage Collection
", 4995 eImageInfo_GarbageCollected); 4997 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) { 4998 // Add the ObjC GC Only value. 4999 Mod.addModuleFlag(llvm::Module::Error, "Objective-C GC Only
", 5002 // Require that GC be specified and set to eImageInfo_GarbageCollected. 5003 llvm::Metadata *Ops[2] = { 5004 llvm::MDString::get(VMContext, "Objective-C Garbage Collection
"), 5005 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( 5006 llvm::Type::getInt32Ty(VMContext), eImageInfo_GarbageCollected))}; 5007 Mod.addModuleFlag(llvm::Module::Require, "Objective-C GC Only
", 5008 llvm::MDNode::get(VMContext, Ops)); 5012 // Indicate whether we're compiling this to run on a simulator. 5013 if (CGM.getTarget().getTriple().isSimulatorEnvironment()) 5014 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Is Simulated
", 5015 eImageInfo_ImageIsSimulated); 5017 // Indicate whether we are generating class properties. 5018 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Class Properties
", 5019 eImageInfo_ClassProperties); 5022 // struct objc_module { 5023 // unsigned long version; 5024 // unsigned long size; 5025 // const char *name; 5029 // FIXME: Get from somewhere 5030 static const int ModuleVersion = 7; 5032 void CGObjCMac::EmitModuleInfo() { 5033 uint64_t Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ModuleTy); 5035 ConstantInitBuilder builder(CGM); 5036 auto values = builder.beginStruct(ObjCTypes.ModuleTy); 5037 values.addInt(ObjCTypes.LongTy, ModuleVersion); 5038 values.addInt(ObjCTypes.LongTy, Size); 5039 // This used to be the filename, now it is unused. <rdr://4327263> 5040 values.add(GetClassName(StringRef(""))); 5041 values.add(EmitModuleSymbols()); 5042 CreateMetadataVar("OBJC_MODULES
", values, 5043 "__OBJC,__module_info,regular,no_dead_strip
", 5044 CGM.getPointerAlign(), true); 5047 llvm::Constant *CGObjCMac::EmitModuleSymbols() { 5048 unsigned NumClasses = DefinedClasses.size(); 5049 unsigned NumCategories = DefinedCategories.size(); 5051 // Return null if no symbols were defined. 5052 if (!NumClasses && !NumCategories) 5053 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy); 5055 ConstantInitBuilder builder(CGM); 5056 auto values = builder.beginStruct(); 5057 values.addInt(ObjCTypes.LongTy, 0); 5058 values.addNullPointer(ObjCTypes.SelectorPtrTy); 5059 values.addInt(ObjCTypes.ShortTy, NumClasses); 5060 values.addInt(ObjCTypes.ShortTy, NumCategories); 5062 // The runtime expects exactly the list of defined classes followed 5063 // by the list of defined categories, in a single array. 5064 auto array = values.beginArray(ObjCTypes.Int8PtrTy); 5065 for (unsigned i=0; i<NumClasses; i++) { 5066 const ObjCInterfaceDecl *ID = ImplementedClasses[i]; 5068 if (ObjCImplementationDecl *IMP = ID->getImplementation()) 5069 // We are implementing a weak imported interface. Give it external linkage 5070 if (ID->isWeakImported() && !IMP->isWeakImported()) 5071 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage); 5073 array.addBitCast(DefinedClasses[i], ObjCTypes.Int8PtrTy); 5075 for (unsigned i=0; i<NumCategories; i++) 5076 array.addBitCast(DefinedCategories[i], ObjCTypes.Int8PtrTy); 5078 array.finishAndAddTo(values); 5080 llvm::GlobalVariable *GV = CreateMetadataVar( 5081 "OBJC_SYMBOLS
", values, "__OBJC,__symbols,regular,no_dead_strip
", 5082 CGM.getPointerAlign(), true); 5083 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy); 5086 llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF, 5087 IdentifierInfo *II) { 5088 LazySymbols.insert(II); 5090 llvm::GlobalVariable *&Entry = ClassReferences[II]; 5093 llvm::Constant *Casted = 5094 llvm::ConstantExpr::getBitCast(GetClassName(II->getName()), 5095 ObjCTypes.ClassPtrTy); 5096 Entry = CreateMetadataVar( 5097 "OBJC_CLASS_REFERENCES_
", Casted, 5098 "__OBJC,__cls_refs,literal_pointers,no_dead_strip
", 5099 CGM.getPointerAlign(), true); 5102 return CGF.Builder.CreateAlignedLoad(Entry, CGF.getPointerAlign()); 5105 llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF, 5106 const ObjCInterfaceDecl *ID) { 5107 // If the class has the objc_runtime_visible attribute, we need to 5108 // use the Objective-C runtime to get the class. 5109 if (ID->hasAttr<ObjCRuntimeVisibleAttr>()) 5110 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes); 5112 IdentifierInfo *RuntimeName = 5113 &CGM.getContext().Idents.get(ID->getObjCRuntimeNameAsString()); 5114 return EmitClassRefFromId(CGF, RuntimeName); 5117 llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) { 5118 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool
"); 5119 return EmitClassRefFromId(CGF, II); 5122 llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel) { 5123 return CGF.Builder.CreateLoad(EmitSelectorAddr(CGF, Sel)); 5126 Address CGObjCMac::EmitSelectorAddr(CodeGenFunction &CGF, Selector Sel) { 5127 CharUnits Align = CGF.getPointerAlign(); 5129 llvm::GlobalVariable *&Entry = SelectorReferences[Sel]; 5131 llvm::Constant *Casted = 5132 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel), 5133 ObjCTypes.SelectorPtrTy); 5134 Entry = CreateMetadataVar( 5135 "OBJC_SELECTOR_REFERENCES_
", Casted, 5136 "__OBJC,__message_refs,literal_pointers,no_dead_strip
", Align, true); 5137 Entry->setExternallyInitialized(true); 5140 return Address(Entry, Align); 5143 llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) { 5144 llvm::GlobalVariable *&Entry = ClassNames[RuntimeName]; 5146 Entry = CreateCStringLiteral(RuntimeName, ObjCLabelType::ClassName); 5147 return getConstantGEP(VMContext, Entry, 0, 0); 5150 llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) { 5151 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*>::iterator 5152 I = MethodDefinitions.find(MD); 5153 if (I != MethodDefinitions.end()) 5161 llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
5162 const ObjCCommonTypesHelper &ObjCTypes) {
5163 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
5166 void IvarLayoutBuilder::visitRecord(const RecordType *RT,
5168 const RecordDecl *RD = RT->getDecl();
5170 // If this is a union, remember that we had one, because it might mess
5171 // up the ordering of layout entries.
5173 IsDisordered = true;
5175 const ASTRecordLayout *recLayout = nullptr;
5176 visitAggregate(RD->field_begin(), RD->field_end(), offset,
5177 [&](const FieldDecl *field) -> CharUnits {
5179 recLayout = &CGM.getContext().getASTRecordLayout(RD);
5180 auto offsetInBits = recLayout->getFieldOffset(field->getFieldIndex());
5181 return CGM.getContext().toCharUnitsFromBits(offsetInBits);
5185 template <class Iterator, class GetOffsetFn>
5186 void IvarLayoutBuilder::visitAggregate(Iterator begin, Iterator end,
5187 CharUnits aggregateOffset,
5188 const GetOffsetFn &getOffset) {
5189 for (; begin != end; ++begin) {
5190 auto field = *begin;
5192 // Skip over bitfields.
5193 if (field->isBitField()) {
5197 // Compute the offset of the field within the aggregate.
5198 CharUnits fieldOffset = aggregateOffset + getOffset(field);
5200 visitField(field, fieldOffset);
5205 void IvarLayoutBuilder::visitField(const FieldDecl *field,
5206 CharUnits fieldOffset) {
5207 QualType fieldType = field->getType();
5209 // Drill down into arrays.
5210 uint64_t numElts = 1;
5211 if (auto arrayType = CGM.getContext().getAsIncompleteArrayType(fieldType)) {
5213 fieldType = arrayType->getElementType();
5215 // Unlike incomplete arrays, constant arrays can be nested.
5216 while (auto arrayType = CGM.getContext().getAsConstantArrayType(fieldType)) {
5217 numElts *= arrayType->getSize().getZExtValue();
5218 fieldType = arrayType->getElementType();
5221 assert(!fieldType->isArrayType() && "ivar of non-constant array
type?
"); 5223 // If we ended up with a zero-sized array, we've done what we can do within 5224 // the limits of this layout encoding. 5225 if (numElts == 0) return; 5227 // Recurse if the base element type is a record type. 5228 if (auto recType = fieldType->getAs<RecordType>()) { 5229 size_t oldEnd = IvarsInfo.size(); 5231 visitRecord(recType, fieldOffset); 5233 // If we have an array, replicate the first entry's layout information. 5234 auto numEltEntries = IvarsInfo.size() - oldEnd; 5235 if (numElts != 1 && numEltEntries != 0) { 5236 CharUnits eltSize = CGM.getContext().getTypeSizeInChars(recType); 5237 for (uint64_t eltIndex = 1; eltIndex != numElts; ++eltIndex) { 5238 // Copy the last numEltEntries onto the end of the array, adjusting 5239 // each for the element size. 5240 for (size_t i = 0; i != numEltEntries; ++i) { 5241 auto firstEntry = IvarsInfo[oldEnd + i]; 5242 IvarsInfo.push_back(IvarInfo(firstEntry.Offset + eltIndex * eltSize, 5243 firstEntry.SizeInWords)); 5251 // Classify the element type. 5252 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), fieldType); 5254 // If it matches what we're looking for, add an entry. 5255 if ((ForStrongLayout && GCAttr == Qualifiers::Strong) 5256 || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) { 5257 assert(CGM.getContext().getTypeSizeInChars(fieldType) 5258 == CGM.getPointerSize()); 5259 IvarsInfo.push_back(IvarInfo(fieldOffset, numElts)); 5266 llvm::Constant *IvarLayoutBuilder::buildBitmap(CGObjCCommonMac &CGObjC,
5267 llvm::SmallVectorImpl<unsigned char> &buffer) {
5268 // The bitmap is a series of skip/scan instructions, aligned to word
5269 // boundaries. The skip is performed first.
5270 const unsigned char MaxNibble = 0xF;
5271 const unsigned char SkipMask = 0xF0, SkipShift = 4;
5272 const unsigned char ScanMask = 0x0F, ScanShift = 0;
5274 assert(!IvarsInfo.empty() && "generating bitmap
for no data
"); 5276 // Sort the ivar info on byte position in case we encounterred a 5277 // union nested in the ivar list. 5279 // This isn't a stable sort, but our algorithm should handle it fine. 5280 llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end()); 5282 assert(std::is_sorted(IvarsInfo.begin(), IvarsInfo.end())); 5284 assert(IvarsInfo.back().Offset < InstanceEnd); 5286 assert(buffer.empty()); 5288 // Skip the next N words. 5289 auto skip = [&](unsigned numWords) { 5290 assert(numWords > 0); 5292 // Try to merge into the previous byte. Since scans happen second, we 5293 // can't do this if it includes a scan. 5294 if (!buffer.empty() && !(buffer.back() & ScanMask)) { 5295 unsigned lastSkip = buffer.back() >> SkipShift; 5296 if (lastSkip < MaxNibble) { 5297 unsigned claimed = std::min(MaxNibble - lastSkip, numWords); 5298 numWords -= claimed; 5299 lastSkip += claimed; 5300 buffer.back() = (lastSkip << SkipShift); 5304 while (numWords >= MaxNibble) { 5305 buffer.push_back(MaxNibble << SkipShift); 5306 numWords -= MaxNibble; 5309 buffer.push_back(numWords << SkipShift); 5313 // Scan the next N words. 5314 auto scan = [&](unsigned numWords) { 5315 assert(numWords > 0); 5317 // Try to merge into the previous byte. Since scans happen second, we can 5318 // do this even if it includes a skip. 5319 if (!buffer.empty()) { 5320 unsigned lastScan = (buffer.back() & ScanMask) >> ScanShift; 5321 if (lastScan < MaxNibble) { 5322 unsigned claimed = std::min(MaxNibble - lastScan, numWords); 5323 numWords -= claimed; 5324 lastScan += claimed; 5325 buffer.back() = (buffer.back() & SkipMask) | (lastScan << ScanShift); 5329 while (numWords >= MaxNibble) { 5330 buffer.push_back(MaxNibble << ScanShift); 5331 numWords -= MaxNibble; 5334 buffer.push_back(numWords << ScanShift); 5338 // One past the end of the last scan. 5339 unsigned endOfLastScanInWords = 0; 5340 const CharUnits WordSize = CGM.getPointerSize(); 5342 // Consider all the scan requests. 5343 for (auto &request : IvarsInfo) { 5344 CharUnits beginOfScan = request.Offset - InstanceBegin; 5346 // Ignore scan requests that don't start at an even multiple of the 5347 // word size. We can't encode them. 5348 if ((beginOfScan % WordSize) != 0) continue; 5350 // Ignore scan requests that start before the instance start. 5351 // This assumes that scans never span that boundary. The boundary 5352 // isn't the true start of the ivars, because in the fragile-ARC case 5353 // it's rounded up to word alignment, but the test above should leave 5354 // us ignoring that possibility. 5355 if (beginOfScan.isNegative()) { 5356 assert(request.Offset + request.SizeInWords * WordSize <= InstanceBegin); 5360 unsigned beginOfScanInWords = beginOfScan / WordSize; 5361 unsigned endOfScanInWords = beginOfScanInWords + request.SizeInWords; 5363 // If the scan starts some number of words after the last one ended, 5365 if (beginOfScanInWords > endOfLastScanInWords) { 5366 skip(beginOfScanInWords - endOfLastScanInWords); 5368 // Otherwise, start scanning where the last left off. 5370 beginOfScanInWords = endOfLastScanInWords; 5372 // If that leaves us with nothing to scan, ignore this request. 5373 if (beginOfScanInWords >= endOfScanInWords) continue; 5376 // Scan to the end of the request. 5377 assert(beginOfScanInWords < endOfScanInWords); 5378 scan(endOfScanInWords - beginOfScanInWords); 5379 endOfLastScanInWords = endOfScanInWords; 5383 return llvm::ConstantPointerNull::get(CGM.Int8PtrTy); 5385 // For GC layouts, emit a skip to the end of the allocation so that we 5386 // have precise information about the entire thing. This isn't useful 5387 // or necessary for the ARC-style layout strings. 5388 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) { 5389 unsigned lastOffsetInWords = 5390 (InstanceEnd - InstanceBegin + WordSize - CharUnits::One()) / WordSize; 5391 if (lastOffsetInWords > endOfLastScanInWords) { 5392 skip(lastOffsetInWords - endOfLastScanInWords); 5396 // Null terminate the string. 5397 buffer.push_back(0); 5399 auto *Entry = CGObjC.CreateCStringLiteral( 5400 reinterpret_cast<char *>(buffer.data()), ObjCLabelType::ClassName); 5401 return getConstantGEP(CGM.getLLVMContext(), Entry, 0, 0); 5421 CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD,
5422 CharUnits beginOffset, CharUnits endOffset,
5423 bool ForStrongLayout, bool HasMRCWeakIvars) {
5424 // If this is MRC, and we're either building a strong layout or there
5425 // are no weak ivars, bail out early.
5426 llvm::Type *PtrTy = CGM.Int8PtrTy;
5427 if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
5428 !CGM.getLangOpts().ObjCAutoRefCount &&
5429 (ForStrongLayout || !HasMRCWeakIvars))
5430 return llvm::Constant::getNullValue(PtrTy);
5432 const ObjCInterfaceDecl *OI = OMD->getClassInterface();
5433 SmallVector<const ObjCIvarDecl*, 32> ivars;
5435 // GC layout strings include the complete object layout, possibly
5436 // inaccurately in the non-fragile ABI; the runtime knows how to fix this
5439 // ARC layout strings only include the class's ivars. In non-fragile
5440 // runtimes, that means starting at InstanceStart, rounded up to word
5441 // alignment. In fragile runtimes, there's no InstanceStart, so it means
5442 // starting at the offset of the first ivar, rounded up to word alignment.
5444 // MRC weak layout strings follow the ARC style.
5445 CharUnits baseOffset;
5446 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
5447 for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();
5448 IVD; IVD = IVD->getNextIvar())
5449 ivars.push_back(IVD);
5451 if (isNonFragileABI()) {
5452 baseOffset = beginOffset; // InstanceStart
5453 } else if (!ivars.empty()) {
5455 CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivars[0]));
5457 baseOffset = CharUnits::Zero();
5460 baseOffset = baseOffset.alignTo(CGM.getPointerAlign());
5463 CGM.getContext().DeepCollectObjCIvars(OI, true, ivars);
5465 baseOffset = CharUnits::Zero();
5469 return llvm::Constant::getNullValue(PtrTy);
5471 IvarLayoutBuilder builder(CGM, baseOffset, endOffset, ForStrongLayout);
5473 builder.visitAggregate(ivars.begin(), ivars.end(), CharUnits::Zero(),
5474 [&](const ObjCIvarDecl *ivar) -> CharUnits {
5475 return CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivar));
5478 if (!builder.hasBitmapData())
5479 return llvm::Constant::getNullValue(PtrTy);
5481 llvm::SmallVector<unsigned char, 4> buffer;
5482 llvm::Constant *C = builder.buildBitmap(*this, buffer);
5484 if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
5485 printf("\n%s ivar layout
for class '%s':
", 5486 ForStrongLayout ? "strong
" : "weak
", 5487 OMD->getClassInterface()->getName().str().c_str()); 5488 builder.dump(buffer); 5493 llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) { 5494 llvm::GlobalVariable *&Entry = MethodVarNames[Sel]; 5495 // FIXME: Avoid std::string in "Sel.getAsString()
" 5497 Entry = CreateCStringLiteral(Sel.getAsString(), ObjCLabelType::MethodVarName); 5498 return getConstantGEP(VMContext, Entry, 0, 0); 5501 // FIXME: Merge into a single cstring creation function. 5502 llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) { 5503 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID)); 5506 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) { 5507 std::string TypeStr; 5508 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field); 5510 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr]; 5512 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType); 5513 return getConstantGEP(VMContext, Entry, 0, 0); 5516 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D, 5518 std::string TypeStr = 5519 CGM.getContext().getObjCEncodingForMethodDecl(D, Extended); 5521 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr]; 5523 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType); 5524 return getConstantGEP(VMContext, Entry, 0, 0); 5527 // FIXME: Merge into a single cstring creation function. 5528 llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) { 5529 llvm::GlobalVariable *&Entry = PropertyNames[Ident]; 5531 Entry = CreateCStringLiteral(Ident->getName(), ObjCLabelType::PropertyName); 5532 return getConstantGEP(VMContext, Entry, 0, 0); 5535 // FIXME: Merge into a single cstring creation function. 5536 // FIXME: This Decl should be more precise. 5538 CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD, 5539 const Decl *Container) { 5540 std::string TypeStr = 5541 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container); 5542 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr)); 5545 void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D, 5546 const ObjCContainerDecl *CD, 5547 SmallVectorImpl<char> &Name) { 5548 llvm::raw_svector_ostream OS(Name); 5549 assert (CD && "Missing container
decl in GetNameForMethod
"); 5550 OS << '\01' << (D->isInstanceMethod() ? '-' : '+') 5551 << '[' << CD->getName(); 5552 if (const ObjCCategoryImplDecl *CID = 5553 dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext())) 5554 OS << '(' << *CID << ')'; 5555 OS << ' ' << D->getSelector().getAsString() << ']'; 5558 void CGObjCMac::FinishModule() { 5561 // Emit the dummy bodies for any protocols which were referenced but 5563 for (auto &entry : Protocols) { 5564 llvm::GlobalVariable *global = entry.second; 5565 if (global->hasInitializer()) 5568 ConstantInitBuilder builder(CGM); 5569 auto values = builder.beginStruct(ObjCTypes.ProtocolTy); 5570 values.addNullPointer(ObjCTypes.ProtocolExtensionPtrTy); 5571 values.add(GetClassName(entry.first->getName())); 5572 values.addNullPointer(ObjCTypes.ProtocolListPtrTy); 5573 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy); 5574 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy); 5575 values.finishAndSetAsInitializer(global); 5576 CGM.addCompilerUsedGlobal(global); 5579 // Add assembler directives to add lazy undefined symbol references 5580 // for classes which are referenced but not defined. This is 5581 // important for correct linker interaction. 5583 // FIXME: It would be nice if we had an LLVM construct for this. 5584 if ((!LazySymbols.empty() || !DefinedSymbols.empty()) && 5585 CGM.getTriple().isOSBinFormatMachO()) { 5586 SmallString<256> Asm; 5587 Asm += CGM.getModule().getModuleInlineAsm(); 5588 if (!Asm.empty() && Asm.back() != '\n') 5591 llvm::raw_svector_ostream OS(Asm); 5592 for (const auto *Sym : DefinedSymbols) 5593 OS << "\t.objc_class_name_
" << Sym->getName() << "=0\n
" 5594 << "\t.globl .objc_class_name_
" << Sym->getName() << "\n
"; 5595 for (const auto *Sym : LazySymbols) 5596 OS << "\t.lazy_reference .objc_class_name_
" << Sym->getName() << "\n
"; 5597 for (const auto &Category : DefinedCategoryNames) 5598 OS << "\t.objc_category_name_
" << Category << "=0\n
" 5599 << "\t.globl .objc_category_name_
" << Category << "\n
"; 5601 CGM.getModule().setModuleInlineAsm(OS.str()); 5605 CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm) 5606 : CGObjCCommonMac(cgm), ObjCTypes(cgm), ObjCEmptyCacheVar(nullptr), 5607 ObjCEmptyVtableVar(nullptr) { 5613 ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm) 5614 : VMContext(cgm.getLLVMContext()), CGM(cgm), ExternalProtocolPtrTy(nullptr) 5616 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 5617 ASTContext &Ctx = CGM.getContext(); 5619 ShortTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.ShortTy)); 5621 LongTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.LongTy)); 5622 Int8PtrTy = CGM.Int8PtrTy; 5623 Int8PtrPtrTy = CGM.Int8PtrPtrTy; 5625 // arm64 targets use "int" ivar offset variables. All others, 5626 // including OS X x86_64 and Windows x86_64, use "long" ivar offsets. 5627 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::aarch64) 5628 IvarOffsetVarTy = IntTy; 5630 IvarOffsetVarTy = LongTy; 5633 cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCIdType())); 5635 llvm::PointerType::getUnqual(ObjectPtrTy); 5637 cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCSelType())); 5639 // I'm not sure I like this. The implicit coordination is a bit 5640 // gross. We should solve this in a reasonable fashion because this 5641 // is a pretty common task (match some runtime data structure with 5642 // an LLVM data structure). 5644 // FIXME: This is leaked. 5645 // FIXME: Merge with rewriter code? 5647 // struct _objc_super { 5651 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct, 5652 Ctx.getTranslationUnitDecl(), 5653 SourceLocation(), SourceLocation(), 5654 &Ctx.Idents.get("_objc_super
")); 5655 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 5656 nullptr, Ctx.getObjCIdType(), nullptr, nullptr, 5657 false, ICIS_NoInit)); 5658 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 5659 nullptr, Ctx.getObjCClassType(), nullptr, 5660 nullptr, false, ICIS_NoInit)); 5661 RD->completeDefinition(); 5663 SuperCTy = Ctx.getTagDeclType(RD); 5664 SuperPtrCTy = Ctx.getPointerType(SuperCTy); 5666 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy)); 5667 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy); 5671 // char *attributes; 5673 PropertyTy = llvm::StructType::create("struct._prop_t
", Int8PtrTy, Int8PtrTy); 5675 // struct _prop_list_t { 5676 // uint32_t entsize; // sizeof(struct _prop_t) 5677 // uint32_t count_of_properties; 5678 // struct _prop_t prop_list[count_of_properties]; 5680 PropertyListTy = llvm::StructType::create( 5681 "struct._prop_list_t
", IntTy, IntTy, llvm::ArrayType::get(PropertyTy, 0)); 5682 // struct _prop_list_t * 5683 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy); 5685 // struct _objc_method { 5687 // char *method_type; 5690 MethodTy = llvm::StructType::create("struct._objc_method
", SelectorPtrTy, 5691 Int8PtrTy, Int8PtrTy); 5693 // struct _objc_cache * 5694 CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache
"); 5695 CachePtrTy = llvm::PointerType::getUnqual(CacheTy); 5698 ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) 5699 : ObjCCommonTypesHelper(cgm) { 5700 // struct _objc_method_description { 5704 MethodDescriptionTy = llvm::StructType::create( 5705 "struct._objc_method_description
", SelectorPtrTy, Int8PtrTy); 5707 // struct _objc_method_description_list { 5709 // struct _objc_method_description[1]; 5711 MethodDescriptionListTy = 5712 llvm::StructType::create("struct._objc_method_description_list
", IntTy, 5713 llvm::ArrayType::get(MethodDescriptionTy, 0)); 5715 // struct _objc_method_description_list * 5716 MethodDescriptionListPtrTy = 5717 llvm::PointerType::getUnqual(MethodDescriptionListTy); 5719 // Protocol description structures 5721 // struct _objc_protocol_extension { 5722 // uint32_t size; // sizeof(struct _objc_protocol_extension) 5723 // struct _objc_method_description_list *optional_instance_methods; 5724 // struct _objc_method_description_list *optional_class_methods; 5725 // struct _objc_property_list *instance_properties; 5726 // const char ** extendedMethodTypes; 5727 // struct _objc_property_list *class_properties; 5729 ProtocolExtensionTy = llvm::StructType::create( 5730 "struct._objc_protocol_extension
", IntTy, MethodDescriptionListPtrTy, 5731 MethodDescriptionListPtrTy, PropertyListPtrTy, Int8PtrPtrTy, 5734 // struct _objc_protocol_extension * 5735 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy); 5737 // Handle recursive construction of Protocol and ProtocolList types 5740 llvm::StructType::create(VMContext, "struct._objc_protocol
"); 5743 llvm::StructType::create(VMContext, "struct._objc_protocol_list
"); 5744 ProtocolListTy->setBody(llvm::PointerType::getUnqual(ProtocolListTy), LongTy, 5745 llvm::ArrayType::get(ProtocolTy, 0)); 5747 // struct _objc_protocol { 5748 // struct _objc_protocol_extension *isa; 5749 // char *protocol_name; 5750 // struct _objc_protocol **_objc_protocol_list; 5751 // struct _objc_method_description_list *instance_methods; 5752 // struct _objc_method_description_list *class_methods; 5754 ProtocolTy->setBody(ProtocolExtensionPtrTy, Int8PtrTy, 5755 llvm::PointerType::getUnqual(ProtocolListTy), 5756 MethodDescriptionListPtrTy, MethodDescriptionListPtrTy); 5758 // struct _objc_protocol_list * 5759 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy); 5761 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy); 5763 // Class description structures 5765 // struct _objc_ivar { 5770 IvarTy = llvm::StructType::create("struct._objc_ivar
", Int8PtrTy, Int8PtrTy, 5773 // struct _objc_ivar_list * 5775 llvm::StructType::create(VMContext, "struct._objc_ivar_list
"); 5776 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy); 5778 // struct _objc_method_list * 5780 llvm::StructType::create(VMContext, "struct._objc_method_list
"); 5781 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy); 5783 // struct _objc_class_extension * 5784 ClassExtensionTy = llvm::StructType::create( 5785 "struct._objc_class_extension
", IntTy, Int8PtrTy, PropertyListPtrTy); 5786 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy); 5788 ClassTy = llvm::StructType::create(VMContext, "struct._objc_class
"); 5790 // struct _objc_class { 5792 // Class super_class; 5796 // long instance_size; 5797 // struct _objc_ivar_list *ivars; 5798 // struct _objc_method_list *methods; 5799 // struct _objc_cache *cache; 5800 // struct _objc_protocol_list *protocols; 5801 // char *ivar_layout; 5802 // struct _objc_class_ext *ext; 5804 ClassTy->setBody(llvm::PointerType::getUnqual(ClassTy), 5805 llvm::PointerType::getUnqual(ClassTy), Int8PtrTy, LongTy, 5806 LongTy, LongTy, IvarListPtrTy, MethodListPtrTy, CachePtrTy, 5807 ProtocolListPtrTy, Int8PtrTy, ClassExtensionPtrTy); 5809 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy); 5811 // struct _objc_category { 5812 // char *category_name; 5813 // char *class_name; 5814 // struct _objc_method_list *instance_method; 5815 // struct _objc_method_list *class_method; 5816 // struct _objc_protocol_list *protocols; 5817 // uint32_t size; // sizeof(struct _objc_category) 5818 // struct _objc_property_list *instance_properties;// category's @property 5819 // struct _objc_property_list *class_properties; 5821 CategoryTy = llvm::StructType::create( 5822 "struct._objc_category
", Int8PtrTy, Int8PtrTy, MethodListPtrTy, 5823 MethodListPtrTy, ProtocolListPtrTy, IntTy, PropertyListPtrTy, 5826 // Global metadata structures 5828 // struct _objc_symtab { 5829 // long sel_ref_cnt; 5831 // short cls_def_cnt; 5832 // short cat_def_cnt; 5833 // char *defs[cls_def_cnt + cat_def_cnt]; 5835 SymtabTy = llvm::StructType::create("struct._objc_symtab
", LongTy, 5836 SelectorPtrTy, ShortTy, ShortTy, 5837 llvm::ArrayType::get(Int8PtrTy, 0)); 5838 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy); 5840 // struct _objc_module { 5842 // long size; // sizeof(struct _objc_module) 5844 // struct _objc_symtab* symtab; 5846 ModuleTy = llvm::StructType::create("struct._objc_module
", LongTy, LongTy, 5847 Int8PtrTy, SymtabPtrTy); 5849 // FIXME: This is the size of the setjmp buffer and should be target 5850 // specific. 18 is what's used on 32-bit X86. 5851 uint64_t SetJmpBufferSize = 18; 5854 llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4); 5856 ExceptionDataTy = llvm::StructType::create( 5857 "struct._objc_exception_data
", 5858 llvm::ArrayType::get(CGM.Int32Ty, SetJmpBufferSize), StackPtrTy); 5861 ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm) 5862 : ObjCCommonTypesHelper(cgm) { 5863 // struct _method_list_t { 5864 // uint32_t entsize; // sizeof(struct _objc_method) 5865 // uint32_t method_count; 5866 // struct _objc_method method_list[method_count]; 5869 llvm::StructType::create("struct.__method_list_t
", IntTy, IntTy, 5870 llvm::ArrayType::get(MethodTy, 0)); 5871 // struct method_list_t * 5872 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy); 5874 // struct _protocol_t { 5876 // const char * const protocol_name; 5877 // const struct _protocol_list_t * protocol_list; // super protocols 5878 // const struct method_list_t * const instance_methods; 5879 // const struct method_list_t * const class_methods; 5880 // const struct method_list_t *optionalInstanceMethods; 5881 // const struct method_list_t *optionalClassMethods; 5882 // const struct _prop_list_t * properties; 5883 // const uint32_t size; // sizeof(struct _protocol_t) 5884 // const uint32_t flags; // = 0 5885 // const char ** extendedMethodTypes; 5886 // const char *demangledName; 5887 // const struct _prop_list_t * class_properties; 5890 // Holder for struct _protocol_list_t * 5891 ProtocolListnfABITy = 5892 llvm::StructType::create(VMContext, "struct._objc_protocol_list
"); 5894 ProtocolnfABITy = llvm::StructType::create( 5895 "struct._protocol_t
", ObjectPtrTy, Int8PtrTy, 5896 llvm::PointerType::getUnqual(ProtocolListnfABITy), MethodListnfABIPtrTy, 5897 MethodListnfABIPtrTy, MethodListnfABIPtrTy, MethodListnfABIPtrTy, 5898 PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy, Int8PtrTy, 5901 // struct _protocol_t* 5902 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy); 5904 // struct _protocol_list_t { 5905 // long protocol_count; // Note, this is 32/64 bit 5906 // struct _protocol_t *[protocol_count]; 5908 ProtocolListnfABITy->setBody(LongTy, 5909 llvm::ArrayType::get(ProtocolnfABIPtrTy, 0)); 5911 // struct _objc_protocol_list* 5912 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy); 5915 // unsigned [long] int *offset; // pointer to ivar offset location 5918 // uint32_t alignment; 5921 IvarnfABITy = llvm::StructType::create( 5922 "struct._ivar_t
", llvm::PointerType::getUnqual(IvarOffsetVarTy), 5923 Int8PtrTy, Int8PtrTy, IntTy, IntTy); 5925 // struct _ivar_list_t { 5926 // uint32 entsize; // sizeof(struct _ivar_t) 5928 // struct _iver_t list[count]; 5931 llvm::StructType::create("struct._ivar_list_t
", IntTy, IntTy, 5932 llvm::ArrayType::get(IvarnfABITy, 0)); 5934 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy); 5936 // struct _class_ro_t { 5937 // uint32_t const flags; 5938 // uint32_t const instanceStart; 5939 // uint32_t const instanceSize; 5940 // uint32_t const reserved; // only when building for 64bit targets 5941 // const uint8_t * const ivarLayout; 5942 // const char *const name; 5943 // const struct _method_list_t * const baseMethods; 5944 // const struct _objc_protocol_list *const baseProtocols; 5945 // const struct _ivar_list_t *const ivars; 5946 // const uint8_t * const weakIvarLayout; 5947 // const struct _prop_list_t * const properties; 5950 // FIXME. Add 'reserved' field in 64bit abi mode! 5951 ClassRonfABITy = llvm::StructType::create( 5952 "struct._class_ro_t
", IntTy, IntTy, IntTy, Int8PtrTy, Int8PtrTy, 5953 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, IvarListnfABIPtrTy, 5954 Int8PtrTy, PropertyListPtrTy); 5956 // ImpnfABITy - LLVM for id (*)(id, SEL, ...) 5957 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy }; 5958 ImpnfABITy = llvm::FunctionType::get(ObjectPtrTy, params, false) 5961 // struct _class_t { 5962 // struct _class_t *isa; 5963 // struct _class_t * const superclass; 5966 // struct class_ro_t *ro; 5969 ClassnfABITy = llvm::StructType::create(VMContext, "struct._class_t
"); 5970 ClassnfABITy->setBody(llvm::PointerType::getUnqual(ClassnfABITy), 5971 llvm::PointerType::getUnqual(ClassnfABITy), CachePtrTy, 5972 llvm::PointerType::getUnqual(ImpnfABITy), 5973 llvm::PointerType::getUnqual(ClassRonfABITy)); 5975 // LLVM for struct _class_t * 5976 ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy); 5978 // struct _category_t { 5979 // const char * const name; 5980 // struct _class_t *const cls; 5981 // const struct _method_list_t * const instance_methods; 5982 // const struct _method_list_t * const class_methods; 5983 // const struct _protocol_list_t * const protocols; 5984 // const struct _prop_list_t * const properties; 5985 // const struct _prop_list_t * const class_properties; 5986 // const uint32_t size; 5988 CategorynfABITy = llvm::StructType::create( 5989 "struct._category_t
", Int8PtrTy, ClassnfABIPtrTy, MethodListnfABIPtrTy, 5990 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, PropertyListPtrTy, 5991 PropertyListPtrTy, IntTy); 5993 // New types for nonfragile abi messaging. 5994 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 5995 ASTContext &Ctx = CGM.getContext(); 5997 // MessageRefTy - LLVM for: 5998 // struct _message_ref_t { 6003 // First the clang type for struct _message_ref_t 6004 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct, 6005 Ctx.getTranslationUnitDecl(), 6006 SourceLocation(), SourceLocation(), 6007 &Ctx.Idents.get("_message_ref_t
")); 6008 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 6009 nullptr, Ctx.VoidPtrTy, nullptr, nullptr, false, 6011 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 6012 nullptr, Ctx.getObjCSelType(), nullptr, nullptr, 6013 false, ICIS_NoInit)); 6014 RD->completeDefinition(); 6016 MessageRefCTy = Ctx.getTagDeclType(RD); 6017 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy); 6018 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy)); 6020 // MessageRefPtrTy - LLVM for struct _message_ref_t* 6021 MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy); 6023 // SuperMessageRefTy - LLVM for: 6024 // struct _super_message_ref_t { 6025 // SUPER_IMP messenger; 6028 SuperMessageRefTy = llvm::StructType::create("struct._super_message_ref_t
", 6029 ImpnfABITy, SelectorPtrTy); 6031 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t* 6032 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy); 6035 // struct objc_typeinfo { 6036 // const void** vtable; // objc_ehtype_vtable + 2 6037 // const char* name; // c++ typeinfo string 6040 EHTypeTy = llvm::StructType::create("struct._objc_typeinfo
", 6041 llvm::PointerType::getUnqual(Int8PtrTy), 6042 Int8PtrTy, ClassnfABIPtrTy); 6043 EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy); 6046 llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() { 6047 FinishNonFragileABIModule(); 6052 void CGObjCNonFragileABIMac::AddModuleClassList( 6053 ArrayRef<llvm::GlobalValue *> Container, StringRef SymbolName, 6054 StringRef SectionName) { 6055 unsigned NumClasses = Container.size(); 6060 SmallVector<llvm::Constant*, 8> Symbols(NumClasses); 6061 for (unsigned i=0; i<NumClasses; i++) 6062 Symbols[i] = llvm::ConstantExpr::getBitCast(Container[i], 6063 ObjCTypes.Int8PtrTy); 6064 llvm::Constant *Init = 6065 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy, 6069 // Section name is obtained by calling GetSectionName, which returns 6070 // sections in the __DATA segment on MachO. 6071 assert((!CGM.getTriple().isOSBinFormatMachO() || 6072 SectionName.startswith("__DATA
")) && 6073 "SectionName expected to start with __DATA on MachO
"); 6074 llvm::GlobalValue::LinkageTypes LT = 6075 getLinkageTypeForObjCMetadata(CGM, SectionName); 6076 llvm::GlobalVariable *GV = 6077 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, LT, Init, 6079 GV->setAlignment(CGM.getDataLayout().getABITypeAlignment(Init->getType())); 6080 GV->setSection(SectionName); 6081 CGM.addCompilerUsedGlobal(GV); 6084 void CGObjCNonFragileABIMac::FinishNonFragileABIModule() { 6085 // nonfragile abi has no module definition. 6087 // Build list of all implemented class addresses in array 6088 // L_OBJC_LABEL_CLASS_$. 6090 for (unsigned i=0, NumClasses=ImplementedClasses.size(); i<NumClasses; i++) { 6091 const ObjCInterfaceDecl *ID = ImplementedClasses[i]; 6093 if (ObjCImplementationDecl *IMP = ID->getImplementation()) 6094 // We are implementing a weak imported interface. Give it external linkage 6095 if (ID->isWeakImported() && !IMP->isWeakImported()) { 6096 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage); 6097 DefinedMetaClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage); 6101 AddModuleClassList(DefinedClasses, "OBJC_LABEL_CLASS_$
", 6102 GetSectionName("__objc_classlist
", 6103 "regular,no_dead_strip
")); 6105 AddModuleClassList(DefinedNonLazyClasses, "OBJC_LABEL_NONLAZY_CLASS_$
", 6106 GetSectionName("__objc_nlclslist
", 6107 "regular,no_dead_strip
")); 6109 // Build list of all implemented category addresses in array 6110 // L_OBJC_LABEL_CATEGORY_$. 6111 AddModuleClassList(DefinedCategories, "OBJC_LABEL_CATEGORY_$
", 6112 GetSectionName("__objc_catlist
", 6113 "regular,no_dead_strip
")); 6114 AddModuleClassList(DefinedStubCategories, "OBJC_LABEL_STUB_CATEGORY_$
", 6115 GetSectionName("__objc_catlist2
", 6116 "regular,no_dead_strip
")); 6117 AddModuleClassList(DefinedNonLazyCategories, "OBJC_LABEL_NONLAZY_CATEGORY_$
", 6118 GetSectionName("__objc_nlcatlist
", 6119 "regular,no_dead_strip
")); 6128 bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
6129 // At various points we've experimented with using vtable-based
6130 // dispatch for all methods.
6131 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
6132 case CodeGenOptions::Legacy:
6134 case CodeGenOptions::NonLegacy:
6136 case CodeGenOptions::Mixed:
6140 // If so, see whether this selector is in the white-list of things which must
6141 // use the new dispatch convention. We lazily build a dense set for this.
6142 if (VTableDispatchMethods.empty()) {
6143 VTableDispatchMethods.insert(GetNullarySelector("alloc
")); 6144 VTableDispatchMethods.insert(GetNullarySelector("class")); 6145 VTableDispatchMethods.insert(GetNullarySelector("self")); 6146 VTableDispatchMethods.insert(GetNullarySelector("isFlipped
")); 6147 VTableDispatchMethods.insert(GetNullarySelector("length")); 6148 VTableDispatchMethods.insert(GetNullarySelector("count
")); 6150 // These are vtable-based if GC is disabled. 6151 // Optimistically use vtable dispatch for hybrid compiles. 6152 if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) { 6153 VTableDispatchMethods.insert(GetNullarySelector("retain
")); 6154 VTableDispatchMethods.insert(GetNullarySelector("release
")); 6155 VTableDispatchMethods.insert(GetNullarySelector("autorelease
")); 6158 VTableDispatchMethods.insert(GetUnarySelector("allocWithZone
")); 6159 VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass
")); 6160 VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector
")); 6161 VTableDispatchMethods.insert(GetUnarySelector("objectForKey
")); 6162 VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex
")); 6163 VTableDispatchMethods.insert(GetUnarySelector("isEqualToString
")); 6164 VTableDispatchMethods.insert(GetUnarySelector("isEqual
")); 6166 // These are vtable-based if GC is enabled. 6167 // Optimistically use vtable dispatch for hybrid compiles. 6168 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) { 6169 VTableDispatchMethods.insert(GetNullarySelector("hash
")); 6170 VTableDispatchMethods.insert(GetUnarySelector("addObject
")); 6172 // "countByEnumeratingWithState:objects:count
" 6173 IdentifierInfo *KeyIdents[] = { 6174 &CGM.getContext().Idents.get("countByEnumeratingWithState
"), 6175 &CGM.getContext().Idents.get("objects
"), 6176 &CGM.getContext().Idents.get("count
") 6178 VTableDispatchMethods.insert( 6179 CGM.getContext().Selectors.getSelector(3, KeyIdents)); 6183 return VTableDispatchMethods.count(Sel); 6201 llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
6203 unsigned InstanceStart,
6204 unsigned InstanceSize,
6205 const ObjCImplementationDecl *ID) {
6206 std::string ClassName = ID->getObjCRuntimeNameAsString();
6208 CharUnits beginInstance = CharUnits::fromQuantity(InstanceStart);
6209 CharUnits endInstance = CharUnits::fromQuantity(InstanceSize);
6211 bool hasMRCWeak = false;
6212 if (CGM.getLangOpts().ObjCAutoRefCount)
6213 flags |= NonFragileABI_Class_CompiledByARC;
6214 else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))
6215 flags |= NonFragileABI_Class_HasMRCWeakIvars;
6217 ConstantInitBuilder builder(CGM);
6218 auto values = builder.beginStruct(ObjCTypes.ClassRonfABITy);
6220 values.addInt(ObjCTypes.IntTy, flags);
6221 values.addInt(ObjCTypes.IntTy, InstanceStart);
6222 values.addInt(ObjCTypes.IntTy, InstanceSize);
6223 values.add((flags & NonFragileABI_Class_Meta)
6224 ? GetIvarLayoutName(nullptr, ObjCTypes)
6225 : BuildStrongIvarLayout(ID, beginInstance, endInstance));
6226 values.add(GetClassName(ID->getObjCRuntimeNameAsString()));
6228 // const struct _method_list_t * const baseMethods;
6229 SmallVector<const ObjCMethodDecl*, 16> methods;
6230 if (flags & NonFragileABI_Class_Meta) {
6231 for (const auto *MD : ID->class_methods())
6232 methods.push_back(MD);
6234 for (const auto *MD : ID->instance_methods())
6235 methods.push_back(MD);
6237 for (const auto *PID : ID->property_impls()) {
6238 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){
6239 ObjCPropertyDecl *PD = PID->getPropertyDecl();
6241 if (auto MD = PD->getGetterMethodDecl())
6242 if (GetMethodDefinition(MD))
6243 methods.push_back(MD);
6244 if (auto MD = PD->getSetterMethodDecl())
6245 if (GetMethodDefinition(MD))
6246 methods.push_back(MD);
6251 values.add(emitMethodList(ID->getObjCRuntimeNameAsString(),
6252 (flags & NonFragileABI_Class_Meta)
6253 ? MethodListType::ClassMethods
6254 : MethodListType::InstanceMethods,
6257 const ObjCInterfaceDecl *OID = ID->getClassInterface();
6258 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer
"); 6259 values.add(EmitProtocolList("_OBJC_CLASS_PROTOCOLS_$_
" 6260 + OID->getObjCRuntimeNameAsString(), 6261 OID->all_referenced_protocol_begin(), 6262 OID->all_referenced_protocol_end())); 6264 if (flags & NonFragileABI_Class_Meta) { 6265 values.addNullPointer(ObjCTypes.IvarListnfABIPtrTy); 6266 values.add(GetIvarLayoutName(nullptr, ObjCTypes)); 6267 values.add(EmitPropertyList( 6268 "_OBJC_$_CLASS_PROP_LIST_
" + ID->getObjCRuntimeNameAsString(), 6269 ID, ID->getClassInterface(), ObjCTypes, true)); 6271 values.add(EmitIvarList(ID)); 6272 values.add(BuildWeakIvarLayout(ID, beginInstance, endInstance, hasMRCWeak)); 6273 values.add(EmitPropertyList( 6274 "_OBJC_$_PROP_LIST_
" + ID->getObjCRuntimeNameAsString(), 6275 ID, ID->getClassInterface(), ObjCTypes, false)); 6278 llvm::SmallString<64> roLabel; 6279 llvm::raw_svector_ostream(roLabel) 6280 << ((flags & NonFragileABI_Class_Meta) ? "_OBJC_METACLASS_RO_$_
" 6281 : "_OBJC_CLASS_RO_$_
") 6284 return finishAndCreateGlobal(values, roLabel, CGM); 6297 llvm::GlobalVariable *
6298 CGObjCNonFragileABIMac::BuildClassObject(const ObjCInterfaceDecl *CI,
6300 llvm::Constant *IsAGV,
6301 llvm::Constant *SuperClassGV,
6302 llvm::Constant *ClassRoGV,
6303 bool HiddenVisibility) {
6304 ConstantInitBuilder builder(CGM);
6305 auto values = builder.beginStruct(ObjCTypes.ClassnfABITy);
6308 values.add(SuperClassGV);
6310 values.addNullPointer(ObjCTypes.ClassnfABIPtrTy);
6312 values.add(ObjCEmptyCacheVar);
6313 values.add(ObjCEmptyVtableVar);
6314 values.add(ClassRoGV);
6316 llvm::GlobalVariable *GV =
6317 cast<llvm::GlobalVariable>(GetClassGlobal(CI, isMetaclass, ForDefinition));
6318 values.finishAndSetAsInitializer(GV);
6320 if (CGM.getTriple().isOSBinFormatMachO())
6321 GV->setSection("__DATA, __objc_data
"); 6323 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassnfABITy)); 6324 if (!CGM.getTriple().isOSBinFormatCOFF()) 6325 if (HiddenVisibility) 6326 GV->setVisibility(llvm::GlobalValue::HiddenVisibility); 6330 bool CGObjCNonFragileABIMac::ImplementationIsNonLazy( 6331 const ObjCImplDecl *OD) const { 6332 return OD->getClassMethod(GetNullarySelector("load
")) != nullptr || 6333 OD->getClassInterface()->hasAttr<ObjCNonLazyClassAttr>() || 6334 OD->hasAttr<ObjCNonLazyClassAttr>(); 6337 void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID, 6338 uint32_t &InstanceStart, 6339 uint32_t &InstanceSize) { 6340 const ASTRecordLayout &RL = 6341 CGM.getContext().getASTObjCImplementationLayout(OID); 6343 // InstanceSize is really instance end. 6344 InstanceSize = RL.getDataSize().getQuantity(); 6346 // If there are no fields, the start is the same as the end. 6347 if (!RL.getFieldCount()) 6348 InstanceStart = InstanceSize; 6350 InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth(); 6353 static llvm::GlobalValue::DLLStorageClassTypes getStorage(CodeGenModule &CGM, 6355 IdentifierInfo &II = CGM.getContext().Idents.get(Name); 6356 TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl(); 6357 DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl); 6359 const VarDecl *VD = nullptr; 6360 for (const auto &Result : DC->lookup(&II)) 6361 if ((VD = dyn_cast<VarDecl>(Result))) 6365 return llvm::GlobalValue::DLLImportStorageClass; 6366 if (VD->hasAttr<DLLExportAttr>()) 6367 return llvm::GlobalValue::DLLExportStorageClass; 6368 if (VD->hasAttr<DLLImportAttr>()) 6369 return llvm::GlobalValue::DLLImportStorageClass; 6370 return llvm::GlobalValue::DefaultStorageClass; 6373 void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { 6374 if (!ObjCEmptyCacheVar) { 6376 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CacheTy, false, 6377 llvm::GlobalValue::ExternalLinkage, nullptr, 6378 "_objc_empty_cache
"); 6379 if (CGM.getTriple().isOSBinFormatCOFF()) 6380 ObjCEmptyCacheVar->setDLLStorageClass(getStorage(CGM, "_objc_empty_cache
")); 6382 // Only OS X with deployment version <10.9 use the empty vtable symbol 6383 const llvm::Triple &Triple = CGM.getTarget().getTriple(); 6384 if (Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 9)) 6385 ObjCEmptyVtableVar = 6386 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ImpnfABITy, false, 6387 llvm::GlobalValue::ExternalLinkage, nullptr, 6388 "_objc_empty_vtable
"); 6390 ObjCEmptyVtableVar = 6391 llvm::ConstantPointerNull::get(ObjCTypes.ImpnfABITy->getPointerTo()); 6394 // FIXME: Is this correct (that meta class size is never computed)? 6395 uint32_t InstanceStart = 6396 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy); 6397 uint32_t InstanceSize = InstanceStart; 6398 uint32_t flags = NonFragileABI_Class_Meta; 6400 llvm::Constant *SuperClassGV, *IsAGV; 6402 const auto *CI = ID->getClassInterface(); 6403 assert(CI && "CGObjCNonFragileABIMac::GenerateClass -
class is 0");
6406 bool classIsHidden = (CGM.
getTriple().isOSBinFormatCOFF())
6407 ? !CI->hasAttr<DLLExportAttr>()
6420 if (!CI->getSuperClass()) {
6437 llvm::GlobalVariable *CLASS_RO_GV =
6438 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
6440 llvm::GlobalVariable *MetaTClass =
6441 BuildClassObject(CI,
true,
6442 IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden);
6444 DefinedMetaClasses.push_back(MetaTClass);
6467 if (!CI->getSuperClass()) {
6469 SuperClassGV =
nullptr;
6472 const auto *Super = CI->getSuperClass();
6476 GetClassSizeInfo(ID, InstanceStart, InstanceSize);
6478 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
6480 llvm::GlobalVariable *ClassMD =
6481 BuildClassObject(CI,
false,
6482 MetaTClass, SuperClassGV, CLASS_RO_GV, classIsHidden);
6484 DefinedClasses.push_back(ClassMD);
6485 ImplementedClasses.push_back(CI);
6488 if (ImplementationIsNonLazy(ID))
6489 DefinedNonLazyClasses.push_back(ClassMD);
6495 MethodDefinitions.clear();
6512 llvm::Constant *Init =
6513 llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD),
6514 ObjCTypes.getExternalProtocolPtrTy());
6516 std::string ProtocolName(
"_OBJC_PROTOCOL_REFERENCE_$_");
6521 llvm::GlobalVariable *PTGV = CGM.
getModule().getGlobalVariable(ProtocolName);
6524 PTGV =
new llvm::GlobalVariable(CGM.
getModule(), Init->getType(),
false,
6525 llvm::GlobalValue::WeakAnyLinkage, Init,
6527 PTGV->setSection(GetSectionName(
"__objc_protorefs",
6528 "coalesced,no_dead_strip"));
6531 if (!CGM.
getTriple().isOSBinFormatMachO())
6532 PTGV->setComdat(CGM.
getModule().getOrInsertComdat(ProtocolName));
6551 const char *Prefix =
"_OBJC_$_CATEGORY_";
6555 ExtCatName +=
"_$_";
6559 auto values = builder.
beginStruct(ObjCTypes.CategorynfABITy);
6563 std::string listName =
6568 for (
const auto *MD : OCD->
methods()) {
6570 instanceMethods.push_back(MD);
6572 classMethods.push_back(MD);
6576 values.add(emitMethodList(listName, MethodListType::CategoryInstanceMethods,
6578 values.add(emitMethodList(listName, MethodListType::CategoryClassMethods,
6587 values.add(EmitProtocolList(
"_OBJC_CATEGORY_PROTOCOLS_$_" 6592 values.add(EmitPropertyList(
"_OBJC_$_PROP_LIST_" + ExtName.str(),
6594 values.add(EmitPropertyList(
"_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(),
6597 values.addNullPointer(ObjCTypes.ProtocolListnfABIPtrTy);
6598 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
6599 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
6602 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.CategorynfABITy);
6603 values.addInt(ObjCTypes.IntTy, Size);
6605 llvm::GlobalVariable *GCATV =
6608 if (Interface->
hasAttr<ObjCClassStubAttr>())
6609 DefinedStubCategories.push_back(GCATV);
6611 DefinedCategories.push_back(GCATV);
6614 if (ImplementationIsNonLazy(OCD))
6615 DefinedNonLazyCategories.push_back(GCATV);
6617 MethodDefinitions.clear();
6632 auto method = builder.
beginStruct(ObjCTypes.MethodTy);
6633 method.addBitCast(GetMethodVarName(MD->
getSelector()),
6634 ObjCTypes.SelectorPtrTy);
6635 method.add(GetMethodVarType(MD));
6639 method.addNullPointer(ObjCTypes.Int8PtrTy);
6641 llvm::Function *fn = GetMethodDefinition(MD);
6642 assert(fn &&
"no definition for method?");
6643 method.addBitCast(fn, ObjCTypes.Int8PtrTy);
6646 method.finishAndAddTo(builder);
6661 if (methods.empty())
6662 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
6667 case MethodListType::CategoryInstanceMethods:
6668 prefix =
"_OBJC_$_CATEGORY_INSTANCE_METHODS_";
6669 forProtocol =
false;
6671 case MethodListType::CategoryClassMethods:
6672 prefix =
"_OBJC_$_CATEGORY_CLASS_METHODS_";
6673 forProtocol =
false;
6675 case MethodListType::InstanceMethods:
6676 prefix =
"_OBJC_$_INSTANCE_METHODS_";
6677 forProtocol =
false;
6679 case MethodListType::ClassMethods:
6680 prefix =
"_OBJC_$_CLASS_METHODS_";
6681 forProtocol =
false;
6684 case MethodListType::ProtocolInstanceMethods:
6685 prefix =
"_OBJC_$_PROTOCOL_INSTANCE_METHODS_";
6688 case MethodListType::ProtocolClassMethods:
6689 prefix =
"_OBJC_$_PROTOCOL_CLASS_METHODS_";
6692 case MethodListType::OptionalProtocolInstanceMethods:
6693 prefix =
"_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_";
6696 case MethodListType::OptionalProtocolClassMethods:
6697 prefix =
"_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_";
6706 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.MethodTy);
6707 values.addInt(ObjCTypes.IntTy, Size);
6709 values.addInt(ObjCTypes.IntTy, methods.size());
6710 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
6711 for (
auto MD : methods) {
6712 emitMethodConstant(methodArray, MD, forProtocol);
6714 methodArray.finishAndAddTo(values);
6718 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListnfABIPtrTy);
6723 llvm::GlobalVariable *
6731 llvm::GlobalVariable *IvarOffsetGV = CGM.
getModule().getGlobalVariable(Name);
6732 if (!IvarOffsetGV) {
6734 new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.IvarOffsetVarTy,
6736 nullptr, Name.str());
6737 if (CGM.
getTriple().isOSBinFormatCOFF()) {
6738 bool IsPrivateOrPackage =
6744 if (ContainingID->
hasAttr<DLLImportAttr>())
6746 ->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
6747 else if (ContainingID->
hasAttr<DLLExportAttr>() && !IsPrivateOrPackage)
6749 ->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
6752 return IvarOffsetGV;
6758 unsigned long int Offset) {
6759 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
6760 IvarOffsetGV->setInitializer(
6761 llvm::ConstantInt::get(ObjCTypes.IvarOffsetVarTy, Offset));
6762 IvarOffsetGV->setAlignment(
6763 CGM.
getDataLayout().getABITypeAlignment(ObjCTypes.IvarOffsetVarTy));
6765 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
6779 if (isClassLayoutKnownStatically(ID))
6780 IvarOffsetGV->setConstant(
true);
6782 if (CGM.
getTriple().isOSBinFormatMachO())
6783 IvarOffsetGV->setSection(
"__DATA, __objc_ivar");
6784 return IvarOffsetGV;
6804 llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
6809 ivarList.addInt(ObjCTypes.IntTy,
6810 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.IvarnfABITy));
6811 auto ivarCountSlot = ivarList.addPlaceholder();
6812 auto ivars = ivarList.beginArray(ObjCTypes.IvarnfABITy);
6815 assert(OID &&
"CGObjCNonFragileABIMac::EmitIvarList - null interface");
6822 if (!IVD->getDeclName())
6825 auto ivar = ivars.beginStruct(ObjCTypes.IvarnfABITy);
6827 ComputeIvarBaseOffset(CGM, ID, IVD)));
6828 ivar.add(GetMethodVarName(IVD->getIdentifier()));
6829 ivar.add(GetMethodVarType(IVD));
6832 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(FieldTy);
6834 IVD->getType().getTypePtr()) >> 3;
6835 Align = llvm::Log2_32(Align);
6836 ivar.addInt(ObjCTypes.IntTy, Align);
6842 ivar.addInt(ObjCTypes.IntTy, Size);
6843 ivar.finishAndAddTo(ivars);
6846 if (ivars.empty()) {
6849 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
6852 auto ivarCount = ivars.size();
6853 ivars.finishAndAddTo(ivarList);
6854 ivarList.fillPlaceholderWithInt(ivarCountSlot, ObjCTypes.IntTy, ivarCount);
6856 const char *Prefix =
"_OBJC_$_INSTANCE_VARIABLES_";
6860 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy);
6863 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(
6865 llvm::GlobalVariable *&Entry = Protocols[PD->
getIdentifier()];
6872 llvm::raw_svector_ostream(Protocol) <<
"_OBJC_PROTOCOL_$_" 6875 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolnfABITy,
6878 if (!CGM.
getTriple().isOSBinFormatMachO())
6879 Entry->setComdat(CGM.
getModule().getOrInsertComdat(Protocol));
6905 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
6907 llvm::GlobalVariable *Entry = Protocols[PD->
getIdentifier()];
6910 if (Entry && Entry->hasInitializer())
6915 "emitting protocol metadata without definition");
6918 auto methodLists = ProtocolMethodLists::get(PD);
6921 auto values = builder.
beginStruct(ObjCTypes.ProtocolnfABITy);
6924 values.addNullPointer(ObjCTypes.ObjectPtrTy);
6925 values.add(GetClassName(PD->getObjCRuntimeNameAsString()));
6926 values.add(EmitProtocolList(
"_OBJC_$_PROTOCOL_REFS_" 6927 + PD->getObjCRuntimeNameAsString(),
6928 PD->protocol_begin(),
6929 PD->protocol_end()));
6930 values.add(methodLists.emitMethodList(
this, PD,
6931 ProtocolMethodLists::RequiredInstanceMethods));
6932 values.add(methodLists.emitMethodList(
this, PD,
6933 ProtocolMethodLists::RequiredClassMethods));
6934 values.add(methodLists.emitMethodList(
this, PD,
6935 ProtocolMethodLists::OptionalInstanceMethods));
6936 values.add(methodLists.emitMethodList(
this, PD,
6937 ProtocolMethodLists::OptionalClassMethods));
6938 values.add(EmitPropertyList(
6939 "_OBJC_$_PROP_LIST_" + PD->getObjCRuntimeNameAsString(),
6940 nullptr, PD, ObjCTypes,
false));
6942 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
6943 values.addInt(ObjCTypes.IntTy, Size);
6944 values.addInt(ObjCTypes.IntTy, 0);
6945 values.add(EmitProtocolMethodTypes(
"_OBJC_$_PROTOCOL_METHOD_TYPES_" 6946 + PD->getObjCRuntimeNameAsString(),
6947 methodLists.emitExtendedTypesArray(
this),
6951 values.addNullPointer(ObjCTypes.Int8PtrTy);
6953 values.add(EmitPropertyList(
6954 "_OBJC_$_CLASS_PROP_LIST_" + PD->getObjCRuntimeNameAsString(),
6955 nullptr, PD, ObjCTypes,
true));
6959 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
6960 values.finishAndSetAsInitializer(Entry);
6963 llvm::raw_svector_ostream(symbolName)
6964 <<
"_OBJC_PROTOCOL_$_" << PD->getObjCRuntimeNameAsString();
6966 Entry = values.finishAndCreateGlobal(symbolName, CGM.
getPointerAlign(),
6968 llvm::GlobalValue::WeakAnyLinkage);
6969 if (!CGM.
getTriple().isOSBinFormatMachO())
6970 Entry->setComdat(CGM.
getModule().getOrInsertComdat(symbolName));
6972 Protocols[PD->getIdentifier()] = Entry;
6980 llvm::raw_svector_ostream(ProtocolRef) <<
"_OBJC_LABEL_PROTOCOL_$_" 6981 << PD->getObjCRuntimeNameAsString();
6983 llvm::GlobalVariable *PTGV =
6984 new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolnfABIPtrTy,
6985 false, llvm::GlobalValue::WeakAnyLinkage, Entry,
6987 if (!CGM.
getTriple().isOSBinFormatMachO())
6988 PTGV->setComdat(CGM.
getModule().getOrInsertComdat(ProtocolRef));
6990 CGM.
getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy));
6991 PTGV->setSection(GetSectionName(
"__objc_protolist",
6992 "coalesced,no_dead_strip"));
7007 CGObjCNonFragileABIMac::EmitProtocolList(Twine Name,
7014 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
7018 Name.toVector(TmpName);
7019 llvm::GlobalVariable *GV =
7020 CGM.
getModule().getGlobalVariable(TmpName.str(),
true);
7022 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy);
7026 auto countSlot = values.addPlaceholder();
7029 auto array = values.beginArray(ObjCTypes.ProtocolnfABIPtrTy);
7030 for (; begin != end; ++begin)
7031 array.add(GetProtocolRef(*begin));
7032 auto count = array.size();
7033 array.addNullPointer(ObjCTypes.ProtocolnfABIPtrTy);
7035 array.finishAndAddTo(values);
7036 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
7040 return llvm::ConstantExpr::getBitCast(GV,
7041 ObjCTypes.ProtocolListnfABIPtrTy);
7050 LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
7055 unsigned CVRQualifiers) {
7057 llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
7058 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
7067 if (isClassLayoutKnownStatically(Interface)) {
7068 IvarOffsetValue = llvm::ConstantInt::get(
7069 ObjCTypes.IvarOffsetVarTy,
7072 llvm::GlobalVariable *GV = ObjCIvarOffsetVariable(Interface, Ivar);
7075 if (IsIvarOffsetKnownIdempotent(CGF, Ivar))
7076 cast<llvm::LoadInst>(IvarOffsetValue)
7077 ->setMetadata(CGM.
getModule().getMDKindID(
"invariant.load"),
7078 llvm::MDNode::get(VMContext,
None));
7084 if (ObjCTypes.IvarOffsetVarTy == ObjCTypes.IntTy)
7085 IvarOffsetValue = CGF.
Builder.CreateIntCast(
7086 IvarOffsetValue, ObjCTypes.LongTy,
true,
"ivar.conv");
7087 return IvarOffsetValue;
7090 static void appendSelectorForMessageRefTable(std::string &buffer,
7097 for (
unsigned i = 0, e = selector.
getNumArgs();
i != e; ++
i) {
7135 args.insert(args.end(), formalArgs.begin(), formalArgs.end());
7137 MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);
7139 NullReturnState nullReturn;
7148 llvm::FunctionCallee fn =
nullptr;
7149 std::string messageRefName(
"_");
7152 fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
7153 messageRefName +=
"objc_msgSendSuper2_stret_fixup";
7155 nullReturn.init(CGF, arg0);
7156 fn = ObjCTypes.getMessageSendStretFixupFn();
7157 messageRefName +=
"objc_msgSend_stret_fixup";
7160 fn = ObjCTypes.getMessageSendFpretFixupFn();
7161 messageRefName +=
"objc_msgSend_fpret_fixup";
7164 fn = ObjCTypes.getMessageSendSuper2FixupFn();
7165 messageRefName +=
"objc_msgSendSuper2_fixup";
7167 fn = ObjCTypes.getMessageSendFixupFn();
7168 messageRefName +=
"objc_msgSend_fixup";
7171 assert(fn &&
"CGObjCNonFragileABIMac::EmitMessageSend");
7172 messageRefName +=
'_';
7176 appendSelectorForMessageRefTable(messageRefName, selector);
7178 llvm::GlobalVariable *messageRef
7179 = CGM.
getModule().getGlobalVariable(messageRefName);
7184 values.add(cast<llvm::Constant>(fn.getCallee()));
7185 values.add(GetMethodVarName(selector));
7186 messageRef = values.finishAndCreateGlobal(messageRefName,
7189 llvm::GlobalValue::WeakAnyLinkage);
7191 messageRef->setSection(GetSectionName(
"__objc_msgrefs",
"coalesced"));
7194 bool requiresnullCheck =
false;
7196 for (
const auto *ParamDecl : method->
parameters()) {
7197 if (ParamDecl->hasAttr<NSConsumedAttr>()) {
7198 if (!nullReturn.NullBB)
7199 nullReturn.init(CGF, arg0);
7200 requiresnullCheck =
true;
7220 return nullReturn.complete(CGF, returnSlot, result, resultType, formalArgs,
7221 requiresnullCheck ? method :
nullptr);
7234 return isVTableDispatchedSelector(Sel)
7235 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
7237 false, CallArgs, Method)
7238 : EmitMessageSend(CGF, Return, ResultType,
7239 EmitSelector(CGF, Sel),
7241 false, CallArgs, Method, Class, ObjCTypes);
7249 (metaclass ? getMetaclassSymbolPrefix() : getClassSymbolPrefix());
7255 && ID->
hasAttr<DLLImportAttr>());
7259 CGObjCNonFragileABIMac::GetClassGlobal(StringRef Name,
7261 bool Weak,
bool DLLImport) {
7262 llvm::GlobalValue::LinkageTypes L =
7263 Weak ? llvm::GlobalValue::ExternalWeakLinkage
7266 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name);
7267 if (!GV || GV->getType() != ObjCTypes.ClassnfABITy->getPointerTo()) {
7268 auto *NewGV =
new llvm::GlobalVariable(ObjCTypes.ClassnfABITy,
false, L,
7272 NewGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
7275 GV->replaceAllUsesWith(
7276 llvm::ConstantExpr::getBitCast(NewGV, GV->getType()));
7277 GV->eraseFromParent();
7280 CGM.
getModule().getGlobalList().push_back(GV);
7283 assert(GV->getLinkage() == L);
7288 CGObjCNonFragileABIMac::GetClassGlobalForClassRef(
const ObjCInterfaceDecl *ID) {
7289 llvm::Constant *ClassGV = GetClassGlobal(ID,
false,
7292 if (!ID->
hasAttr<ObjCClassStubAttr>())
7295 ClassGV = llvm::ConstantExpr::getPointerCast(ClassGV, ObjCTypes.Int8PtrTy);
7299 auto *Idx = llvm::ConstantInt::get(CGM.
Int32Ty, 1);
7300 return llvm::ConstantExpr::getGetElementPtr(CGM.
Int8Ty, ClassGV, Idx);
7306 llvm::GlobalVariable *Entry) {
7307 if (ID && ID->
hasAttr<ObjCClassStubAttr>()) {
7311 ObjCTypes.getLoadClassrefFn(), Entry,
"load_classref_result");
7322 llvm::GlobalVariable *&Entry = ClassReferences[II];
7325 llvm::Constant *ClassGV;
7327 ClassGV = GetClassGlobalForClassRef(ID);
7329 ClassGV = GetClassGlobal((getClassSymbolPrefix() + II->
getName()).str(),
7331 assert(ClassGV->getType() == ObjCTypes.ClassnfABIPtrTy &&
7332 "classref was emitted with the wrong type?");
7335 std::string SectionName =
7336 GetSectionName(
"__objc_classrefs",
"regular,no_dead_strip");
7337 Entry =
new llvm::GlobalVariable(
7338 CGM.
getModule(), ClassGV->getType(),
false,
7340 "OBJC_CLASSLIST_REFERENCES_$_");
7342 if (!ID || !ID->
hasAttr<ObjCClassStubAttr>())
7343 Entry->setSection(SectionName);
7348 return EmitLoadOfClassRef(CGF, ID, Entry);
7355 if (ID->
hasAttr<ObjCRuntimeVisibleAttr>())
7356 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
7361 llvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(
7364 return EmitClassRefFromId(CGF, II,
nullptr);
7370 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->
getIdentifier()];
7373 llvm::Constant *ClassGV = GetClassGlobalForClassRef(ID);
7374 std::string SectionName =
7375 GetSectionName(
"__objc_superrefs",
"regular,no_dead_strip");
7376 Entry =
new llvm::GlobalVariable(
7377 CGM.
getModule(), ClassGV->getType(),
false,
7379 "OBJC_CLASSLIST_SUP_REFS_$_");
7381 Entry->setSection(SectionName);
7385 return EmitLoadOfClassRef(CGF, ID, Entry);
7395 llvm::GlobalVariable * &Entry = MetaClassReferences[ID->
getIdentifier()];
7398 std::string SectionName =
7399 GetSectionName(
"__objc_superrefs",
"regular,no_dead_strip");
7400 Entry =
new llvm::GlobalVariable(
7401 CGM.
getModule(), ObjCTypes.ClassnfABIPtrTy,
false,
7403 "OBJC_CLASSLIST_SUP_REFS_$_");
7405 Entry->setSection(SectionName);
7419 assert(!isa<llvm::GlobalVariable>(ClassGV) ||
7420 cast<llvm::GlobalVariable>(ClassGV)->hasExternalWeakLinkage());
7423 return EmitClassRef(CGF, ID);
7435 bool isCategoryImpl,
7437 bool IsClassMessage,
7457 Target = EmitSuperClassRef(CGF, Class);
7466 return (isVTableDispatchedSelector(Sel))
7467 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
7468 ObjCSuper.
getPointer(), ObjCTypes.SuperPtrCTy,
7469 true, CallArgs, Method)
7470 : EmitMessageSend(CGF, Return, ResultType,
7471 EmitSelector(CGF, Sel),
7472 ObjCSuper.
getPointer(), ObjCTypes.SuperPtrCTy,
7473 true, CallArgs, Method, Class, ObjCTypes);
7478 Address Addr = EmitSelectorAddr(CGF, Sel);
7481 LI->setMetadata(CGM.
getModule().getMDKindID(
"invariant.load"),
7482 llvm::MDNode::get(VMContext,
None));
7488 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
7492 llvm::Constant *Casted =
7493 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
7494 ObjCTypes.SelectorPtrTy);
7495 std::string SectionName =
7496 GetSectionName(
"__objc_selrefs",
"literal_pointers,no_dead_strip");
7497 Entry =
new llvm::GlobalVariable(
7498 CGM.
getModule(), ObjCTypes.SelectorPtrTy,
false,
7500 "OBJC_SELECTOR_REFERENCES_");
7501 Entry->setExternallyInitialized(
true);
7502 Entry->setSection(SectionName);
7518 if (!isa<llvm::PointerType>(SrcTy)) {
7519 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(SrcTy);
7520 assert(Size <= 8 && "does not support size > 8
"); 7521 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 7522 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 7523 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 7525 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 7526 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 7527 llvm::Value *args[] = { src, dst.getPointer(), ivarOffset }; 7528 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args); 7534 void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
7535 CodeGen::CodeGenFunction &CGF,
7536 llvm::Value *src, Address dst) {
7537 llvm::Type * SrcTy = src->getType();
7538 if (!isa<llvm::PointerType>(SrcTy)) {
7539 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7540 assert(Size <= 8 && "does
not support size > 8
"); 7541 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 7542 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 7543 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 7545 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 7546 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 7547 llvm::Value *args[] = { src, dst.getPointer() }; 7548 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), 7549 args, "weakassign
"); 7552 void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable( 7553 CodeGen::CodeGenFunction &CGF, 7556 llvm::Value *Size) { 7557 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy); 7558 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy); 7559 llvm::Value *args[] = { DestPtr.getPointer(), SrcPtr.getPointer(), Size }; 7560 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args); 7566 llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(
7567 CodeGen::CodeGenFunction &CGF,
7568 Address AddrWeakObj) {
7569 llvm::Type *DestTy = AddrWeakObj.getElementType();
7570 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy);
7571 llvm::Value *read_weak =
7572 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(),
7573 AddrWeakObj.getPointer(), "weakread
"); 7574 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy); 7581 void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
7582 llvm::Value *src, Address dst) {
7583 llvm::Type * SrcTy = src->getType();
7584 if (!isa<llvm::PointerType>(SrcTy)) {
7585 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7586 assert(Size <= 8 && "does
not support size > 8
"); 7587 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 7588 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 7589 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 7591 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 7592 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 7593 llvm::Value *args[] = { src, dst.getPointer() }; 7594 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), 7595 args, "weakassign
"); 7601 void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
7602 llvm::Value *src, Address dst,
7604 llvm::Type * SrcTy = src->getType();
7605 if (!isa<llvm::PointerType>(SrcTy)) {
7606 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7607 assert(Size <= 8 && "does
not support size > 8
"); 7608 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 7609 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 7610 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 7612 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 7613 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 7614 llvm::Value *args[] = { src, dst.getPointer() }; 7616 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), 7617 args, "globalassign
"); 7619 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(), 7620 args, "threadlocalassign
"); 7624 CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 7625 const ObjCAtSynchronizedStmt &S) { 7626 EmitAtSynchronizedStmt(CGF, S, ObjCTypes.getSyncEnterFn(), 7627 ObjCTypes.getSyncExitFn()); 7631 CGObjCNonFragileABIMac::GetEHType(QualType T) { 7632 // There's a particular fixed type info for 'id'. 7633 if (T->isObjCIdType() || T->isObjCQualifiedIdType()) { 7634 auto *IDEHType = CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id
"); 7637 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false, 7638 llvm::GlobalValue::ExternalLinkage, nullptr, 7640 if (CGM.getTriple().isOSBinFormatCOFF()) 7641 IDEHType->setDLLStorageClass(getStorage(CGM, "OBJC_EHTYPE_id
")); 7646 // All other types should be Objective-C interface pointer types. 7647 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>(); 7648 assert(PT && "Invalid
@catch type.
"); 7650 const ObjCInterfaceType *IT = PT->getInterfaceType(); 7651 assert(IT && "Invalid
@catch type.
"); 7653 return GetInterfaceEHType(IT->getDecl(), NotForDefinition); 7656 void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, 7657 const ObjCAtTryStmt &S) { 7658 EmitTryCatchStmt(CGF, S, ObjCTypes.getObjCBeginCatchFn(), 7659 ObjCTypes.getObjCEndCatchFn(), 7660 ObjCTypes.getExceptionRethrowFn()); 7664 void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
7665 const ObjCAtThrowStmt &S,
7666 bool ClearInsertionPoint) {
7667 if (const Expr *ThrowExpr = S.getThrowExpr()) {
7668 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
7669 Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
7670 llvm::CallBase *Call =
7671 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception);
7672 Call->setDoesNotReturn();
7674 llvm::CallBase *Call =
7675 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionRethrowFn());
7676 Call->setDoesNotReturn();
7679 CGF.Builder.CreateUnreachable();
7680 if (ClearInsertionPoint)
7681 CGF.Builder.ClearInsertionPoint();
7685 CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
7686 ForDefinition_t IsForDefinition) {
7687 llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
7688 StringRef ClassName = ID->getObjCRuntimeNameAsString();
7690 // If we don't need a definition, return the entry if found or check
7691 // if we use an external reference.
7692 if (!IsForDefinition) {
7696 // If this type (or a super class) has the __objc_exception__
7697 // attribute, emit an external reference.
7698 if (hasObjCExceptionAttribute(CGM.getContext(), ID)) {
7699 std::string EHTypeName = ("OBJC_EHTYPE_$_
" + ClassName).str(); 7700 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, 7701 false, llvm::GlobalValue::ExternalLinkage, 7702 nullptr, EHTypeName); 7703 CGM.setGVProperties(Entry, ID); 7708 // Otherwise we need to either make a new entry or fill in the initializer. 7709 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition
"); 7711 std::string VTableName = "objc_ehtype_vtable
"; 7712 auto *VTableGV = CGM.getModule().getGlobalVariable(VTableName); 7715 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy, false, 7716 llvm::GlobalValue::ExternalLinkage, nullptr, 7718 if (CGM.getTriple().isOSBinFormatCOFF()) 7719 VTableGV->setDLLStorageClass(getStorage(CGM, VTableName)); 7722 llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2); 7723 ConstantInitBuilder builder(CGM); 7724 auto values = builder.beginStruct(ObjCTypes.EHTypeTy); 7726 llvm::ConstantExpr::getInBoundsGetElementPtr(VTableGV->getValueType(), 7727 VTableGV, VTableIdx)); 7728 values.add(GetClassName(ClassName)); 7729 values.add(GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition)); 7731 llvm::GlobalValue::LinkageTypes L = IsForDefinition 7732 ? llvm::GlobalValue::ExternalLinkage 7733 : llvm::GlobalValue::WeakAnyLinkage; 7735 values.finishAndSetAsInitializer(Entry); 7736 Entry->setAlignment(CGM.getPointerAlign().getQuantity()); 7738 Entry = values.finishAndCreateGlobal("OBJC_EHTYPE_$_
" + ClassName, 7739 CGM.getPointerAlign(), 7742 if (hasObjCExceptionAttribute(CGM.getContext(), ID)) 7743 CGM.setGVProperties(Entry, ID); 7745 assert(Entry->getLinkage() == L); 7747 if (!CGM.getTriple().isOSBinFormatCOFF()) 7748 if (ID->getVisibility() == HiddenVisibility) 7749 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility); 7751 if (IsForDefinition) 7752 if (CGM.getTriple().isOSBinFormatMachO()) 7753 Entry->setSection("__DATA,__objc_const
"); 7760 CodeGen::CGObjCRuntime * 7761 CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) { 7762 switch (CGM.getLangOpts().ObjCRuntime.getKind()) { 7763 case ObjCRuntime::FragileMacOSX: 7764 return new CGObjCMac(CGM); 7766 case ObjCRuntime::MacOSX: 7767 case ObjCRuntime::iOS: 7768 case ObjCRuntime::WatchOS: 7769 return new CGObjCNonFragileABIMac(CGM); 7771 case ObjCRuntime::GNUstep: 7772 case ObjCRuntime::GCC: 7773 case ObjCRuntime::ObjFW: 7774 llvm_unreachable("these runtimes are
not Mac runtimes
"); 7776 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.
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
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()
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.
static llvm::GlobalValue::LinkageTypes getLinkageTypeForObjCMetadata(CodeGenModule &CGM, StringRef Section)
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)
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
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.
CanQualType getCanonicalParamType(QualType T) const
Return the canonical parameter type corresponding to the specific potentially non-canonical one...
Represents a variable declaration or definition.
Objects with "hidden" visibility are not seen by the dynamic linker.
const T * getAs() const
Member-template getAs<specific type>'.
llvm::GlobalVariable * finishAndCreateGlobal(As &&...args)
Given that this builder was created by beginning an array or struct directly on a ConstantInitBuilder...
ObjCMethodDecl - Represents an instance or class method declaration.
QualType getObjCClassType() const
Represents the Objective-C Class type.
llvm::Value * getPointer() const
Defines the Objective-C statement AST node classes.
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
protocol_range protocols() const
Represents a parameter to a function.
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have...
void add(RValue rvalue, QualType type)
A jump destination is an abstract label, branching to which may require a jump out through normal cle...
llvm::Value * EmitObjCThrowOperand(const Expr *expr)
Class implementation was compiled under ARC.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Represents a struct/union/class.
uint64_t getPointerWidth(unsigned AddrSpace) const
Return the width of pointers on this target, for the specified address space.
One of these records is kept for each identifier that is lexed.
Represents a class type in Objective C.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ParmVarDecl *const * param_const_iterator
field_range fields() const
Class has non-trivial destructors, but zero-initialization is okay.
bool isObjCIdType() const
Represents a member of a struct/union/class.
protocol_iterator protocol_begin() const
CharUnits getSizeAlign() const
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.
__SIZE_TYPE__ size_t
The unsigned integer type of the result of the sizeof operator.
prop_range properties() const
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
bool isObjCQualifiedClassType() const
Has the exception attribute.
static std::string getBlockLayoutInfoString(const SmallVectorImpl< CGObjCCommonMac::RUN_SKIP > &RunSkipBlockVars, bool HasCopyDisposeHelpers)
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)
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
static llvm::GlobalVariable * finishAndCreateGlobal(ConstantInitBuilder::StructBuilder &Builder, const llvm::Twine &Name, CodeGenModule &CGM)
A helper function to create an internal or private global variable.
Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
QualType getObjCClassRedefinitionType() const
Retrieve the type that Class has been defined to, which may be different from the built-in Class if C...
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
unsigned getBitWidthValue(const ASTContext &Ctx) const
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void addCompilerUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.compiler.used metadata.
void ForceCleanup(std::initializer_list< llvm::Value **> ValuesToReload={})
Force the emission of cleanups now, instead of waiting until this object is destroyed.
Represents an Objective-C protocol declaration.
llvm::Constant * CreateRuntimeVariable(llvm::Type *Ty, StringRef Name)
Create a new runtime global variable with the specified type and name.
CharUnits getPointerAlign() const
typename ConstantInitBuilderTraits ::StructBuilder StructBuilder
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
Represents an ObjC class declaration.
QualType getReturnType() const
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface...
Address NormalCleanupDest
i32s containing the indexes of the cleanup destinations.
all_protocol_iterator all_referenced_protocol_end() const
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
QualType getObjCProtoType() const
Retrieve the type of the Objective-C Protocol class.
This object can be modified without requiring retains or releases.
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
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)
bool hasDefinition() const
Determine whether this protocol has a definition.
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.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
This represents one expression.
Defines the clang::LangOptions interface.
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
CharUnits getOffset() const
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
llvm::BasicBlock * getBlock() const
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
bool isObjCClassType() const
bool isObjCIdType() const
True if this is equivalent to the 'id' type, i.e.
Represents Objective-C's @synchronized statement.
ObjCInterfaceDecl * getSuperClass() const
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
llvm::LLVMContext & getLLVMContext()
bool needsCopyDisposeHelpers() const
bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI)
Return true iff the given type uses an argument slot when 'sret' is used as a return type...
llvm::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
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **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.
SmallVector< llvm::Value *, 8 > ObjCEHValueStack
ObjCEHValueStack - Stack of Objective-C exception values, used for rethrows.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const
Set visibility, dllimport/dllexport and dso_local.
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
const CGFunctionInfo & arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD)
Objective-C methods are C functions with some implicit parameters.
void EmitStmt(const Stmt *S, ArrayRef< const Attr *> Attrs=None)
EmitStmt - Emit the code for the statement.
static void PushProtocolProperties(llvm::SmallPtrSet< const IdentifierInfo *, 16 > &PropertySet, SmallVectorImpl< const ObjCPropertyDecl *> &Properties, const ObjCProtocolDecl *Proto, bool IsClassProperty)
static bool hasMRCWeakIvars(CodeGenModule &CGM, const ObjCImplementationDecl *ID)
For compatibility, we only want to set the "HasMRCWeakIvars" flag (and actually fill in a layout stri...
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
ObjCCategoryDecl - Represents a category declaration.
static bool hasWeakMember(QualType type)
bool isObjCObjectPointerType() const
Represents one property declaration in an Objective-C interface.
Class implementation was compiled under MRC and has MRC weak ivars.
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...
All available information about a concrete callee.
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)
The given basic block lies in the current EH scope, but may be a target of a potentially scope-crossi...
Assigning into this object requires a lifetime extension.
unsigned getPreferredTypeAlign(const Type *T) const
Return the "preferred" alignment of the specified type T for the current target, in bits...
bool ReturnTypeUsesFP2Ret(QualType ResultType)
Return true iff the given type uses 'fp2ret' when used as a return type.
ObjCImplementationDecl * getImplementation() const
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
ConstantAddress GetAddrOfConstantCString(const std::string &Str, const char *GlobalName=nullptr)
Returns a pointer to a character array containing the literal and a terminating '\0' character...
StringRef getName() const
Return the actual identifier string.
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type, returning the result.
void addUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.used metadata.
ObjCIvarDecl * getNextIvar()
bool isObjCGCWeak() const
true when Type is objc's weak.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
This class organizes the cross-function state that is used while generating LLVM code.
protocol_iterator protocol_end() const
StructBuilder beginStruct(llvm::StructType *ty=nullptr)
const ObjCInterfaceDecl * getClassInterface() const
static void addIfPresent(llvm::DenseSet< llvm::Value *> &S, Address V)
Dataflow Directional Tag Classes.
CharUnits getSize() const
getSize - Get the record size in characters.
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
ArrayRef< Capture > captures() const
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
int printf(__constant const char *st,...) __attribute__((format(printf
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.
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...
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false)
Create or return a runtime function declaration with the specified type and name. ...
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.
ASTImporterLookupTable & LT
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
CharUnits BlockHeaderForcedGapSize
Has a non-trivial constructor or destructor.
Represents Objective-C's @try ... @catch ... @finally statement.
protocol_iterator protocol_end() const
unsigned getNumCatchStmts() const
Retrieve the number of @catch statements in this try-catch-finally block.
StringLiteral - This represents a string literal expression, e.g.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
StringRef getName() const
getName - Get the name of identifier for the class interface associated with this implementation as a...
static RValue get(llvm::Value *V)
Visibility getVisibility() const
Determines the visibility of this entity.
const internal::VariadicDynCastAllOfMatcher< Decl, BlockDecl > blockDecl
Matches block declarations.
const VarDecl * getCatchParamDecl() const
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
std::string ObjCConstantStringClass
LValue - This represents an lvalue references.
Information for lazily generating a cleanup.
ObjCMethodDecl * getGetterMethodDecl() const
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
AccessControl getAccessControl() const
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
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