29 #include "llvm/ADT/CachedHashString.h" 30 #include "llvm/ADT/DenseSet.h" 31 #include "llvm/ADT/SetVector.h" 32 #include "llvm/ADT/SmallPtrSet.h" 33 #include "llvm/ADT/SmallString.h" 34 #include "llvm/IR/DataLayout.h" 35 #include "llvm/IR/InlineAsm.h" 36 #include "llvm/IR/IntrinsicInst.h" 37 #include "llvm/IR/LLVMContext.h" 38 #include "llvm/IR/Module.h" 39 #include "llvm/Support/ScopedPrinter.h" 40 #include "llvm/Support/raw_ostream.h" 43 using namespace clang;
44 using namespace CodeGen;
51 class ObjCCommonTypesHelper {
53 llvm::LLVMContext &VMContext;
63 llvm::FunctionCallee getMessageSendFn()
const {
66 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
67 return CGM.CreateRuntimeFunction(
68 llvm::FunctionType::get(ObjectPtrTy, params,
true),
"objc_msgSend",
69 llvm::AttributeList::get(CGM.getLLVMContext(),
70 llvm::AttributeList::FunctionIndex,
71 llvm::Attribute::NonLazyBind));
79 llvm::FunctionCallee getMessageSendStretFn()
const {
80 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
81 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy,
83 "objc_msgSend_stret");
91 llvm::FunctionCallee getMessageSendFpretFn()
const {
92 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
93 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.DoubleTy,
95 "objc_msgSend_fpret");
103 llvm::FunctionCallee getMessageSendFp2retFn()
const {
104 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
105 llvm::Type *longDoubleType = llvm::Type::getX86_FP80Ty(VMContext);
107 llvm::StructType::get(longDoubleType, longDoubleType);
109 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(resultType,
111 "objc_msgSend_fp2ret");
119 llvm::FunctionCallee getMessageSendSuperFn()
const {
120 llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
121 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
123 "objc_msgSendSuper");
130 llvm::FunctionCallee getMessageSendSuperFn2()
const {
131 llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
132 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
134 "objc_msgSendSuper2");
141 llvm::FunctionCallee getMessageSendSuperStretFn()
const {
142 llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
143 return CGM.CreateRuntimeFunction(
144 llvm::FunctionType::get(CGM.VoidTy, params,
true),
145 "objc_msgSendSuper_stret");
152 llvm::FunctionCallee getMessageSendSuperStretFn2()
const {
153 llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
154 return CGM.CreateRuntimeFunction(
155 llvm::FunctionType::get(CGM.VoidTy, params,
true),
156 "objc_msgSendSuper2_stret");
159 llvm::FunctionCallee getMessageSendSuperFpretFn()
const {
161 return getMessageSendSuperFn();
164 llvm::FunctionCallee getMessageSendSuperFpretFn2()
const {
166 return getMessageSendSuperFn2();
173 llvm::IntegerType *ShortTy, *IntTy, *LongTy;
174 llvm::PointerType *Int8PtrTy, *Int8PtrPtrTy;
178 llvm::PointerType *ObjectPtrTy;
181 llvm::PointerType *PtrObjectPtrTy;
184 llvm::PointerType *SelectorPtrTy;
193 if (!ExternalProtocolPtrTy) {
199 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
202 return ExternalProtocolPtrTy;
211 llvm::StructType *SuperTy;
213 llvm::PointerType *SuperPtrTy;
217 llvm::StructType *PropertyTy;
221 llvm::StructType *PropertyListTy;
223 llvm::PointerType *PropertyListPtrTy;
226 llvm::StructType *MethodTy;
231 llvm::PointerType *CachePtrTy;
233 llvm::FunctionCallee getGetPropertyFn() {
242 llvm::FunctionType *FTy =
248 llvm::FunctionCallee getSetPropertyFn() {
261 llvm::FunctionType *FTy =
267 llvm::FunctionCallee getOptimizedSetPropertyFn(
bool atomic,
bool copy) {
282 Params.push_back(IdType);
283 Params.push_back(SelType);
284 Params.push_back(IdType);
286 llvm::FunctionType *FTy =
291 name =
"objc_setProperty_atomic_copy";
292 else if (atomic && !copy)
293 name =
"objc_setProperty_atomic";
294 else if (!atomic && copy)
295 name =
"objc_setProperty_nonatomic_copy";
297 name =
"objc_setProperty_nonatomic";
302 llvm::FunctionCallee getCopyStructFn() {
310 Params.push_back(Ctx.
BoolTy);
311 Params.push_back(Ctx.
BoolTy);
312 llvm::FunctionType *FTy =
322 llvm::FunctionCallee getCppAtomicObjectFunction() {
330 llvm::FunctionType *FTy =
336 llvm::FunctionCallee getEnumerationMutationFn() {
342 llvm::FunctionType *FTy =
348 llvm::FunctionCallee getLookUpClassFn() {
355 llvm::FunctionType *FTy =
363 llvm::FunctionCallee getGcReadWeakFn() {
365 llvm::Type *args[] = { ObjectPtrTy->getPointerTo() };
366 llvm::FunctionType *FTy =
367 llvm::FunctionType::get(ObjectPtrTy, args,
false);
372 llvm::FunctionCallee getGcAssignWeakFn() {
374 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
375 llvm::FunctionType *FTy =
376 llvm::FunctionType::get(ObjectPtrTy, args,
false);
381 llvm::FunctionCallee getGcAssignGlobalFn() {
383 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
384 llvm::FunctionType *FTy =
385 llvm::FunctionType::get(ObjectPtrTy, args,
false);
390 llvm::FunctionCallee getGcAssignThreadLocalFn() {
392 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
393 llvm::FunctionType *FTy =
394 llvm::FunctionType::get(ObjectPtrTy, args,
false);
399 llvm::FunctionCallee getGcAssignIvarFn() {
401 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo(),
403 llvm::FunctionType *FTy =
404 llvm::FunctionType::get(ObjectPtrTy, args,
false);
409 llvm::FunctionCallee GcMemmoveCollectableFn() {
411 llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, LongTy };
412 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, args,
false);
417 llvm::FunctionCallee getGcAssignStrongCastFn() {
419 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
420 llvm::FunctionType *FTy =
421 llvm::FunctionType::get(ObjectPtrTy, args,
false);
426 llvm::FunctionCallee getExceptionThrowFn() {
429 llvm::FunctionType *FTy =
430 llvm::FunctionType::get(CGM.
VoidTy, args,
false);
435 llvm::FunctionCallee getExceptionRethrowFn() {
437 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
442 llvm::FunctionCallee getSyncEnterFn() {
445 llvm::FunctionType *FTy =
446 llvm::FunctionType::get(CGM.
IntTy, args,
false);
451 llvm::FunctionCallee getSyncExitFn() {
454 llvm::FunctionType *FTy =
455 llvm::FunctionType::get(CGM.
IntTy, args,
false);
459 llvm::FunctionCallee getSendFn(
bool IsSuper)
const {
460 return IsSuper ? getMessageSendSuperFn() : getMessageSendFn();
463 llvm::FunctionCallee getSendFn2(
bool IsSuper)
const {
464 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();
467 llvm::FunctionCallee getSendStretFn(
bool IsSuper)
const {
468 return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();
471 llvm::FunctionCallee getSendStretFn2(
bool IsSuper)
const {
472 return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();
475 llvm::FunctionCallee getSendFpretFn(
bool IsSuper)
const {
476 return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();
479 llvm::FunctionCallee getSendFpretFn2(
bool IsSuper)
const {
480 return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();
483 llvm::FunctionCallee getSendFp2retFn(
bool IsSuper)
const {
484 return IsSuper ? getMessageSendSuperFn() : getMessageSendFp2retFn();
487 llvm::FunctionCallee getSendFp2RetFn2(
bool IsSuper)
const {
488 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFp2retFn();
496 class ObjCTypesHelper :
public ObjCCommonTypesHelper {
499 llvm::StructType *SymtabTy;
501 llvm::PointerType *SymtabPtrTy;
503 llvm::StructType *ModuleTy;
506 llvm::StructType *ProtocolTy;
508 llvm::PointerType *ProtocolPtrTy;
511 llvm::StructType *ProtocolExtensionTy;
514 llvm::PointerType *ProtocolExtensionPtrTy;
517 llvm::StructType *MethodDescriptionTy;
520 llvm::StructType *MethodDescriptionListTy;
523 llvm::PointerType *MethodDescriptionListPtrTy;
525 llvm::StructType *ProtocolListTy;
527 llvm::PointerType *ProtocolListPtrTy;
529 llvm::StructType *CategoryTy;
531 llvm::StructType *ClassTy;
533 llvm::PointerType *ClassPtrTy;
535 llvm::StructType *ClassExtensionTy;
537 llvm::PointerType *ClassExtensionPtrTy;
539 llvm::StructType *IvarTy;
541 llvm::StructType *IvarListTy;
543 llvm::PointerType *IvarListPtrTy;
545 llvm::StructType *MethodListTy;
547 llvm::PointerType *MethodListPtrTy;
550 llvm::StructType *ExceptionDataTy;
553 llvm::FunctionCallee getExceptionTryEnterFn() {
554 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
556 llvm::FunctionType::get(CGM.
VoidTy, params,
false),
557 "objc_exception_try_enter");
561 llvm::FunctionCallee getExceptionTryExitFn() {
562 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
564 llvm::FunctionType::get(CGM.
VoidTy, params,
false),
565 "objc_exception_try_exit");
569 llvm::FunctionCallee getExceptionExtractFn() {
570 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
573 "objc_exception_extract");
577 llvm::FunctionCallee getExceptionMatchFn() {
578 llvm::Type *params[] = { ClassPtrTy, ObjectPtrTy };
580 llvm::FunctionType::get(CGM.
Int32Ty, params,
false),
581 "objc_exception_match");
585 llvm::FunctionCallee getSetJmpFn() {
589 llvm::FunctionType::get(CGM.
Int32Ty, params,
false),
"_setjmp",
591 llvm::AttributeList::FunctionIndex,
592 llvm::Attribute::NonLazyBind));
601 class ObjCNonFragileABITypesHelper :
public ObjCCommonTypesHelper {
604 llvm::StructType *MethodListnfABITy;
607 llvm::PointerType *MethodListnfABIPtrTy;
610 llvm::StructType *ProtocolnfABITy;
613 llvm::PointerType *ProtocolnfABIPtrTy;
616 llvm::StructType *ProtocolListnfABITy;
619 llvm::PointerType *ProtocolListnfABIPtrTy;
622 llvm::StructType *ClassnfABITy;
625 llvm::PointerType *ClassnfABIPtrTy;
628 llvm::StructType *IvarnfABITy;
631 llvm::StructType *IvarListnfABITy;
634 llvm::PointerType *IvarListnfABIPtrTy;
637 llvm::StructType *ClassRonfABITy;
640 llvm::PointerType *ImpnfABITy;
643 llvm::StructType *CategorynfABITy;
652 llvm::StructType *MessageRefTy;
666 llvm::StructType *SuperMessageRefTy;
669 llvm::PointerType *SuperMessageRefPtrTy;
671 llvm::FunctionCallee getMessageSendFixupFn() {
673 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
676 "objc_msgSend_fixup");
679 llvm::FunctionCallee getMessageSendFpretFixupFn() {
681 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
684 "objc_msgSend_fpret_fixup");
687 llvm::FunctionCallee getMessageSendStretFixupFn() {
689 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
692 "objc_msgSend_stret_fixup");
695 llvm::FunctionCallee getMessageSendSuper2FixupFn() {
698 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
701 "objc_msgSendSuper2_fixup");
704 llvm::FunctionCallee getMessageSendSuper2StretFixupFn() {
707 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
710 "objc_msgSendSuper2_stret_fixup");
713 llvm::FunctionCallee getObjCEndCatchFn() {
718 llvm::FunctionCallee getObjCBeginCatchFn() {
730 llvm::FunctionCallee getLoadClassrefFn()
const {
738 llvm::FunctionType::get(ClassnfABIPtrTy, params,
false),
741 llvm::AttributeList::FunctionIndex,
742 {llvm::Attribute::NonLazyBind,
743 llvm::Attribute::ReadNone,
744 llvm::Attribute::NoUnwind}));
745 if (!CGM.
getTriple().isOSBinFormatCOFF())
746 cast<llvm::Function>(F.getCallee())->setLinkage(
747 llvm::Function::ExternalWeakLinkage);
752 llvm::StructType *EHTypeTy;
771 SKIP_SCAN(
unsigned _skip = 0,
unsigned _scan = 0)
772 : skip(_skip), scan(_scan) {}
779 enum BLOCK_LAYOUT_OPCODE {
786 BLOCK_LAYOUT_OPERATOR = 0,
792 BLOCK_LAYOUT_NON_OBJECT_BYTES = 1,
797 BLOCK_LAYOUT_NON_OBJECT_WORDS = 2,
801 BLOCK_LAYOUT_STRONG = 3,
804 BLOCK_LAYOUT_BYREF = 4,
808 BLOCK_LAYOUT_WEAK = 5,
812 BLOCK_LAYOUT_UNRETAINED = 6
829 enum BLOCK_LAYOUT_OPCODE opcode;
832 RUN_SKIP(
enum BLOCK_LAYOUT_OPCODE
Opcode = BLOCK_LAYOUT_OPERATOR,
835 : opcode(
Opcode), block_var_bytepos(BytePos), block_var_size(Size) {}
838 bool operator<(
const RUN_SKIP &b)
const {
839 return block_var_bytepos < b.block_var_bytepos;
844 llvm::LLVMContext &VMContext;
853 llvm::SetVector<IdentifierInfo*> LazySymbols;
859 llvm::SetVector<IdentifierInfo*> DefinedSymbols;
862 llvm::StringMap<llvm::GlobalVariable*> ClassNames;
865 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
872 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
876 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
880 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> DirectMethodDefinitions;
883 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
886 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
889 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
894 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
920 llvm::WeakTrackingVH ConstantStringClassRef;
923 llvm::StructType *NSConstantStringType =
nullptr;
925 llvm::StringMap<llvm::GlobalVariable *> NSConstantStringMap;
932 bool ignoreCategoryNamespace =
false);
936 llvm::Constant *GetMethodVarName(
Selector Sel);
944 bool Extended =
false);
945 llvm::Constant *GetMethodVarType(
const FieldDecl *D);
953 const Decl *Container);
958 llvm::Constant *GetClassName(StringRef RuntimeName);
972 bool forStrongLayout,
978 return BuildIvarLayout(OI, beginOffset, endOffset,
true,
false);
984 bool hasMRCWeakIvars) {
985 return BuildIvarLayout(OI, beginOffset, endOffset,
false, hasMRCWeakIvars);
990 void UpdateRunSkipBlockVars(
bool IsByref,
995 void BuildRCBlockVarRecordLayout(
const RecordType *RT,
997 bool ByrefLayout=
false);
999 void BuildRCRecordLayout(
const llvm::StructLayout *RecLayout,
1007 llvm::Constant *getBitmapBlockLayout(
bool ComputeByrefLayout);
1012 const ObjCCommonTypesHelper &ObjCTypes);
1016 llvm::Constant *EmitPropertyList(Twine Name,
1017 const Decl *Container,
1019 const ObjCCommonTypesHelper &ObjCTypes,
1020 bool IsClassProperty);
1024 llvm::Constant *EmitProtocolMethodTypes(Twine Name,
1026 const ObjCCommonTypesHelper &ObjCTypes);
1037 ObjCCommonTypesHelper &ObjCTypes);
1039 std::string GetSectionName(StringRef Section, StringRef MachOAttributes);
1056 llvm::GlobalVariable *CreateMetadataVar(Twine Name,
1060 llvm::GlobalVariable *CreateMetadataVar(Twine Name,
1061 llvm::Constant *Init,
1065 llvm::GlobalVariable *CreateCStringLiteral(StringRef Name,
1067 bool ForceNonFragileABI =
false,
1068 bool NullTerminate =
true);
1081 const ObjCCommonTypesHelper &ObjCTypes);
1085 void EmitImageInfo();
1091 bool isNonFragileABI()
const {
1092 return ObjCABI == 2;
1104 void GenerateDirectMethodPrologue(
CodeGenFunction &CGF, llvm::Function *Fn,
1119 virtual llvm::Constant *GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD)=0;
1121 virtual llvm::Constant *getNSConstantStringClassRef() = 0;
1140 CategoryInstanceMethods,
1141 CategoryClassMethods,
1144 ProtocolInstanceMethods,
1145 ProtocolClassMethods,
1146 OptionalProtocolInstanceMethods,
1147 OptionalProtocolClassMethods,
1152 class ProtocolMethodLists {
1155 RequiredInstanceMethods,
1156 RequiredClassMethods,
1157 OptionalInstanceMethods,
1158 OptionalClassMethods
1161 NumProtocolMethodLists = 4
1166 case RequiredInstanceMethods:
1167 return MethodListType::ProtocolInstanceMethods;
1168 case RequiredClassMethods:
1169 return MethodListType::ProtocolClassMethods;
1170 case OptionalInstanceMethods:
1171 return MethodListType::OptionalProtocolInstanceMethods;
1172 case OptionalClassMethods:
1173 return MethodListType::OptionalProtocolClassMethods;
1175 llvm_unreachable(
"bad kind");
1181 ProtocolMethodLists result;
1183 for (
auto MD : PD->methods()) {
1184 size_t index = (2 *
size_t(MD->isOptional()))
1185 + (
size_t(MD->isClassMethod()));
1186 result.Methods[index].push_back(MD);
1192 template <
class Self>
1203 for (
auto &list : Methods) {
1204 for (
auto MD : list) {
1205 result.push_back(self->GetMethodVarType(MD,
true));
1212 template <
class Self>
1216 getMethodListKind(kind), Methods[
kind]);
1222 class CGObjCMac :
public CGObjCCommonMac {
1224 friend ProtocolMethodLists;
1226 ObjCTypesHelper ObjCTypes;
1230 void EmitModuleInfo();
1234 llvm::Constant *EmitModuleSymbols();
1238 void FinishModule();
1277 llvm::Constant *Protocols,
1308 const ProtocolMethodLists &methodLists);
1312 llvm::Constant *EmitProtocolList(Twine Name,
1324 llvm::Constant *getNSConstantStringClassRef()
override;
1326 llvm::Function *ModuleInitFunction()
override;
1355 llvm::Constant *GetEHType(
QualType T)
override;
1366 llvm::FunctionCallee GetPropertyGetFunction()
override;
1367 llvm::FunctionCallee GetPropertySetFunction()
override;
1368 llvm::FunctionCallee GetOptimizedPropertySetFunction(
bool atomic,
1369 bool copy)
override;
1370 llvm::FunctionCallee GetGetStructFunction()
override;
1371 llvm::FunctionCallee GetSetStructFunction()
override;
1372 llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override;
1373 llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override;
1374 llvm::FunctionCallee EnumerationMutationFunction()
override;
1382 bool ClearInsertionPoint=
true)
override;
1384 Address AddrWeakObj)
override;
1389 bool threadlocal =
false)
override;
1401 unsigned CVRQualifiers)
override;
1407 class CGObjCNonFragileABIMac :
public CGObjCCommonMac {
1409 friend ProtocolMethodLists;
1410 ObjCNonFragileABITypesHelper ObjCTypes;
1411 llvm::GlobalVariable* ObjCEmptyCacheVar;
1412 llvm::Constant* ObjCEmptyVtableVar;
1415 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences;
1418 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences;
1421 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences;
1428 std::vector<llvm::GlobalValue*> DefinedMetaClasses;
1432 bool isVTableDispatchedSelector(
Selector Sel);
1436 void FinishNonFragileABIModule();
1441 StringRef SymbolName, StringRef SectionName);
1443 llvm::GlobalVariable * BuildClassRoTInitializer(
unsigned flags,
1444 unsigned InstanceStart,
1445 unsigned InstanceSize,
1449 llvm::Constant *IsAGV,
1450 llvm::Constant *SuperClassGV,
1451 llvm::Constant *ClassRoGV,
1472 unsigned long int offset);
1487 llvm::Constant *EmitProtocolList(Twine Name,
1503 llvm::Constant *GetClassGlobal(StringRef Name,
1505 bool Weak =
false,
bool DLLImport =
false);
1514 llvm::GlobalVariable *Entry);
1540 llvm::GlobalVariable * ObjCIvarOffsetVariable(
1554 StringRef getMetaclassSymbolPrefix()
const {
return "OBJC_METACLASS_$_"; }
1556 StringRef getClassSymbolPrefix()
const {
return "OBJC_CLASS_$_"; }
1559 uint32_t &InstanceStart,
1560 uint32_t &InstanceSize);
1575 bool ImplementationIsNonLazy(
const ObjCImplDecl *OD)
const;
1594 dyn_cast_or_null<ObjCMethodDecl>(CGF.
CurFuncDecl))
1613 llvm::Constant *getNSConstantStringClassRef()
override;
1615 llvm::Function *ModuleInitFunction()
override;
1637 {
return EmitSelector(CGF, Sel); }
1639 {
return EmitSelectorAddr(Sel); }
1645 {
return EmitSelector(CGF, Method->
getSelector()); }
1656 llvm::Constant *GetEHType(
QualType T)
override;
1658 llvm::FunctionCallee GetPropertyGetFunction()
override {
1659 return ObjCTypes.getGetPropertyFn();
1661 llvm::FunctionCallee GetPropertySetFunction()
override {
1662 return ObjCTypes.getSetPropertyFn();
1665 llvm::FunctionCallee GetOptimizedPropertySetFunction(
bool atomic,
1666 bool copy)
override {
1667 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
1670 llvm::FunctionCallee GetSetStructFunction()
override {
1671 return ObjCTypes.getCopyStructFn();
1674 llvm::FunctionCallee GetGetStructFunction()
override {
1675 return ObjCTypes.getCopyStructFn();
1678 llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override {
1679 return ObjCTypes.getCppAtomicObjectFunction();
1682 llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override {
1683 return ObjCTypes.getCppAtomicObjectFunction();
1686 llvm::FunctionCallee EnumerationMutationFunction()
override {
1687 return ObjCTypes.getEnumerationMutationFn();
1695 bool ClearInsertionPoint=
true)
override;
1697 Address AddrWeakObj)
override;
1702 bool threadlocal =
false)
override;
1713 unsigned CVRQualifiers)
override;
1721 struct NullReturnState {
1722 llvm::BasicBlock *NullBB;
1723 NullReturnState() : NullBB(
nullptr) {}
1736 CGF.
Builder.CreateCondBr(isNull, NullBB, callBB);
1751 if (!NullBB)
return result;
1755 llvm::BasicBlock *contBB =
nullptr;
1758 llvm::BasicBlock *callBB = CGF.
Builder.GetInsertBlock();
1769 CallArgList::const_iterator I = CallArgs.begin();
1771 e = Method->
param_end(); i != e; ++i, ++I) {
1773 if (ParamDecl->
hasAttr<NSConsumedAttr>()) {
1774 RValue RV = I->getRValue(CGF);
1776 "NullReturnState::complete - arg not on object");
1783 assert(CGF.
Builder.GetInsertBlock() == NullBB);
1802 llvm::PHINode *phi = CGF.
Builder.CreatePHI(null->getType(), 2);
1804 phi->addIncoming(null, NullBB);
1813 assert(result.
isAggregate() &&
"null init of non-aggregate result?");
1825 llvm::Type *scalarTy = callResult.first->getType();
1826 llvm::Constant *scalarZero = llvm::Constant::getNullValue(scalarTy);
1829 llvm::PHINode *real = CGF.
Builder.CreatePHI(scalarTy, 2);
1830 real->addIncoming(callResult.first, callBB);
1831 real->addIncoming(scalarZero, NullBB);
1832 llvm::PHINode *imag = CGF.
Builder.CreatePHI(scalarTy, 2);
1833 imag->addIncoming(callResult.second, callBB);
1834 imag->addIncoming(scalarZero, NullBB);
1845 llvm::GlobalVariable *C,
unsigned idx0,
1848 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),
1849 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)
1851 return llvm::ConstantExpr::getGetElementPtr(C->getValueType(), C, Idxs);
1858 if (OID->
hasAttr<ObjCExceptionAttr>())
1865 static llvm::GlobalValue::LinkageTypes
1867 if (CGM.
getTriple().isOSBinFormatMachO() &&
1868 (Section.empty() || Section.startswith(
"__DATA")))
1870 return llvm::GlobalValue::PrivateLinkage;
1874 static llvm::GlobalVariable *
1877 std::string SectionName;
1878 if (CGM.
getTriple().isOSBinFormatMachO())
1879 SectionName =
"__DATA, __objc_const";
1880 auto *GV = Builder.finishAndCreateGlobal(
1883 GV->setSection(SectionName);
1899 return EmitClassRef(CGF, ID);
1904 return EmitSelector(CGF, Sel);
1907 return EmitSelectorAddr(Sel);
1914 llvm::Constant *CGObjCMac::GetEHType(
QualType T) {
1928 llvm_unreachable(
"asking for catch type for ObjC type in fragile runtime");
1951 CGObjCCommonMac::GenerateConstantString(
const StringLiteral *SL) {
1954 : GenerateConstantNSString(SL));
1957 static llvm::StringMapEntry<llvm::GlobalVariable *> &
1960 StringRef String = Literal->
getString();
1961 StringLength = String.size();
1962 return *Map.insert(std::make_pair(String,
nullptr)).first;
1965 llvm::Constant *CGObjCMac::getNSConstantStringClassRef() {
1967 return cast<llvm::Constant>(
V);
1971 StringClass.empty() ?
"_NSConstantStringClassReference" 1972 :
"_" + StringClass +
"ClassReference";
1976 auto V = llvm::ConstantExpr::getBitCast(GV, CGM.
IntTy->getPointerTo());
1977 ConstantStringClassRef =
V;
1981 llvm::Constant *CGObjCNonFragileABIMac::getNSConstantStringClassRef() {
1983 return cast<llvm::Constant>(
V);
1987 StringClass.empty() ?
"OBJC_CLASS_$_NSConstantString" 1988 :
"OBJC_CLASS_$_" + StringClass;
1992 auto V = llvm::ConstantExpr::getBitCast(GV, CGM.
IntTy->getPointerTo());
1994 ConstantStringClassRef =
V;
1999 CGObjCCommonMac::GenerateConstantNSString(
const StringLiteral *Literal) {
2000 unsigned StringLength = 0;
2001 llvm::StringMapEntry<llvm::GlobalVariable *> &Entry =
2004 if (
auto *C = Entry.second)
2008 llvm::Constant *Class = getNSConstantStringClassRef();
2011 if (!NSConstantStringType) {
2012 NSConstantStringType =
2017 },
"struct.__builtin_NSString");
2021 auto Fields = Builder.beginStruct(NSConstantStringType);
2028 llvm::ConstantDataArray::getString(VMContext, Entry.first());
2030 llvm::GlobalValue::LinkageTypes
Linkage = llvm::GlobalValue::PrivateLinkage;
2031 bool isConstant = !CGM.
getLangOpts().WritableStrings;
2033 auto *GV =
new llvm::GlobalVariable(CGM.
getModule(), C->getType(), isConstant,
2035 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2042 Fields.addInt(CGM.
IntTy, StringLength);
2046 GV = Fields.finishAndCreateGlobal(
"_unnamed_nsstring_", Alignment,
2048 llvm::GlobalVariable::PrivateLinkage);
2049 const char *NSStringSection =
"__OBJC,__cstring_object,regular,no_dead_strip";
2050 const char *NSStringNonFragileABISection =
2051 "__DATA,__objc_stringobj,regular,no_dead_strip";
2054 ? NSStringNonFragileABISection
2074 bool isCategoryImpl,
2076 bool IsClassMessage,
2091 if (IsClassMessage) {
2092 if (isCategoryImpl) {
2103 llvm::Constant *MetaClassPtr = EmitMetaClassRef(Class);
2110 }
else if (isCategoryImpl)
2123 return EmitMessageSend(CGF, Return, ResultType, Sel, ObjCSuper.
getPointer(),
2124 ObjCTypes.SuperPtrCTy,
true, CallArgs, Method, Class,
2137 return EmitMessageSend(CGF, Return, ResultType, Sel, Receiver,
2139 Method, Class, ObjCTypes);
2162 const ObjCCommonTypesHelper &ObjCTypes) {
2171 SelValue = llvm::UndefValue::get(Types.
ConvertType(selTy));
2173 SelValue = GetSelector(CGF, Sel);
2184 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2189 "Result type mismatch!");
2191 bool ReceiverCanBeNull =
true;
2196 ReceiverCanBeNull =
false;
2200 }
else if (ClassReceiver && Method && Method->
isClassMethod()) {
2205 }
else if (
auto CurMethod =
2206 dyn_cast_or_null<ObjCMethodDecl>(CGF.
CurCodeDecl)) {
2207 auto Self = CurMethod->getSelfDecl();
2208 if (Self->getType().isConstQualified()) {
2209 if (
auto LI = dyn_cast<llvm::LoadInst>(Arg0->stripPointerCasts())) {
2211 if (SelfAddr == LI->getPointerOperand()) {
2212 ReceiverCanBeNull =
false;
2218 bool RequiresNullCheck =
false;
2220 llvm::FunctionCallee Fn =
nullptr;
2224 if (ReceiverCanBeNull) RequiresNullCheck =
true;
2225 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
2226 : ObjCTypes.getSendStretFn(IsSuper);
2228 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
2229 : ObjCTypes.getSendFpretFn(IsSuper);
2231 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)
2232 : ObjCTypes.getSendFp2retFn(IsSuper);
2237 RequiresNullCheck =
true;
2238 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
2239 : ObjCTypes.getSendFn(IsSuper);
2243 llvm::Constant *BitcastFn = cast<llvm::Constant>(
2249 RequiresNullCheck =
false;
2252 if (!RequiresNullCheck && CGM.
getLangOpts().ObjCAutoRefCount && Method) {
2253 for (
const auto *ParamDecl : Method->
parameters()) {
2254 if (ParamDecl->hasAttr<NSConsumedAttr>()) {
2255 RequiresNullCheck =
true;
2261 NullReturnState nullReturn;
2262 if (RequiresNullCheck) {
2263 nullReturn.init(CGF, Arg0);
2266 llvm::CallBase *CallSite;
2268 RValue rvalue = CGF.
EmitCall(MSI.CallInfo, Callee, Return, ActualArgs,
2273 if (Method && Method->
hasAttr<NoReturnAttr>() && !ReceiverCanBeNull) {
2274 CallSite->setDoesNotReturn();
2277 return nullReturn.complete(CGF, Return, rvalue, ResultType, CallArgs,
2278 RequiresNullCheck ? Method :
nullptr);
2282 bool pointee =
false) {
2295 switch (ownership) {
2302 llvm_unreachable(
"bad objc ownership");
2321 uint64_t SizeInWords;
2322 IvarInfo(
CharUnits offset, uint64_t sizeInWords)
2323 :
Offset(offset), SizeInWords(sizeInWords) {}
2326 bool operator<(
const IvarInfo &other)
const {
2327 return Offset < other.Offset;
2332 class IvarLayoutBuilder {
2343 bool ForStrongLayout;
2346 bool IsDisordered =
false;
2352 CharUnits instanceEnd,
bool forStrongLayout)
2353 : CGM(CGM), InstanceBegin(instanceBegin), InstanceEnd(instanceEnd),
2354 ForStrongLayout(forStrongLayout) {
2359 template <
class Iterator,
class GetOffsetFn>
2360 void visitAggregate(Iterator begin, Iterator end,
2362 const GetOffsetFn &getOffset);
2370 bool hasBitmapData()
const {
return !IvarsInfo.empty(); }
2372 llvm::Constant *buildBitmap(CGObjCCommonMac &CGObjC,
2376 const unsigned char *s = buffer.data();
2377 for (
unsigned i = 0, e = buffer.size(); i < e; i++)
2379 printf(
"0x0%x%s", s[i], s[i] != 0 ?
", " :
"");
2381 printf(
"0x%x%s", s[i], s[i] != 0 ?
", " :
"");
2387 llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(
CodeGenModule &CGM,
2390 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2397 builder.visitBlock(blockInfo);
2399 if (!builder.hasBitmapData())
2403 llvm::Constant *C = builder.buildBitmap(*
this, buffer);
2404 if (CGM.
getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
2405 printf(
"\n block variable layout for block: ");
2406 builder.dump(buffer);
2412 void IvarLayoutBuilder::visitBlock(
const CGBlockInfo &blockInfo) {
2425 for (
const auto &CI : blockDecl->
captures()) {
2426 const VarDecl *variable = CI.getVariable();
2438 if (fieldOffset < lastFieldOffset)
2439 IsDisordered =
true;
2440 lastFieldOffset = fieldOffset;
2444 IvarsInfo.push_back(IvarInfo(fieldOffset, 1));
2448 assert(!type->
isArrayType() &&
"array variable should not be caught");
2450 visitRecord(record, fieldOffset);
2459 IvarsInfo.push_back(IvarInfo(fieldOffset, 1));
2484 void CGObjCCommonMac::UpdateRunSkipBlockVars(
bool IsByref,
2490 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset,
2493 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset,
2496 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset,
2499 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset,
2502 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES,
2507 void CGObjCCommonMac::BuildRCRecordLayout(
const llvm::StructLayout *RecLayout,
2512 bool IsUnion = (RD && RD->
isUnion());
2515 const FieldDecl *LastFieldBitfieldOrUnnamed =
nullptr;
2519 if (RecFields.empty())
2523 for (
unsigned i = 0, e = RecFields.size(); i != e; ++i) {
2533 LastFieldBitfieldOrUnnamed = Field;
2534 LastBitfieldOrUnnamedOffset = FieldOffset;
2538 LastFieldBitfieldOrUnnamed =
nullptr;
2545 BytePos + FieldOffset, HasUnion);
2550 auto *CArray = cast<ConstantArrayType>(Array);
2551 uint64_t ElCount = CArray->getSize().getZExtValue();
2552 assert(CArray &&
"only array with known element size is supported");
2553 FQT = CArray->getElementType();
2555 auto *CArray = cast<ConstantArrayType>(Array);
2556 ElCount *= CArray->getSize().getZExtValue();
2557 FQT = CArray->getElementType();
2560 int OldIndex = RunSkipBlockVars.size() - 1;
2562 BuildRCBlockVarRecordLayout(RT, BytePos + FieldOffset,
2568 for (
int FirstIndex = RunSkipBlockVars.size() - 1 ;ElIx < ElCount; ElIx++) {
2570 for (
int i = OldIndex+1; i <= FirstIndex; ++i)
2571 RunSkipBlockVars.push_back(
2572 RUN_SKIP(RunSkipBlockVars[i].opcode,
2573 RunSkipBlockVars[i].block_var_bytepos + Size*ElIx,
2574 RunSkipBlockVars[i].block_var_size));
2582 if (UnionIvarSize > MaxUnionSize) {
2583 MaxUnionSize = UnionIvarSize;
2585 MaxFieldOffset = FieldOffset;
2588 UpdateRunSkipBlockVars(
false,
2589 getBlockCaptureLifetime(FQT, ByrefLayout),
2590 BytePos + FieldOffset,
2595 if (LastFieldBitfieldOrUnnamed) {
2596 if (LastFieldBitfieldOrUnnamed->
isBitField()) {
2598 uint64_t BitFieldSize
2600 unsigned UnsSize = (BitFieldSize / ByteSizeInBits) +
2601 ((BitFieldSize % ByteSizeInBits) != 0);
2603 Size += LastBitfieldOrUnnamedOffset;
2604 UpdateRunSkipBlockVars(
false,
2605 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
2607 BytePos + LastBitfieldOrUnnamedOffset,
2610 assert(!LastFieldBitfieldOrUnnamed->
getIdentifier() &&
"Expected unnamed");
2614 UpdateRunSkipBlockVars(
false,
2615 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
2617 BytePos + LastBitfieldOrUnnamedOffset,
2623 UpdateRunSkipBlockVars(
false,
2624 getBlockCaptureLifetime(MaxField->
getType(), ByrefLayout),
2625 BytePos + MaxFieldOffset,
2629 void CGObjCCommonMac::BuildRCBlockVarRecordLayout(
const RecordType *RT,
2636 const llvm::StructLayout *RecLayout =
2637 CGM.
getDataLayout().getStructLayout(cast<llvm::StructType>(Ty));
2639 BuildRCRecordLayout(RecLayout, RD, Fields, BytePos, HasUnion, ByrefLayout);
2651 uint64_t CGObjCCommonMac::InlineLayoutInstruction(
2653 uint64_t Result = 0;
2654 if (Layout.size() <= 3) {
2655 unsigned size = Layout.size();
2656 unsigned strong_word_count = 0, byref_word_count=0, weak_word_count=0;
2658 enum BLOCK_LAYOUT_OPCODE opcode ;
2662 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2663 if (opcode == BLOCK_LAYOUT_STRONG)
2664 strong_word_count = (inst & 0xF)+1;
2668 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2669 if (opcode == BLOCK_LAYOUT_BYREF)
2670 byref_word_count = (inst & 0xF)+1;
2674 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2675 if (opcode == BLOCK_LAYOUT_WEAK)
2676 weak_word_count = (inst & 0xF)+1;
2683 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2684 if (opcode == BLOCK_LAYOUT_STRONG) {
2685 strong_word_count = (inst & 0xF)+1;
2687 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2688 if (opcode == BLOCK_LAYOUT_BYREF)
2689 byref_word_count = (inst & 0xF)+1;
2690 else if (opcode == BLOCK_LAYOUT_WEAK)
2691 weak_word_count = (inst & 0xF)+1;
2695 else if (opcode == BLOCK_LAYOUT_BYREF) {
2696 byref_word_count = (inst & 0xF)+1;
2698 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2699 if (opcode == BLOCK_LAYOUT_WEAK)
2700 weak_word_count = (inst & 0xF)+1;
2710 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2711 if (opcode == BLOCK_LAYOUT_STRONG)
2712 strong_word_count = (inst & 0xF)+1;
2713 else if (opcode == BLOCK_LAYOUT_BYREF)
2714 byref_word_count = (inst & 0xF)+1;
2715 else if (opcode == BLOCK_LAYOUT_WEAK)
2716 weak_word_count = (inst & 0xF)+1;
2728 if (strong_word_count == 16 || byref_word_count == 16 || weak_word_count == 16)
2732 (strong_word_count != 0) + (byref_word_count != 0) + (weak_word_count != 0);
2734 if (size == count) {
2735 if (strong_word_count)
2736 Result = strong_word_count;
2738 if (byref_word_count)
2739 Result += byref_word_count;
2741 if (weak_word_count)
2742 Result += weak_word_count;
2748 llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(
bool ComputeByrefLayout) {
2749 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2750 if (RunSkipBlockVars.empty())
2754 unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2758 llvm::array_pod_sort(RunSkipBlockVars.begin(), RunSkipBlockVars.end());
2761 unsigned size = RunSkipBlockVars.size();
2762 for (
unsigned i = 0; i < size; i++) {
2763 enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode;
2764 CharUnits start_byte_pos = RunSkipBlockVars[i].block_var_bytepos;
2765 CharUnits end_byte_pos = start_byte_pos;
2768 if (opcode == RunSkipBlockVars[j].opcode) {
2769 end_byte_pos = RunSkipBlockVars[j++].block_var_bytepos;
2776 end_byte_pos - start_byte_pos + RunSkipBlockVars[j-1].block_var_size;
2779 RunSkipBlockVars[j].block_var_bytepos -
2780 RunSkipBlockVars[j-1].block_var_bytepos - RunSkipBlockVars[j-1].block_var_size;
2781 size_in_bytes += gap;
2784 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) {
2785 residue_in_bytes = size_in_bytes % WordSizeInBytes;
2786 size_in_bytes -= residue_in_bytes;
2787 opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS;
2790 unsigned size_in_words = size_in_bytes.
getQuantity() / WordSizeInBytes;
2791 while (size_in_words >= 16) {
2794 unsigned char inst = (opcode << 4) | 0xf;
2795 Layout.push_back(inst);
2796 size_in_words -= 16;
2798 if (size_in_words > 0) {
2801 unsigned char inst = (opcode << 4) | (size_in_words-1);
2802 Layout.push_back(inst);
2805 unsigned char inst =
2806 (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) | (residue_in_bytes.
getQuantity()-1);
2807 Layout.push_back(inst);
2811 while (!Layout.empty()) {
2812 unsigned char inst = Layout.back();
2813 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2814 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES || opcode == BLOCK_LAYOUT_NON_OBJECT_WORDS)
2820 uint64_t Result = InlineLayoutInstruction(Layout);
2824 if (ComputeByrefLayout)
2825 printf(
"\n Inline BYREF variable layout: ");
2827 printf(
"\n Inline block variable layout: ");
2828 printf(
"0x0%" PRIx64
"", Result);
2829 if (
auto numStrong = (Result & 0xF00) >> 8)
2830 printf(
", BL_STRONG:%d", (
int) numStrong);
2831 if (
auto numByref = (Result & 0x0F0) >> 4)
2832 printf(
", BL_BYREF:%d", (
int) numByref);
2833 if (
auto numWeak = (Result & 0x00F) >> 0)
2834 printf(
", BL_WEAK:%d", (
int) numWeak);
2835 printf(
", BL_OPERATOR:0\n");
2837 return llvm::ConstantInt::get(CGM.
IntPtrTy, Result);
2840 unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0;
2841 Layout.push_back(inst);
2843 for (
unsigned i = 0, e = Layout.size(); i != e; i++)
2844 BitMap += Layout[i];
2847 if (ComputeByrefLayout)
2848 printf(
"\n Byref variable layout: ");
2850 printf(
"\n Block variable layout: ");
2851 for (
unsigned i = 0, e = BitMap.size(); i != e; i++) {
2852 unsigned char inst = BitMap[i];
2853 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2856 case BLOCK_LAYOUT_OPERATOR:
2860 case BLOCK_LAYOUT_NON_OBJECT_BYTES:
2861 printf(
"BL_NON_OBJECT_BYTES:");
2863 case BLOCK_LAYOUT_NON_OBJECT_WORDS:
2864 printf(
"BL_NON_OBJECT_WORD:");
2866 case BLOCK_LAYOUT_STRONG:
2869 case BLOCK_LAYOUT_BYREF:
2872 case BLOCK_LAYOUT_WEAK:
2875 case BLOCK_LAYOUT_UNRETAINED:
2876 printf(
"BL_UNRETAINED:");
2881 printf(
"%d", (inst & 0xf) + delta);
2889 auto *Entry = CreateCStringLiteral(BitMap, ObjCLabelType::ClassName,
2897 bool HasCopyDisposeHelpers) {
2899 for (
const CGObjCCommonMac::RUN_SKIP &R : RunSkipBlockVars) {
2900 if (R.opcode == CGObjCCommonMac::BLOCK_LAYOUT_UNRETAINED) {
2904 }
else if (HasCopyDisposeHelpers) {
2912 case CGObjCCommonMac::BLOCK_LAYOUT_STRONG:
2915 case CGObjCCommonMac::BLOCK_LAYOUT_BYREF:
2918 case CGObjCCommonMac::BLOCK_LAYOUT_WEAK:
2925 Str += llvm::to_string(R.block_var_bytepos.getQuantity());
2926 Str +=
"l" + llvm::to_string(R.block_var_size.getQuantity());
2931 void CGObjCCommonMac::fillRunSkipBlockVars(
CodeGenModule &CGM,
2935 RunSkipBlockVars.clear();
2936 bool hasUnion =
false;
2940 unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2945 const llvm::StructLayout *layout =
2955 for (
const auto &CI : blockDecl->
captures()) {
2956 const VarDecl *variable = CI.getVariable();
2967 assert(!type->
isArrayType() &&
"array variable should not be caught");
2970 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion);
2978 UpdateRunSkipBlockVars(CI.isByRef(), getBlockCaptureLifetime(type,
false),
2979 fieldOffset, fieldSize);
2986 fillRunSkipBlockVars(CGM, blockInfo);
2987 return getBitmapBlockLayout(
false);
2990 std::string CGObjCCommonMac::getRCBlockLayoutStr(
CodeGenModule &CGM,
2992 fillRunSkipBlockVars(CGM, blockInfo);
3000 assert(!T->
isArrayType() &&
"__block array variable should not be caught");
3002 RunSkipBlockVars.clear();
3003 bool hasUnion =
false;
3005 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion,
true );
3006 llvm::Constant *Result = getBitmapBlockLayout(
true);
3007 if (isa<llvm::ConstantInt>(Result))
3008 Result = llvm::ConstantExpr::getIntToPtr(Result, CGM.
Int8PtrTy);
3011 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
3021 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
3022 ObjCTypes.getExternalProtocolPtrTy());
3034 GetOrEmitProtocol(PD);
3037 llvm::Constant *CGObjCCommonMac::GetProtocolRef(
const ObjCProtocolDecl *PD) {
3039 return GetOrEmitProtocol(PD);
3041 return GetOrEmitProtocolRef(PD);
3044 llvm::Value *CGObjCCommonMac::EmitClassRefViaRuntime(
3047 ObjCCommonTypesHelper &ObjCTypes) {
3048 llvm::FunctionCallee lookUpClassFn = ObjCTypes.getLookUpClassFn();
3058 llvm::CallInst *call = CGF.
Builder.CreateCall(lookUpClassFn, className);
3059 call->setDoesNotThrow();
3076 llvm::GlobalVariable *Entry = Protocols[PD->
getIdentifier()];
3079 if (Entry && Entry->hasInitializer())
3091 auto methodLists = ProtocolMethodLists::get(PD);
3094 auto values = builder.
beginStruct(ObjCTypes.ProtocolTy);
3095 values.add(EmitProtocolExtension(PD, methodLists));
3097 values.add(EmitProtocolList(
"OBJC_PROTOCOL_REFS_" + PD->
getName(),
3099 values.add(methodLists.emitMethodList(
this, PD,
3100 ProtocolMethodLists::RequiredInstanceMethods));
3101 values.add(methodLists.emitMethodList(
this, PD,
3102 ProtocolMethodLists::RequiredClassMethods));
3106 assert(Entry->hasPrivateLinkage());
3107 values.finishAndSetAsInitializer(Entry);
3109 Entry = values.finishAndCreateGlobal(
"OBJC_PROTOCOL_" + PD->
getName(),
3112 llvm::GlobalValue::PrivateLinkage);
3113 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
3122 llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD) {
3123 llvm::GlobalVariable *&Entry = Protocols[PD->
getIdentifier()];
3129 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolTy,
3130 false, llvm::GlobalValue::PrivateLinkage,
3131 nullptr,
"OBJC_PROTOCOL_" + PD->
getName());
3132 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
3134 Entry->setAlignment(llvm::Align(4));
3152 const ProtocolMethodLists &methodLists) {
3153 auto optInstanceMethods =
3154 methodLists.emitMethodList(
this, PD,
3155 ProtocolMethodLists::OptionalInstanceMethods);
3156 auto optClassMethods =
3157 methodLists.emitMethodList(
this, PD,
3158 ProtocolMethodLists::OptionalClassMethods);
3160 auto extendedMethodTypes =
3161 EmitProtocolMethodTypes(
"OBJC_PROTOCOL_METHOD_TYPES_" + PD->
getName(),
3162 methodLists.emitExtendedTypesArray(
this),
3165 auto instanceProperties =
3166 EmitPropertyList(
"OBJC_$_PROP_PROTO_LIST_" + PD->
getName(),
nullptr, PD,
3168 auto classProperties =
3169 EmitPropertyList(
"OBJC_$_CLASS_PROP_PROTO_LIST_" + PD->
getName(),
nullptr,
3170 PD, ObjCTypes,
true);
3173 if (optInstanceMethods->isNullValue() &&
3174 optClassMethods->isNullValue() &&
3175 extendedMethodTypes->isNullValue() &&
3176 instanceProperties->isNullValue() &&
3177 classProperties->isNullValue()) {
3178 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
3182 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
3185 auto values = builder.
beginStruct(ObjCTypes.ProtocolExtensionTy);
3186 values.addInt(ObjCTypes.IntTy, size);
3187 values.add(optInstanceMethods);
3188 values.add(optClassMethods);
3189 values.add(instanceProperties);
3190 values.add(extendedMethodTypes);
3191 values.add(classProperties);
3194 return CreateMetadataVar(
"_OBJC_PROTOCOLEXT_" + PD->
getName(), values,
3206 CGObjCMac::EmitProtocolList(Twine name,
3211 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
3217 values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
3220 auto countSlot = values.addPlaceholder();
3222 auto refsArray = values.beginArray(ObjCTypes.ProtocolPtrTy);
3223 for (; begin != end; ++begin) {
3224 refsArray.add(GetProtocolRef(*begin));
3226 auto count = refsArray.size();
3229 refsArray.addNullPointer(ObjCTypes.ProtocolPtrTy);
3231 refsArray.finishAndAddTo(values);
3232 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
3235 if (CGM.
getTriple().isOSBinFormatMachO())
3236 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3238 llvm::GlobalVariable *GV =
3239 CreateMetadataVar(name, values, section, CGM.
getPointerAlign(),
false);
3240 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
3247 bool IsClassProperty) {
3249 if (IsClassProperty != PD->isClassProperty())
3253 Properties.push_back(PD);
3272 llvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name,
3273 const Decl *Container,
3275 const ObjCCommonTypesHelper &ObjCTypes,
3276 bool IsClassProperty) {
3277 if (IsClassProperty) {
3281 if ((Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 11)) ||
3282 (Triple.isiOS() && Triple.isOSVersionLT(9)))
3283 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3287 llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
3292 if (IsClassProperty != PD->isClassProperty())
3295 Properties.push_back(PD);
3299 if (IsClassProperty != PD->isClassProperty())
3305 Properties.push_back(PD);
3309 for (
const auto *
P : OID->all_referenced_protocols())
3313 for (
const auto *
P : CD->protocols())
3318 if (Properties.empty())
3319 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3321 unsigned propertySize =
3326 values.addInt(ObjCTypes.IntTy, propertySize);
3327 values.addInt(ObjCTypes.IntTy, Properties.size());
3328 auto propertiesArray = values.beginArray(ObjCTypes.PropertyTy);
3329 for (
auto PD : Properties) {
3330 if (PD->isDirectProperty())
3332 auto property = propertiesArray.beginStruct(ObjCTypes.PropertyTy);
3334 property.add(GetPropertyTypeString(PD, Container));
3335 property.finishAndAddTo(propertiesArray);
3337 propertiesArray.finishAndAddTo(values);
3340 if (CGM.
getTriple().isOSBinFormatMachO())
3341 Section = (ObjCABI == 2) ?
"__DATA, __objc_const" 3342 :
"__OBJC,__property,regular,no_dead_strip";
3344 llvm::GlobalVariable *GV =
3345 CreateMetadataVar(Name, values, Section, CGM.
getPointerAlign(),
true);
3346 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy);
3350 CGObjCCommonMac::EmitProtocolMethodTypes(Twine Name,
3352 const ObjCCommonTypesHelper &ObjCTypes) {
3354 if (MethodTypes.empty())
3355 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy);
3357 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
3358 MethodTypes.size());
3359 llvm::Constant *Init = llvm::ConstantArray::get(AT, MethodTypes);
3362 if (CGM.
getTriple().isOSBinFormatMachO() && ObjCABI == 2)
3363 Section =
"__DATA, __objc_const";
3365 llvm::GlobalVariable *GV =
3367 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.Int8PtrPtrTy);
3383 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.CategoryTy);
3394 llvm::raw_svector_ostream(ExtName) << Interface->
getName() <<
'_' 3398 auto Values = Builder.
beginStruct(ObjCTypes.CategoryTy);
3406 for (
const auto *MD : OCD->
methods()) {
3407 if (!MD->isDirectMethod())
3408 Methods[
unsigned(MD->isClassMethod())].push_back(MD);
3411 Values.add(GetClassName(OCD->
getName()));
3415 Values.add(emitMethodList(ExtName, MethodListType::CategoryInstanceMethods,
3416 Methods[InstanceMethods]));
3417 Values.add(emitMethodList(ExtName, MethodListType::CategoryClassMethods,
3418 Methods[ClassMethods]));
3421 EmitProtocolList(
"OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
3424 Values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
3426 Values.addInt(ObjCTypes.IntTy, Size);
3430 Values.add(EmitPropertyList(
"_OBJC_$_PROP_LIST_" + ExtName.str(),
3432 Values.add(EmitPropertyList(
"_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(),
3435 Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
3436 Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
3439 llvm::GlobalVariable *GV =
3440 CreateMetadataVar(
"OBJC_CATEGORY_" + ExtName.str(), Values,
3441 "__OBJC,__category,regular,no_dead_strip",
3443 DefinedCategories.push_back(GV);
3444 DefinedCategoryNames.insert(llvm::CachedHashString(ExtName));
3446 MethodDefinitions.clear();
3506 for (
auto field : recType->getDecl()->fields()) {
3555 DefinedSymbols.insert(RuntimeName);
3561 llvm::Constant *Protocols =
3562 EmitProtocolList(
"OBJC_CLASS_PROTOCOLS_" + ID->
getName(),
3569 bool hasMRCWeak =
false;
3589 for (
const auto *MD : ID->
methods()) {
3590 if (!MD->isDirectMethod())
3591 Methods[
unsigned(MD->isClassMethod())].push_back(MD);
3596 if (PID->getPropertyDecl()->isDirectProperty())
3599 if (GetMethodDefinition(MD))
3600 Methods[InstanceMethods].push_back(MD);
3602 if (GetMethodDefinition(MD))
3603 Methods[InstanceMethods].push_back(MD);
3608 auto values = builder.
beginStruct(ObjCTypes.ClassTy);
3609 values.add(EmitMetaClass(ID, Protocols, Methods[ClassMethods]));
3612 LazySymbols.insert(Super->getIdentifier());
3614 values.addBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
3615 ObjCTypes.ClassPtrTy);
3617 values.addNullPointer(ObjCTypes.ClassPtrTy);
3621 values.addInt(ObjCTypes.LongTy, 0);
3622 values.addInt(ObjCTypes.LongTy, Flags);
3623 values.addInt(ObjCTypes.LongTy, Size.
getQuantity());
3624 values.add(EmitIvarList(ID,
false));
3625 values.add(emitMethodList(ID->
getName(), MethodListType::InstanceMethods,
3626 Methods[InstanceMethods]));
3628 values.addNullPointer(ObjCTypes.CachePtrTy);
3629 values.add(Protocols);
3631 values.add(EmitClassExtension(ID, Size, hasMRCWeak,
3634 std::string Name(
"OBJC_CLASS_");
3636 const char *Section =
"__OBJC,__class,regular,no_dead_strip";
3638 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3640 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3641 "Forward metaclass reference has incorrect type.");
3642 values.finishAndSetAsInitializer(GV);
3643 GV->setSection(Section);
3647 GV = CreateMetadataVar(Name, values, Section, CGM.
getPointerAlign(),
true);
3648 DefinedClasses.push_back(GV);
3649 ImplementedClasses.push_back(Interface);
3651 MethodDefinitions.clear();
3655 llvm::Constant *Protocols,
3658 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ClassTy);
3664 auto values = builder.
beginStruct(ObjCTypes.ClassTy);
3670 ObjCTypes.ClassPtrTy);
3675 values.addBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
3676 ObjCTypes.ClassPtrTy);
3678 values.addNullPointer(ObjCTypes.ClassPtrTy);
3682 values.addInt(ObjCTypes.LongTy, 0);
3683 values.addInt(ObjCTypes.LongTy, Flags);
3684 values.addInt(ObjCTypes.LongTy, Size);
3685 values.add(EmitIvarList(ID,
true));
3686 values.add(emitMethodList(ID->
getName(), MethodListType::ClassMethods,
3689 values.addNullPointer(ObjCTypes.CachePtrTy);
3690 values.add(Protocols);
3692 values.addNullPointer(ObjCTypes.Int8PtrTy);
3697 std::string Name(
"OBJC_METACLASS_");
3701 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3703 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3704 "Forward metaclass reference has incorrect type.");
3705 values.finishAndSetAsInitializer(GV);
3709 llvm::GlobalValue::PrivateLinkage);
3711 GV->setSection(
"__OBJC,__meta_class,regular,no_dead_strip");
3728 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3730 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
3731 llvm::GlobalValue::PrivateLinkage,
nullptr,
3734 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3735 "Forward metaclass reference has incorrect type.");
3741 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3744 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
3745 llvm::GlobalValue::PrivateLinkage,
nullptr,
3748 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3749 "Forward class metadata reference has incorrect type.");
3769 llvm::Constant *layout;
3771 layout = llvm::ConstantPointerNull::get(CGM.
Int8PtrTy);
3778 llvm::Constant *propertyList =
3779 EmitPropertyList((isMetaclass ? Twine(
"_OBJC_$_CLASS_PROP_LIST_")
3780 : Twine(
"_OBJC_$_PROP_LIST_"))
3785 if (layout->isNullValue() && propertyList->isNullValue()) {
3786 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
3790 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
3793 auto values = builder.
beginStruct(ObjCTypes.ClassExtensionTy);
3794 values.addInt(ObjCTypes.IntTy, size);
3796 values.add(propertyList);
3798 return CreateMetadataVar(
"OBJC_CLASSEXT_" + ID->
getName(), values,
3799 "__OBJC,__class_ext,regular,no_dead_strip",
3823 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3829 auto countSlot = ivarList.addPlaceholder();
3830 auto ivars = ivarList.beginArray(ObjCTypes.IvarTy);
3835 if (!IVD->getDeclName())
3838 auto ivar = ivars.beginStruct(ObjCTypes.IvarTy);
3839 ivar.add(GetMethodVarName(IVD->getIdentifier()));
3840 ivar.add(GetMethodVarType(IVD));
3841 ivar.addInt(ObjCTypes.IntTy, ComputeIvarBaseOffset(CGM, OID, IVD));
3842 ivar.finishAndAddTo(ivars);
3846 auto count = ivars.size();
3850 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3853 ivars.finishAndAddTo(ivarList);
3854 ivarList.fillPlaceholderWithInt(countSlot, ObjCTypes.IntTy, count);
3856 llvm::GlobalVariable *GV;
3859 CreateMetadataVar(
"OBJC_CLASS_VARIABLES_" + ID->
getName(), ivarList,
3860 "__OBJC,__class_vars,regular,no_dead_strip",
3863 GV = CreateMetadataVar(
"OBJC_INSTANCE_VARIABLES_" + ID->
getName(), ivarList,
3864 "__OBJC,__instance_vars,regular,no_dead_strip",
3866 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy);
3877 auto description = builder.
beginStruct(ObjCTypes.MethodDescriptionTy);
3878 description.addBitCast(GetMethodVarName(MD->
getSelector()),
3879 ObjCTypes.SelectorPtrTy);
3880 description.add(GetMethodVarType(MD));
3881 description.finishAndAddTo(builder);
3893 llvm::Function *fn = GetMethodDefinition(MD);
3894 assert(fn &&
"no definition registered for method");
3896 auto method = builder.
beginStruct(ObjCTypes.MethodTy);
3897 method.addBitCast(GetMethodVarName(MD->
getSelector()),
3898 ObjCTypes.SelectorPtrTy);
3899 method.add(GetMethodVarType(MD));
3900 method.addBitCast(fn, ObjCTypes.Int8PtrTy);
3901 method.finishAndAddTo(builder);
3917 llvm::Constant *CGObjCMac::emitMethodList(Twine name,
MethodListType MLT,
3921 bool forProtocol =
false;
3923 case MethodListType::CategoryInstanceMethods:
3924 prefix =
"OBJC_CATEGORY_INSTANCE_METHODS_";
3925 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
3926 forProtocol =
false;
3928 case MethodListType::CategoryClassMethods:
3929 prefix =
"OBJC_CATEGORY_CLASS_METHODS_";
3930 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3931 forProtocol =
false;
3933 case MethodListType::InstanceMethods:
3934 prefix =
"OBJC_INSTANCE_METHODS_";
3935 section =
"__OBJC,__inst_meth,regular,no_dead_strip";
3936 forProtocol =
false;
3938 case MethodListType::ClassMethods:
3939 prefix =
"OBJC_CLASS_METHODS_";
3940 section =
"__OBJC,__cls_meth,regular,no_dead_strip";
3941 forProtocol =
false;
3943 case MethodListType::ProtocolInstanceMethods:
3944 prefix =
"OBJC_PROTOCOL_INSTANCE_METHODS_";
3945 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
3948 case MethodListType::ProtocolClassMethods:
3949 prefix =
"OBJC_PROTOCOL_CLASS_METHODS_";
3950 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3953 case MethodListType::OptionalProtocolInstanceMethods:
3954 prefix =
"OBJC_PROTOCOL_INSTANCE_METHODS_OPT_";
3955 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
3958 case MethodListType::OptionalProtocolClassMethods:
3959 prefix =
"OBJC_PROTOCOL_CLASS_METHODS_OPT_";
3960 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3966 if (methods.empty())
3967 return llvm::Constant::getNullValue(forProtocol
3968 ? ObjCTypes.MethodDescriptionListPtrTy
3969 : ObjCTypes.MethodListPtrTy);
3976 values.addInt(ObjCTypes.IntTy, methods.size());
3977 auto methodArray = values.beginArray(ObjCTypes.MethodDescriptionTy);
3978 for (
auto MD : methods) {
3979 emitMethodDescriptionConstant(methodArray, MD);
3981 methodArray.finishAndAddTo(values);
3983 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
3985 return llvm::ConstantExpr::getBitCast(GV,
3986 ObjCTypes.MethodDescriptionListPtrTy);
3992 values.addNullPointer(ObjCTypes.Int8PtrTy);
3993 values.addInt(ObjCTypes.IntTy, methods.size());
3994 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
3995 for (
auto MD : methods) {
3997 emitMethodConstant(methodArray, MD);
3999 methodArray.finishAndAddTo(values);
4001 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
4003 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListPtrTy);
4006 llvm::Function *CGObjCCommonMac::GenerateMethod(
const ObjCMethodDecl *OMD,
4008 llvm::Function *Method;
4011 Method = GenerateDirectMethod(OMD, CD);
4014 GetNameForMethod(OMD, CD, Name);
4017 llvm::FunctionType *MethodTy =
4024 MethodDefinitions.insert(std::make_pair(OMD, Method));
4033 if (I != DirectMethodDefinitions.end())
4037 GetNameForMethod(OMD, CD, Name,
true);
4040 llvm::FunctionType *MethodTy =
4042 llvm::Function *Method =
4045 DirectMethodDefinitions.insert(std::make_pair(OMD->
getCanonicalDecl(), Method));
4050 void CGObjCCommonMac::GenerateDirectMethodPrologue(
4054 bool ReceiverCanBeNull =
true;
4056 auto selfValue = Builder.CreateLoad(selfAddr);
4074 "GenerateDirectMethod() should be called with the Class Interface");
4087 result = GeneratePossiblySpecializedMessageSend(
4098 if (ReceiverCanBeNull) {
4099 llvm::BasicBlock *SelfIsNilBlock =
4101 llvm::BasicBlock *ContBlock =
4105 auto selfTy = cast<llvm::PointerType>(selfValue->getType());
4106 auto Zero = llvm::ConstantPointerNull::get(selfTy);
4109 Builder.CreateCondBr(Builder.CreateICmpEQ(selfValue, Zero), SelfIsNilBlock,
4110 ContBlock, MDHelper.createBranchWeights(1, 1 << 20));
4116 Builder.SetInsertPoint(SelfIsNilBlock);
4117 if (!retTy->isVoidType()) {
4125 Builder.SetInsertPoint(ContBlock);
4130 Builder.CreateStore(GetSelector(CGF, OMD),
4135 llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
4140 llvm::GlobalValue::LinkageTypes
LT =
4142 llvm::GlobalVariable *GV =
4144 if (!Section.empty())
4145 GV->setSection(Section);
4151 llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
4152 llvm::Constant *Init,
4157 llvm::GlobalValue::LinkageTypes
LT =
4159 llvm::GlobalVariable *GV =
4160 new llvm::GlobalVariable(CGM.
getModule(), Ty,
false,
LT, Init, Name);
4161 if (!Section.empty())
4162 GV->setSection(Section);
4169 llvm::GlobalVariable *
4171 bool ForceNonFragileABI,
4172 bool NullTerminate) {
4175 case ObjCLabelType::ClassName: Label =
"OBJC_CLASS_NAME_";
break;
4176 case ObjCLabelType::MethodVarName: Label =
"OBJC_METH_VAR_NAME_";
break;
4177 case ObjCLabelType::MethodVarType: Label =
"OBJC_METH_VAR_TYPE_";
break;
4178 case ObjCLabelType::PropertyName: Label =
"OBJC_PROP_NAME_ATTR_";
break;
4181 bool NonFragile = ForceNonFragileABI || isNonFragileABI();
4185 case ObjCLabelType::ClassName:
4186 Section = NonFragile ?
"__TEXT,__objc_classname,cstring_literals" 4187 :
"__TEXT,__cstring,cstring_literals";
4189 case ObjCLabelType::MethodVarName:
4190 Section = NonFragile ?
"__TEXT,__objc_methname,cstring_literals" 4191 :
"__TEXT,__cstring,cstring_literals";
4193 case ObjCLabelType::MethodVarType:
4194 Section = NonFragile ?
"__TEXT,__objc_methtype,cstring_literals" 4195 :
"__TEXT,__cstring,cstring_literals";
4197 case ObjCLabelType::PropertyName:
4198 Section =
"__TEXT,__cstring,cstring_literals";
4202 llvm::Constant *
Value =
4203 llvm::ConstantDataArray::getString(VMContext, Name, NullTerminate);
4204 llvm::GlobalVariable *GV =
4205 new llvm::GlobalVariable(CGM.
getModule(), Value->getType(),
4207 llvm::GlobalValue::PrivateLinkage,
Value,
Label);
4208 if (CGM.
getTriple().isOSBinFormatMachO())
4209 GV->setSection(Section);
4210 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4217 llvm::Function *CGObjCMac::ModuleInitFunction() {
4223 llvm::FunctionCallee CGObjCMac::GetPropertyGetFunction() {
4224 return ObjCTypes.getGetPropertyFn();
4227 llvm::FunctionCallee CGObjCMac::GetPropertySetFunction() {
4228 return ObjCTypes.getSetPropertyFn();
4231 llvm::FunctionCallee CGObjCMac::GetOptimizedPropertySetFunction(
bool atomic,
4233 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
4236 llvm::FunctionCallee CGObjCMac::GetGetStructFunction() {
4237 return ObjCTypes.getCopyStructFn();
4240 llvm::FunctionCallee CGObjCMac::GetSetStructFunction() {
4241 return ObjCTypes.getCopyStructFn();
4244 llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectGetFunction() {
4245 return ObjCTypes.getCppAtomicObjectFunction();
4248 llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectSetFunction() {
4249 return ObjCTypes.getCppAtomicObjectFunction();
4252 llvm::FunctionCallee CGObjCMac::EnumerationMutationFunction() {
4253 return ObjCTypes.getEnumerationMutationFn();
4257 return EmitTryOrSynchronizedStmt(CGF, S);
4262 return EmitTryOrSynchronizedStmt(CGF, S);
4271 ObjCTypesHelper &ObjCTypes;
4272 PerformFragileFinally(
const Stmt *S,
4276 ObjCTypesHelper *ObjCTypes)
4277 : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
4278 ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
4283 llvm::BasicBlock *FinallyCallExit =
4285 llvm::BasicBlock *FinallyNoCallExit =
4288 FinallyCallExit, FinallyNoCallExit);
4296 if (isa<ObjCAtTryStmt>(S)) {
4298 cast<ObjCAtTryStmt>(S).getFinallyStmt()) {
4300 if (flags.isForEHCleanup())
return;
4307 CGF.
EmitStmt(FinallyStmt->getFinallyBody());
4326 class FragileHazards {
4331 llvm::InlineAsm *ReadHazard;
4332 llvm::InlineAsm *WriteHazard;
4334 llvm::FunctionType *GetAsmFnType();
4336 void collectLocals();
4342 void emitWriteHazard();
4343 void emitHazardsInNewBlocks();
4355 if (Locals.empty())
return;
4358 for (llvm::Function::iterator
4359 I = CGF.
CurFn->begin(), E = CGF.
CurFn->end(); I != E; ++I)
4360 BlocksBeforeTry.insert(&*I);
4362 llvm::FunctionType *AsmFnTy = GetAsmFnType();
4370 std::string Constraint;
4371 for (
unsigned I = 0, E = Locals.size(); I != E; ++I) {
4372 if (I) Constraint +=
',';
4376 ReadHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
4384 std::string Constraint;
4385 for (
unsigned I = 0, E = Locals.size(); I != E; ++I) {
4386 if (I) Constraint +=
',';
4387 Constraint +=
"=*m";
4390 WriteHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
4395 void FragileHazards::emitWriteHazard() {
4396 if (Locals.empty())
return;
4401 void FragileHazards::emitReadHazard(
CGBuilderTy &Builder) {
4402 assert(!Locals.empty());
4403 llvm::CallInst *call = Builder.CreateCall(ReadHazard, Locals);
4404 call->setDoesNotThrow();
4410 void FragileHazards::emitHazardsInNewBlocks() {
4411 if (Locals.empty())
return;
4416 for (llvm::Function::iterator
4417 FI = CGF.
CurFn->begin(), FE = CGF.
CurFn->end(); FI != FE; ++FI) {
4418 llvm::BasicBlock &BB = *FI;
4419 if (BlocksBeforeTry.count(&BB))
continue;
4422 for (llvm::BasicBlock::iterator
4423 BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) {
4424 llvm::Instruction &I = *BI;
4428 if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I))
4430 if (isa<llvm::IntrinsicInst>(I))
4435 if (cast<llvm::CallBase>(I).doesNotThrow())
4443 Builder.SetInsertPoint(&BB, BI);
4444 emitReadHazard(Builder);
4453 void FragileHazards::collectLocals() {
4461 llvm::BasicBlock &Entry = CGF.
CurFn->getEntryBlock();
4462 for (llvm::BasicBlock::iterator
4463 I = Entry.begin(), E = Entry.end(); I != E; ++I)
4464 if (isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I))
4465 Locals.push_back(&*I);
4468 llvm::FunctionType *FragileHazards::GetAsmFnType() {
4470 for (
unsigned i = 0, e = Locals.size(); i != e; ++i)
4471 tys[i] = Locals[i]->getType();
4472 return llvm::FunctionType::get(CGF.
VoidTy, tys,
false);
4589 bool isTry = isa<ObjCAtTryStmt>(S);
4609 CGF.
EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
4622 "exceptiondata.ptr");
4628 FragileHazards Hazards(CGF);
4657 ExceptionData.getPointer());
4660 llvm::Constant *
Zero = llvm::ConstantInt::get(CGF.
Builder.getInt32Ty(), 0);
4663 ObjCTypes.ExceptionDataTy, ExceptionData.getPointer(), GEPIndexes,
4666 ObjCTypes.getSetJmpFn(), SetJmpBuffer,
"setjmp_result");
4667 SetJmpResult->setCanReturnTwice();
4674 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
4675 CGF.
Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
4680 CGF.
EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
4681 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
4683 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.
Builder.saveAndClearIP();
4689 Hazards.emitWriteHazard();
4693 if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
4702 llvm::CallInst *Caught =
4704 ExceptionData.getPointer(),
"caught");
4714 llvm::BasicBlock *CatchBlock =
nullptr;
4715 llvm::BasicBlock *CatchHandler =
nullptr;
4721 "propagating_exception");
4727 ExceptionData.getPointer());
4729 llvm::CallInst *SetJmpResult =
4731 SetJmpBuffer,
"setjmp.result");
4732 SetJmpResult->setCanReturnTwice();
4735 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
4739 CGF.
Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
4749 bool AllMatched =
false;
4779 EmitInitOfCatchParam(CGF, Caught, CatchParam);
4791 assert(OPT &&
"Unexpected non-object pointer type in @catch");
4796 assert(IDecl &&
"Catch parameter must have Objective-C type!");
4802 llvm::CallInst *Match =
4804 matchArgs,
"match");
4809 CGF.
Builder.CreateCondBr(CGF.
Builder.CreateIsNotNull(Match,
"matched"),
4810 MatchedBlock, NextCatchBlock);
4826 EmitInitOfCatchParam(CGF, Tmp, CatchParam);
4842 if (Caught->use_empty())
4843 Caught->eraseFromParent();
4859 assert(PropagatingExnVar.
isValid());
4860 llvm::CallInst *NewCaught =
4862 ExceptionData.getPointer(),
"caught");
4872 Hazards.emitHazardsInNewBlocks();
4875 CGF.
Builder.restoreIP(TryFallthroughIP);
4879 CGF.
EmitBlock(FinallyEnd.getBlock(),
true);
4882 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
4887 if (PropagatingExnVar.
isValid()) {
4892 llvm::CallInst *Caught =
4894 ExceptionData.getPointer());
4895 PropagatingExn = Caught;
4900 CGF.
Builder.CreateUnreachable();
4903 CGF.
Builder.restoreIP(SavedIP);
4908 bool ClearInsertionPoint) {
4917 "Unexpected rethrow outside @catch block.");
4921 CGF.
EmitRuntimeCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
4922 ->setDoesNotReturn();
4923 CGF.
Builder.CreateUnreachable();
4926 if (ClearInsertionPoint)
4927 CGF.
Builder.ClearInsertionPoint();
4937 ObjCTypes.PtrObjectPtrTy);
4951 if (!isa<llvm::PointerType>(SrcTy)) {
4952 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(SrcTy);
4953 assert(Size <= 8 && "does not support size > 8
"); 4954 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty) 4955 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty); 4956 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 4958 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 4959 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 4960 llvm::Value *args[] = { src, dst.getPointer() }; 4961 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), 4962 args, "weakassign
"); 4968 void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
4969 llvm::Value *src, Address dst,
4971 llvm::Type * SrcTy = src->getType();
4972 if (!isa<llvm::PointerType>(SrcTy)) {
4973 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4974 assert(Size <= 8 && "does
not support size > 8
"); 4975 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty) 4976 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty); 4977 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 4979 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 4980 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 4981 llvm::Value *args[] = { src, dst.getPointer() }; 4983 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), 4984 args, "globalassign
"); 4986 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(), 4987 args, "threadlocalassign
"); 4993 void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
4994 llvm::Value *src, Address dst,
4995 llvm::Value *ivarOffset) {
4996 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is
NULL"); 4997 llvm::Type * SrcTy = src->getType(); 4998 if (!isa<llvm::PointerType>(SrcTy)) { 4999 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy); 5000 assert(Size <= 8 && "does
not support size > 8
"); 5001 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty) 5002 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty); 5003 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 5005 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 5006 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 5007 llvm::Value *args[] = { src, dst.getPointer(), ivarOffset }; 5008 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args); 5014 void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
5015 llvm::Value *src, Address dst) {
5016 llvm::Type * SrcTy = src->getType();
5017 if (!isa<llvm::PointerType>(SrcTy)) {
5018 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
5019 assert(Size <= 8 && "does
not support size > 8
"); 5020 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty) 5021 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty); 5022 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 5024 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 5025 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 5026 llvm::Value *args[] = { src, dst.getPointer() }; 5027 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), 5028 args, "strongassign
"); 5031 void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, 5034 llvm::Value *size) { 5035 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy); 5036 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy); 5037 llvm::Value *args[] = { DestPtr.getPointer(), SrcPtr.getPointer(), size }; 5038 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args); 5043 LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
5045 llvm::Value *BaseValue,
5046 const ObjCIvarDecl *Ivar,
5047 unsigned CVRQualifiers) {
5048 const ObjCInterfaceDecl *ID =
5049 ObjectTy->castAs<ObjCObjectType>()->getInterface();
5050 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
5051 EmitIvarOffset(CGF, ID, Ivar));
5054 llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
5055 const ObjCInterfaceDecl *Interface,
5056 const ObjCIvarDecl *Ivar) {
5057 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
5058 return llvm::ConstantInt::get(
5059 CGM.getTypes().ConvertType(CGM.getContext().LongTy),
5063 /* *** Private Interface *** */
5065 std::string CGObjCCommonMac::GetSectionName(StringRef Section,
5066 StringRef MachOAttributes) {
5067 switch (CGM.getTriple().getObjectFormat()) {
5068 case llvm::Triple::UnknownObjectFormat:
5069 llvm_unreachable("unexpected
object file format
"); 5070 case llvm::Triple::MachO: { 5071 if (MachOAttributes.empty()) 5072 return ("__DATA,
" + Section).str(); 5073 return ("__DATA,
" + Section + ",
" + MachOAttributes).str(); 5075 case llvm::Triple::ELF: 5076 assert(Section.substr(0, 2) == "__
" && 5077 "expected the name to begin with __
"); 5078 return Section.substr(2).str(); 5079 case llvm::Triple::COFF: 5080 assert(Section.substr(0, 2) == "__
" && 5081 "expected the name to begin with __
"); 5082 return (".
" + Section.substr(2) + "$B
").str(); 5083 case llvm::Triple::Wasm: 5084 case llvm::Triple::XCOFF: 5085 llvm::report_fatal_error( 5086 "Objective-C support is unimplemented
for object file format.
"); 5089 llvm_unreachable("Unhandled llvm::Triple::ObjectFormatType
enum"); 5100 enum ImageInfoFlags {
5101 eImageInfo_FixAndContinue = (1 << 0), // This flag is no longer set by clang.
5102 eImageInfo_GarbageCollected = (1 << 1),
5103 eImageInfo_GCOnly = (1 << 2),
5104 eImageInfo_OptimizedByDyld = (1 << 3), // This flag is set by the dyld shared cache.
5106 // A flag indicating that the module has no instances of a @synthesize of a
5107 // superclass variable. <rdar://problem/6803242>
5108 eImageInfo_CorrectedSynthesize = (1 << 4), // This flag is no longer set by clang.
5109 eImageInfo_ImageIsSimulated = (1 << 5),
5110 eImageInfo_ClassProperties = (1 << 6)
5113 void CGObjCCommonMac::EmitImageInfo() {
5114 unsigned version = 0; // Version is unused?
5115 std::string Section =
5117 ? "__OBJC,__image_info,regular
" 5118 : GetSectionName("__objc_imageinfo
", "regular,no_dead_strip
"); 5120 // Generate module-level named metadata to convey this information to the 5121 // linker and code-gen. 5122 llvm::Module &Mod = CGM.getModule(); 5124 // Add the ObjC ABI version to the module flags. 5125 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Version
", ObjCABI); 5126 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Version
", 5128 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Section
", 5129 llvm::MDString::get(VMContext, Section)); 5131 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) { 5132 // Non-GC overrides those files which specify GC. 5133 Mod.addModuleFlag(llvm::Module::Override, 5134 "Objective-C Garbage Collection
", (uint32_t)0); 5136 // Add the ObjC garbage collection value. 5137 Mod.addModuleFlag(llvm::Module::Error, 5138 "Objective-C Garbage Collection
", 5139 eImageInfo_GarbageCollected); 5141 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) { 5142 // Add the ObjC GC Only value. 5143 Mod.addModuleFlag(llvm::Module::Error, "Objective-C GC Only
", 5146 // Require that GC be specified and set to eImageInfo_GarbageCollected. 5147 llvm::Metadata *Ops[2] = { 5148 llvm::MDString::get(VMContext, "Objective-C Garbage Collection
"), 5149 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( 5150 llvm::Type::getInt32Ty(VMContext), eImageInfo_GarbageCollected))}; 5151 Mod.addModuleFlag(llvm::Module::Require, "Objective-C GC Only
", 5152 llvm::MDNode::get(VMContext, Ops)); 5156 // Indicate whether we're compiling this to run on a simulator. 5157 if (CGM.getTarget().getTriple().isSimulatorEnvironment()) 5158 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Is Simulated
", 5159 eImageInfo_ImageIsSimulated); 5161 // Indicate whether we are generating class properties. 5162 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Class Properties
", 5163 eImageInfo_ClassProperties); 5166 // struct objc_module { 5167 // unsigned long version; 5168 // unsigned long size; 5169 // const char *name; 5173 // FIXME: Get from somewhere 5174 static const int ModuleVersion = 7; 5176 void CGObjCMac::EmitModuleInfo() { 5177 uint64_t Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ModuleTy); 5179 ConstantInitBuilder builder(CGM); 5180 auto values = builder.beginStruct(ObjCTypes.ModuleTy); 5181 values.addInt(ObjCTypes.LongTy, ModuleVersion); 5182 values.addInt(ObjCTypes.LongTy, Size); 5183 // This used to be the filename, now it is unused. <rdr://4327263> 5184 values.add(GetClassName(StringRef(""))); 5185 values.add(EmitModuleSymbols()); 5186 CreateMetadataVar("OBJC_MODULES
", values, 5187 "__OBJC,__module_info,regular,no_dead_strip
", 5188 CGM.getPointerAlign(), true); 5191 llvm::Constant *CGObjCMac::EmitModuleSymbols() { 5192 unsigned NumClasses = DefinedClasses.size(); 5193 unsigned NumCategories = DefinedCategories.size(); 5195 // Return null if no symbols were defined. 5196 if (!NumClasses && !NumCategories) 5197 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy); 5199 ConstantInitBuilder builder(CGM); 5200 auto values = builder.beginStruct(); 5201 values.addInt(ObjCTypes.LongTy, 0); 5202 values.addNullPointer(ObjCTypes.SelectorPtrTy); 5203 values.addInt(ObjCTypes.ShortTy, NumClasses); 5204 values.addInt(ObjCTypes.ShortTy, NumCategories); 5206 // The runtime expects exactly the list of defined classes followed 5207 // by the list of defined categories, in a single array. 5208 auto array = values.beginArray(ObjCTypes.Int8PtrTy); 5209 for (unsigned i=0; i<NumClasses; i++) { 5210 const ObjCInterfaceDecl *ID = ImplementedClasses[i]; 5212 if (ObjCImplementationDecl *IMP = ID->getImplementation()) 5213 // We are implementing a weak imported interface. Give it external linkage 5214 if (ID->isWeakImported() && !IMP->isWeakImported()) 5215 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage); 5217 array.addBitCast(DefinedClasses[i], ObjCTypes.Int8PtrTy); 5219 for (unsigned i=0; i<NumCategories; i++) 5220 array.addBitCast(DefinedCategories[i], ObjCTypes.Int8PtrTy); 5222 array.finishAndAddTo(values); 5224 llvm::GlobalVariable *GV = CreateMetadataVar( 5225 "OBJC_SYMBOLS
", values, "__OBJC,__symbols,regular,no_dead_strip
", 5226 CGM.getPointerAlign(), true); 5227 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy); 5230 llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF, 5231 IdentifierInfo *II) { 5232 LazySymbols.insert(II); 5234 llvm::GlobalVariable *&Entry = ClassReferences[II]; 5237 llvm::Constant *Casted = 5238 llvm::ConstantExpr::getBitCast(GetClassName(II->getName()), 5239 ObjCTypes.ClassPtrTy); 5240 Entry = CreateMetadataVar( 5241 "OBJC_CLASS_REFERENCES_
", Casted, 5242 "__OBJC,__cls_refs,literal_pointers,no_dead_strip
", 5243 CGM.getPointerAlign(), true); 5246 return CGF.Builder.CreateAlignedLoad(Entry, CGF.getPointerAlign()); 5249 llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF, 5250 const ObjCInterfaceDecl *ID) { 5251 // If the class has the objc_runtime_visible attribute, we need to 5252 // use the Objective-C runtime to get the class. 5253 if (ID->hasAttr<ObjCRuntimeVisibleAttr>()) 5254 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes); 5256 IdentifierInfo *RuntimeName = 5257 &CGM.getContext().Idents.get(ID->getObjCRuntimeNameAsString()); 5258 return EmitClassRefFromId(CGF, RuntimeName); 5261 llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) { 5262 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool
"); 5263 return EmitClassRefFromId(CGF, II); 5266 llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel) { 5267 return CGF.Builder.CreateLoad(EmitSelectorAddr(Sel)); 5270 Address CGObjCMac::EmitSelectorAddr(Selector Sel) { 5271 CharUnits Align = CGM.getPointerAlign(); 5273 llvm::GlobalVariable *&Entry = SelectorReferences[Sel]; 5275 llvm::Constant *Casted = 5276 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel), 5277 ObjCTypes.SelectorPtrTy); 5278 Entry = CreateMetadataVar( 5279 "OBJC_SELECTOR_REFERENCES_
", Casted, 5280 "__OBJC,__message_refs,literal_pointers,no_dead_strip
", Align, true); 5281 Entry->setExternallyInitialized(true); 5284 return Address(Entry, Align); 5287 llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) { 5288 llvm::GlobalVariable *&Entry = ClassNames[RuntimeName]; 5290 Entry = CreateCStringLiteral(RuntimeName, ObjCLabelType::ClassName); 5291 return getConstantGEP(VMContext, Entry, 0, 0); 5294 llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) { 5295 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*>::iterator 5296 I = MethodDefinitions.find(MD); 5297 if (I != MethodDefinitions.end()) 5305 llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
5306 const ObjCCommonTypesHelper &ObjCTypes) {
5307 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
5310 void IvarLayoutBuilder::visitRecord(const RecordType *RT,
5312 const RecordDecl *RD = RT->getDecl();
5314 // If this is a union, remember that we had one, because it might mess
5315 // up the ordering of layout entries.
5317 IsDisordered = true;
5319 const ASTRecordLayout *recLayout = nullptr;
5320 visitAggregate(RD->field_begin(), RD->field_end(), offset,
5321 [&](const FieldDecl *field) -> CharUnits {
5323 recLayout = &CGM.getContext().getASTRecordLayout(RD);
5324 auto offsetInBits = recLayout->getFieldOffset(field->getFieldIndex());
5325 return CGM.getContext().toCharUnitsFromBits(offsetInBits);
5329 template <class Iterator, class GetOffsetFn>
5330 void IvarLayoutBuilder::visitAggregate(Iterator begin, Iterator end,
5331 CharUnits aggregateOffset,
5332 const GetOffsetFn &getOffset) {
5333 for (; begin != end; ++begin) {
5334 auto field = *begin;
5336 // Skip over bitfields.
5337 if (field->isBitField()) {
5341 // Compute the offset of the field within the aggregate.
5342 CharUnits fieldOffset = aggregateOffset + getOffset(field);
5344 visitField(field, fieldOffset);
5349 void IvarLayoutBuilder::visitField(const FieldDecl *field,
5350 CharUnits fieldOffset) {
5351 QualType fieldType = field->getType();
5353 // Drill down into arrays.
5354 uint64_t numElts = 1;
5355 if (auto arrayType = CGM.getContext().getAsIncompleteArrayType(fieldType)) {
5357 fieldType = arrayType->getElementType();
5359 // Unlike incomplete arrays, constant arrays can be nested.
5360 while (auto arrayType = CGM.getContext().getAsConstantArrayType(fieldType)) {
5361 numElts *= arrayType->getSize().getZExtValue();
5362 fieldType = arrayType->getElementType();
5365 assert(!fieldType->isArrayType() && "ivar of non-constant array
type?
"); 5367 // If we ended up with a zero-sized array, we've done what we can do within 5368 // the limits of this layout encoding. 5369 if (numElts == 0) return; 5371 // Recurse if the base element type is a record type. 5372 if (auto recType = fieldType->getAs<RecordType>()) { 5373 size_t oldEnd = IvarsInfo.size(); 5375 visitRecord(recType, fieldOffset); 5377 // If we have an array, replicate the first entry's layout information. 5378 auto numEltEntries = IvarsInfo.size() - oldEnd; 5379 if (numElts != 1 && numEltEntries != 0) { 5380 CharUnits eltSize = CGM.getContext().getTypeSizeInChars(recType); 5381 for (uint64_t eltIndex = 1; eltIndex != numElts; ++eltIndex) { 5382 // Copy the last numEltEntries onto the end of the array, adjusting 5383 // each for the element size. 5384 for (size_t i = 0; i != numEltEntries; ++i) { 5385 auto firstEntry = IvarsInfo[oldEnd + i]; 5386 IvarsInfo.push_back(IvarInfo(firstEntry.Offset + eltIndex * eltSize, 5387 firstEntry.SizeInWords)); 5395 // Classify the element type. 5396 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), fieldType); 5398 // If it matches what we're looking for, add an entry. 5399 if ((ForStrongLayout && GCAttr == Qualifiers::Strong) 5400 || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) { 5401 assert(CGM.getContext().getTypeSizeInChars(fieldType) 5402 == CGM.getPointerSize()); 5403 IvarsInfo.push_back(IvarInfo(fieldOffset, numElts)); 5410 llvm::Constant *IvarLayoutBuilder::buildBitmap(CGObjCCommonMac &CGObjC,
5411 llvm::SmallVectorImpl<unsigned char> &buffer) {
5412 // The bitmap is a series of skip/scan instructions, aligned to word
5413 // boundaries. The skip is performed first.
5414 const unsigned char MaxNibble = 0xF;
5415 const unsigned char SkipMask = 0xF0, SkipShift = 4;
5416 const unsigned char ScanMask = 0x0F, ScanShift = 0;
5418 assert(!IvarsInfo.empty() && "generating bitmap
for no data
"); 5420 // Sort the ivar info on byte position in case we encounterred a 5421 // union nested in the ivar list. 5423 // This isn't a stable sort, but our algorithm should handle it fine. 5424 llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end()); 5426 assert(std::is_sorted(IvarsInfo.begin(), IvarsInfo.end())); 5428 assert(IvarsInfo.back().Offset < InstanceEnd); 5430 assert(buffer.empty()); 5432 // Skip the next N words. 5433 auto skip = [&](unsigned numWords) { 5434 assert(numWords > 0); 5436 // Try to merge into the previous byte. Since scans happen second, we 5437 // can't do this if it includes a scan. 5438 if (!buffer.empty() && !(buffer.back() & ScanMask)) { 5439 unsigned lastSkip = buffer.back() >> SkipShift; 5440 if (lastSkip < MaxNibble) { 5441 unsigned claimed = std::min(MaxNibble - lastSkip, numWords); 5442 numWords -= claimed; 5443 lastSkip += claimed; 5444 buffer.back() = (lastSkip << SkipShift); 5448 while (numWords >= MaxNibble) { 5449 buffer.push_back(MaxNibble << SkipShift); 5450 numWords -= MaxNibble; 5453 buffer.push_back(numWords << SkipShift); 5457 // Scan the next N words. 5458 auto scan = [&](unsigned numWords) { 5459 assert(numWords > 0); 5461 // Try to merge into the previous byte. Since scans happen second, we can 5462 // do this even if it includes a skip. 5463 if (!buffer.empty()) { 5464 unsigned lastScan = (buffer.back() & ScanMask) >> ScanShift; 5465 if (lastScan < MaxNibble) { 5466 unsigned claimed = std::min(MaxNibble - lastScan, numWords); 5467 numWords -= claimed; 5468 lastScan += claimed; 5469 buffer.back() = (buffer.back() & SkipMask) | (lastScan << ScanShift); 5473 while (numWords >= MaxNibble) { 5474 buffer.push_back(MaxNibble << ScanShift); 5475 numWords -= MaxNibble; 5478 buffer.push_back(numWords << ScanShift); 5482 // One past the end of the last scan. 5483 unsigned endOfLastScanInWords = 0; 5484 const CharUnits WordSize = CGM.getPointerSize(); 5486 // Consider all the scan requests. 5487 for (auto &request : IvarsInfo) { 5488 CharUnits beginOfScan = request.Offset - InstanceBegin; 5490 // Ignore scan requests that don't start at an even multiple of the 5491 // word size. We can't encode them. 5492 if ((beginOfScan % WordSize) != 0) continue; 5494 // Ignore scan requests that start before the instance start. 5495 // This assumes that scans never span that boundary. The boundary 5496 // isn't the true start of the ivars, because in the fragile-ARC case 5497 // it's rounded up to word alignment, but the test above should leave 5498 // us ignoring that possibility. 5499 if (beginOfScan.isNegative()) { 5500 assert(request.Offset + request.SizeInWords * WordSize <= InstanceBegin); 5504 unsigned beginOfScanInWords = beginOfScan / WordSize; 5505 unsigned endOfScanInWords = beginOfScanInWords + request.SizeInWords; 5507 // If the scan starts some number of words after the last one ended, 5509 if (beginOfScanInWords > endOfLastScanInWords) { 5510 skip(beginOfScanInWords - endOfLastScanInWords); 5512 // Otherwise, start scanning where the last left off. 5514 beginOfScanInWords = endOfLastScanInWords; 5516 // If that leaves us with nothing to scan, ignore this request. 5517 if (beginOfScanInWords >= endOfScanInWords) continue; 5520 // Scan to the end of the request. 5521 assert(beginOfScanInWords < endOfScanInWords); 5522 scan(endOfScanInWords - beginOfScanInWords); 5523 endOfLastScanInWords = endOfScanInWords; 5527 return llvm::ConstantPointerNull::get(CGM.Int8PtrTy); 5529 // For GC layouts, emit a skip to the end of the allocation so that we 5530 // have precise information about the entire thing. This isn't useful 5531 // or necessary for the ARC-style layout strings. 5532 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) { 5533 unsigned lastOffsetInWords = 5534 (InstanceEnd - InstanceBegin + WordSize - CharUnits::One()) / WordSize; 5535 if (lastOffsetInWords > endOfLastScanInWords) { 5536 skip(lastOffsetInWords - endOfLastScanInWords); 5540 // Null terminate the string. 5541 buffer.push_back(0); 5543 auto *Entry = CGObjC.CreateCStringLiteral( 5544 reinterpret_cast<char *>(buffer.data()), ObjCLabelType::ClassName); 5545 return getConstantGEP(CGM.getLLVMContext(), Entry, 0, 0); 5565 CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD,
5566 CharUnits beginOffset, CharUnits endOffset,
5567 bool ForStrongLayout, bool HasMRCWeakIvars) {
5568 // If this is MRC, and we're either building a strong layout or there
5569 // are no weak ivars, bail out early.
5570 llvm::Type *PtrTy = CGM.Int8PtrTy;
5571 if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
5572 !CGM.getLangOpts().ObjCAutoRefCount &&
5573 (ForStrongLayout || !HasMRCWeakIvars))
5574 return llvm::Constant::getNullValue(PtrTy);
5576 const ObjCInterfaceDecl *OI = OMD->getClassInterface();
5577 SmallVector<const ObjCIvarDecl*, 32> ivars;
5579 // GC layout strings include the complete object layout, possibly
5580 // inaccurately in the non-fragile ABI; the runtime knows how to fix this
5583 // ARC layout strings only include the class's ivars. In non-fragile
5584 // runtimes, that means starting at InstanceStart, rounded up to word
5585 // alignment. In fragile runtimes, there's no InstanceStart, so it means
5586 // starting at the offset of the first ivar, rounded up to word alignment.
5588 // MRC weak layout strings follow the ARC style.
5589 CharUnits baseOffset;
5590 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
5591 for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();
5592 IVD; IVD = IVD->getNextIvar())
5593 ivars.push_back(IVD);
5595 if (isNonFragileABI()) {
5596 baseOffset = beginOffset; // InstanceStart
5597 } else if (!ivars.empty()) {
5599 CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivars[0]));
5601 baseOffset = CharUnits::Zero();
5604 baseOffset = baseOffset.alignTo(CGM.getPointerAlign());
5607 CGM.getContext().DeepCollectObjCIvars(OI, true, ivars);
5609 baseOffset = CharUnits::Zero();
5613 return llvm::Constant::getNullValue(PtrTy);
5615 IvarLayoutBuilder builder(CGM, baseOffset, endOffset, ForStrongLayout);
5617 builder.visitAggregate(ivars.begin(), ivars.end(), CharUnits::Zero(),
5618 [&](const ObjCIvarDecl *ivar) -> CharUnits {
5619 return CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivar));
5622 if (!builder.hasBitmapData())
5623 return llvm::Constant::getNullValue(PtrTy);
5625 llvm::SmallVector<unsigned char, 4> buffer;
5626 llvm::Constant *C = builder.buildBitmap(*this, buffer);
5628 if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
5629 printf("\n%s ivar layout
for class '%s':
", 5630 ForStrongLayout ? "strong
" : "weak
", 5631 OMD->getClassInterface()->getName().str().c_str()); 5632 builder.dump(buffer); 5637 llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) { 5638 llvm::GlobalVariable *&Entry = MethodVarNames[Sel]; 5639 // FIXME: Avoid std::string in "Sel.
getAsString()
" 5641 Entry = CreateCStringLiteral(Sel.getAsString(), ObjCLabelType::MethodVarName); 5642 return getConstantGEP(VMContext, Entry, 0, 0); 5645 // FIXME: Merge into a single cstring creation function. 5646 llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) { 5647 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID)); 5650 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) { 5651 std::string TypeStr; 5652 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field); 5654 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr]; 5656 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType); 5657 return getConstantGEP(VMContext, Entry, 0, 0); 5660 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D, 5662 std::string TypeStr = 5663 CGM.getContext().getObjCEncodingForMethodDecl(D, Extended); 5665 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr]; 5667 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType); 5668 return getConstantGEP(VMContext, Entry, 0, 0); 5671 // FIXME: Merge into a single cstring creation function. 5672 llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) { 5673 llvm::GlobalVariable *&Entry = PropertyNames[Ident]; 5675 Entry = CreateCStringLiteral(Ident->getName(), ObjCLabelType::PropertyName); 5676 return getConstantGEP(VMContext, Entry, 0, 0); 5679 // FIXME: Merge into a single cstring creation function. 5680 // FIXME: This Decl should be more precise. 5682 CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD, 5683 const Decl *Container) { 5684 std::string TypeStr = 5685 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container); 5686 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr)); 5689 void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D, 5690 const ObjCContainerDecl *CD, 5691 SmallVectorImpl<char> &Name, 5692 bool ignoreCategoryNamespace) { 5693 llvm::raw_svector_ostream OS(Name); 5694 assert (CD && "Missing container
decl in GetNameForMethod
"); 5695 OS << '\01' << (D->isInstanceMethod() ? '-' : '+') 5696 << '[' << CD->getName(); 5697 if (!ignoreCategoryNamespace) 5698 if (const ObjCCategoryImplDecl *CID = 5699 dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext())) 5700 OS << '(' << *CID << ')'; 5701 OS << ' ' << D->getSelector().getAsString() << ']'; 5704 void CGObjCMac::FinishModule() { 5707 // Emit the dummy bodies for any protocols which were referenced but 5709 for (auto &entry : Protocols) { 5710 llvm::GlobalVariable *global = entry.second; 5711 if (global->hasInitializer()) 5714 ConstantInitBuilder builder(CGM); 5715 auto values = builder.beginStruct(ObjCTypes.ProtocolTy); 5716 values.addNullPointer(ObjCTypes.ProtocolExtensionPtrTy); 5717 values.add(GetClassName(entry.first->getName())); 5718 values.addNullPointer(ObjCTypes.ProtocolListPtrTy); 5719 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy); 5720 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy); 5721 values.finishAndSetAsInitializer(global); 5722 CGM.addCompilerUsedGlobal(global); 5725 // Add assembler directives to add lazy undefined symbol references 5726 // for classes which are referenced but not defined. This is 5727 // important for correct linker interaction. 5729 // FIXME: It would be nice if we had an LLVM construct for this. 5730 if ((!LazySymbols.empty() || !DefinedSymbols.empty()) && 5731 CGM.getTriple().isOSBinFormatMachO()) { 5732 SmallString<256> Asm; 5733 Asm += CGM.getModule().getModuleInlineAsm(); 5734 if (!Asm.empty() && Asm.back() != '\n') 5737 llvm::raw_svector_ostream OS(Asm); 5738 for (const auto *Sym : DefinedSymbols) 5739 OS << "\t.objc_class_name_
" << Sym->getName() << "=0\n
" 5740 << "\t.globl .objc_class_name_
" << Sym->getName() << "\n
"; 5741 for (const auto *Sym : LazySymbols) 5742 OS << "\t.lazy_reference .objc_class_name_
" << Sym->getName() << "\n
"; 5743 for (const auto &Category : DefinedCategoryNames) 5744 OS << "\t.objc_category_name_
" << Category << "=0\n
" 5745 << "\t.globl .objc_category_name_
" << Category << "\n
"; 5747 CGM.getModule().setModuleInlineAsm(OS.str()); 5751 CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm) 5752 : CGObjCCommonMac(cgm), ObjCTypes(cgm), ObjCEmptyCacheVar(nullptr), 5753 ObjCEmptyVtableVar(nullptr) { 5759 ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm) 5760 : VMContext(cgm.getLLVMContext()), CGM(cgm), ExternalProtocolPtrTy(nullptr) 5762 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 5763 ASTContext &Ctx = CGM.getContext(); 5765 ShortTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.ShortTy)); 5767 LongTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.LongTy)); 5768 Int8PtrTy = CGM.Int8PtrTy; 5769 Int8PtrPtrTy = CGM.Int8PtrPtrTy; 5771 // arm64 targets use "int" ivar offset variables. All others, 5772 // including OS X x86_64 and Windows x86_64, use "long" ivar offsets. 5773 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::aarch64) 5774 IvarOffsetVarTy = IntTy; 5776 IvarOffsetVarTy = LongTy; 5779 cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCIdType())); 5781 llvm::PointerType::getUnqual(ObjectPtrTy); 5783 cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCSelType())); 5785 // I'm not sure I like this. The implicit coordination is a bit 5786 // gross. We should solve this in a reasonable fashion because this 5787 // is a pretty common task (match some runtime data structure with 5788 // an LLVM data structure). 5790 // FIXME: This is leaked. 5791 // FIXME: Merge with rewriter code? 5793 // struct _objc_super { 5797 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct, 5798 Ctx.getTranslationUnitDecl(), 5799 SourceLocation(), SourceLocation(), 5800 &Ctx.Idents.get("_objc_super
")); 5801 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 5802 nullptr, Ctx.getObjCIdType(), nullptr, nullptr, 5803 false, ICIS_NoInit)); 5804 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 5805 nullptr, Ctx.getObjCClassType(), nullptr, 5806 nullptr, false, ICIS_NoInit)); 5807 RD->completeDefinition(); 5809 SuperCTy = Ctx.getTagDeclType(RD); 5810 SuperPtrCTy = Ctx.getPointerType(SuperCTy); 5812 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy)); 5813 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy); 5817 // char *attributes; 5819 PropertyTy = llvm::StructType::create("struct._prop_t
", Int8PtrTy, Int8PtrTy); 5821 // struct _prop_list_t { 5822 // uint32_t entsize; // sizeof(struct _prop_t) 5823 // uint32_t count_of_properties; 5824 // struct _prop_t prop_list[count_of_properties]; 5826 PropertyListTy = llvm::StructType::create( 5827 "struct._prop_list_t
", IntTy, IntTy, llvm::ArrayType::get(PropertyTy, 0)); 5828 // struct _prop_list_t * 5829 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy); 5831 // struct _objc_method { 5833 // char *method_type; 5836 MethodTy = llvm::StructType::create("struct._objc_method
", SelectorPtrTy, 5837 Int8PtrTy, Int8PtrTy); 5839 // struct _objc_cache * 5840 CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache
"); 5841 CachePtrTy = llvm::PointerType::getUnqual(CacheTy); 5844 ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) 5845 : ObjCCommonTypesHelper(cgm) { 5846 // struct _objc_method_description { 5850 MethodDescriptionTy = llvm::StructType::create( 5851 "struct._objc_method_description
", SelectorPtrTy, Int8PtrTy); 5853 // struct _objc_method_description_list { 5855 // struct _objc_method_description[1]; 5857 MethodDescriptionListTy = 5858 llvm::StructType::create("struct._objc_method_description_list
", IntTy, 5859 llvm::ArrayType::get(MethodDescriptionTy, 0)); 5861 // struct _objc_method_description_list * 5862 MethodDescriptionListPtrTy = 5863 llvm::PointerType::getUnqual(MethodDescriptionListTy); 5865 // Protocol description structures 5867 // struct _objc_protocol_extension { 5868 // uint32_t size; // sizeof(struct _objc_protocol_extension) 5869 // struct _objc_method_description_list *optional_instance_methods; 5870 // struct _objc_method_description_list *optional_class_methods; 5871 // struct _objc_property_list *instance_properties; 5872 // const char ** extendedMethodTypes; 5873 // struct _objc_property_list *class_properties; 5875 ProtocolExtensionTy = llvm::StructType::create( 5876 "struct._objc_protocol_extension
", IntTy, MethodDescriptionListPtrTy, 5877 MethodDescriptionListPtrTy, PropertyListPtrTy, Int8PtrPtrTy, 5880 // struct _objc_protocol_extension * 5881 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy); 5883 // Handle recursive construction of Protocol and ProtocolList types 5886 llvm::StructType::create(VMContext, "struct._objc_protocol
"); 5889 llvm::StructType::create(VMContext, "struct._objc_protocol_list
"); 5890 ProtocolListTy->setBody(llvm::PointerType::getUnqual(ProtocolListTy), LongTy, 5891 llvm::ArrayType::get(ProtocolTy, 0)); 5893 // struct _objc_protocol { 5894 // struct _objc_protocol_extension *isa; 5895 // char *protocol_name; 5896 // struct _objc_protocol **_objc_protocol_list; 5897 // struct _objc_method_description_list *instance_methods; 5898 // struct _objc_method_description_list *class_methods; 5900 ProtocolTy->setBody(ProtocolExtensionPtrTy, Int8PtrTy, 5901 llvm::PointerType::getUnqual(ProtocolListTy), 5902 MethodDescriptionListPtrTy, MethodDescriptionListPtrTy); 5904 // struct _objc_protocol_list * 5905 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy); 5907 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy); 5909 // Class description structures 5911 // struct _objc_ivar { 5916 IvarTy = llvm::StructType::create("struct._objc_ivar
", Int8PtrTy, Int8PtrTy, 5919 // struct _objc_ivar_list * 5921 llvm::StructType::create(VMContext, "struct._objc_ivar_list
"); 5922 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy); 5924 // struct _objc_method_list * 5926 llvm::StructType::create(VMContext, "struct._objc_method_list
"); 5927 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy); 5929 // struct _objc_class_extension * 5930 ClassExtensionTy = llvm::StructType::create( 5931 "struct._objc_class_extension
", IntTy, Int8PtrTy, PropertyListPtrTy); 5932 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy); 5934 ClassTy = llvm::StructType::create(VMContext, "struct._objc_class
"); 5936 // struct _objc_class { 5938 // Class super_class; 5942 // long instance_size; 5943 // struct _objc_ivar_list *ivars; 5944 // struct _objc_method_list *methods; 5945 // struct _objc_cache *cache; 5946 // struct _objc_protocol_list *protocols; 5947 // char *ivar_layout; 5948 // struct _objc_class_ext *ext; 5950 ClassTy->setBody(llvm::PointerType::getUnqual(ClassTy), 5951 llvm::PointerType::getUnqual(ClassTy), Int8PtrTy, LongTy, 5952 LongTy, LongTy, IvarListPtrTy, MethodListPtrTy, CachePtrTy, 5953 ProtocolListPtrTy, Int8PtrTy, ClassExtensionPtrTy); 5955 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy); 5957 // struct _objc_category { 5958 // char *category_name; 5959 // char *class_name; 5960 // struct _objc_method_list *instance_method; 5961 // struct _objc_method_list *class_method; 5962 // struct _objc_protocol_list *protocols; 5963 // uint32_t size; // sizeof(struct _objc_category) 5964 // struct _objc_property_list *instance_properties;// category's @property 5965 // struct _objc_property_list *class_properties; 5967 CategoryTy = llvm::StructType::create( 5968 "struct._objc_category
", Int8PtrTy, Int8PtrTy, MethodListPtrTy, 5969 MethodListPtrTy, ProtocolListPtrTy, IntTy, PropertyListPtrTy, 5972 // Global metadata structures 5974 // struct _objc_symtab { 5975 // long sel_ref_cnt; 5977 // short cls_def_cnt; 5978 // short cat_def_cnt; 5979 // char *defs[cls_def_cnt + cat_def_cnt]; 5981 SymtabTy = llvm::StructType::create("struct._objc_symtab
", LongTy, 5982 SelectorPtrTy, ShortTy, ShortTy, 5983 llvm::ArrayType::get(Int8PtrTy, 0)); 5984 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy); 5986 // struct _objc_module { 5988 // long size; // sizeof(struct _objc_module) 5990 // struct _objc_symtab* symtab; 5992 ModuleTy = llvm::StructType::create("struct._objc_module
", LongTy, LongTy, 5993 Int8PtrTy, SymtabPtrTy); 5995 // FIXME: This is the size of the setjmp buffer and should be target 5996 // specific. 18 is what's used on 32-bit X86. 5997 uint64_t SetJmpBufferSize = 18; 6000 llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4); 6002 ExceptionDataTy = llvm::StructType::create( 6003 "struct._objc_exception_data
", 6004 llvm::ArrayType::get(CGM.Int32Ty, SetJmpBufferSize), StackPtrTy); 6007 ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm) 6008 : ObjCCommonTypesHelper(cgm) { 6009 // struct _method_list_t { 6010 // uint32_t entsize; // sizeof(struct _objc_method) 6011 // uint32_t method_count; 6012 // struct _objc_method method_list[method_count]; 6015 llvm::StructType::create("struct.__method_list_t
", IntTy, IntTy, 6016 llvm::ArrayType::get(MethodTy, 0)); 6017 // struct method_list_t * 6018 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy); 6020 // struct _protocol_t { 6022 // const char * const protocol_name; 6023 // const struct _protocol_list_t * protocol_list; // super protocols 6024 // const struct method_list_t * const instance_methods; 6025 // const struct method_list_t * const class_methods; 6026 // const struct method_list_t *optionalInstanceMethods; 6027 // const struct method_list_t *optionalClassMethods; 6028 // const struct _prop_list_t * properties; 6029 // const uint32_t size; // sizeof(struct _protocol_t) 6030 // const uint32_t flags; // = 0 6031 // const char ** extendedMethodTypes; 6032 // const char *demangledName; 6033 // const struct _prop_list_t * class_properties; 6036 // Holder for struct _protocol_list_t * 6037 ProtocolListnfABITy = 6038 llvm::StructType::create(VMContext, "struct._objc_protocol_list
"); 6040 ProtocolnfABITy = llvm::StructType::create( 6041 "struct._protocol_t
", ObjectPtrTy, Int8PtrTy, 6042 llvm::PointerType::getUnqual(ProtocolListnfABITy), MethodListnfABIPtrTy, 6043 MethodListnfABIPtrTy, MethodListnfABIPtrTy, MethodListnfABIPtrTy, 6044 PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy, Int8PtrTy, 6047 // struct _protocol_t* 6048 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy); 6050 // struct _protocol_list_t { 6051 // long protocol_count; // Note, this is 32/64 bit 6052 // struct _protocol_t *[protocol_count]; 6054 ProtocolListnfABITy->setBody(LongTy, 6055 llvm::ArrayType::get(ProtocolnfABIPtrTy, 0)); 6057 // struct _objc_protocol_list* 6058 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy); 6061 // unsigned [long] int *offset; // pointer to ivar offset location 6064 // uint32_t alignment; 6067 IvarnfABITy = llvm::StructType::create( 6068 "struct._ivar_t
", llvm::PointerType::getUnqual(IvarOffsetVarTy), 6069 Int8PtrTy, Int8PtrTy, IntTy, IntTy); 6071 // struct _ivar_list_t { 6072 // uint32 entsize; // sizeof(struct _ivar_t) 6074 // struct _iver_t list[count]; 6077 llvm::StructType::create("struct._ivar_list_t
", IntTy, IntTy, 6078 llvm::ArrayType::get(IvarnfABITy, 0)); 6080 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy); 6082 // struct _class_ro_t { 6083 // uint32_t const flags; 6084 // uint32_t const instanceStart; 6085 // uint32_t const instanceSize; 6086 // uint32_t const reserved; // only when building for 64bit targets 6087 // const uint8_t * const ivarLayout; 6088 // const char *const name; 6089 // const struct _method_list_t * const baseMethods; 6090 // const struct _objc_protocol_list *const baseProtocols; 6091 // const struct _ivar_list_t *const ivars; 6092 // const uint8_t * const weakIvarLayout; 6093 // const struct _prop_list_t * const properties; 6096 // FIXME. Add 'reserved' field in 64bit abi mode! 6097 ClassRonfABITy = llvm::StructType::create( 6098 "struct._class_ro_t
", IntTy, IntTy, IntTy, Int8PtrTy, Int8PtrTy, 6099 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, IvarListnfABIPtrTy, 6100 Int8PtrTy, PropertyListPtrTy); 6102 // ImpnfABITy - LLVM for id (*)(id, SEL, ...) 6103 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy }; 6104 ImpnfABITy = llvm::FunctionType::get(ObjectPtrTy, params, false) 6107 // struct _class_t { 6108 // struct _class_t *isa; 6109 // struct _class_t * const superclass; 6112 // struct class_ro_t *ro; 6115 ClassnfABITy = llvm::StructType::create(VMContext, "struct._class_t
"); 6116 ClassnfABITy->setBody(llvm::PointerType::getUnqual(ClassnfABITy), 6117 llvm::PointerType::getUnqual(ClassnfABITy), CachePtrTy, 6118 llvm::PointerType::getUnqual(ImpnfABITy), 6119 llvm::PointerType::getUnqual(ClassRonfABITy)); 6121 // LLVM for struct _class_t * 6122 ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy); 6124 // struct _category_t { 6125 // const char * const name; 6126 // struct _class_t *const cls; 6127 // const struct _method_list_t * const instance_methods; 6128 // const struct _method_list_t * const class_methods; 6129 // const struct _protocol_list_t * const protocols; 6130 // const struct _prop_list_t * const properties; 6131 // const struct _prop_list_t * const class_properties; 6132 // const uint32_t size; 6134 CategorynfABITy = llvm::StructType::create( 6135 "struct._category_t
", Int8PtrTy, ClassnfABIPtrTy, MethodListnfABIPtrTy, 6136 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, PropertyListPtrTy, 6137 PropertyListPtrTy, IntTy); 6139 // New types for nonfragile abi messaging. 6140 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 6141 ASTContext &Ctx = CGM.getContext(); 6143 // MessageRefTy - LLVM for: 6144 // struct _message_ref_t { 6149 // First the clang type for struct _message_ref_t 6150 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct, 6151 Ctx.getTranslationUnitDecl(), 6152 SourceLocation(), SourceLocation(), 6153 &Ctx.Idents.get("_message_ref_t
")); 6154 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 6155 nullptr, Ctx.VoidPtrTy, nullptr, nullptr, false, 6157 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 6158 nullptr, Ctx.getObjCSelType(), nullptr, nullptr, 6159 false, ICIS_NoInit)); 6160 RD->completeDefinition(); 6162 MessageRefCTy = Ctx.getTagDeclType(RD); 6163 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy); 6164 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy)); 6166 // MessageRefPtrTy - LLVM for struct _message_ref_t* 6167 MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy); 6169 // SuperMessageRefTy - LLVM for: 6170 // struct _super_message_ref_t { 6171 // SUPER_IMP messenger; 6174 SuperMessageRefTy = llvm::StructType::create("struct._super_message_ref_t
", 6175 ImpnfABITy, SelectorPtrTy); 6177 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t* 6178 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy); 6181 // struct objc_typeinfo { 6182 // const void** vtable; // objc_ehtype_vtable + 2 6183 // const char* name; // c++ typeinfo string 6186 EHTypeTy = llvm::StructType::create("struct._objc_typeinfo
", 6187 llvm::PointerType::getUnqual(Int8PtrTy), 6188 Int8PtrTy, ClassnfABIPtrTy); 6189 EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy); 6192 llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() { 6193 FinishNonFragileABIModule(); 6198 void CGObjCNonFragileABIMac::AddModuleClassList( 6199 ArrayRef<llvm::GlobalValue *> Container, StringRef SymbolName, 6200 StringRef SectionName) { 6201 unsigned NumClasses = Container.size(); 6206 SmallVector<llvm::Constant*, 8> Symbols(NumClasses); 6207 for (unsigned i=0; i<NumClasses; i++) 6208 Symbols[i] = llvm::ConstantExpr::getBitCast(Container[i], 6209 ObjCTypes.Int8PtrTy); 6210 llvm::Constant *Init = 6211 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy, 6215 // Section name is obtained by calling GetSectionName, which returns 6216 // sections in the __DATA segment on MachO. 6217 assert((!CGM.getTriple().isOSBinFormatMachO() || 6218 SectionName.startswith("__DATA
")) && 6219 "SectionName expected to start with __DATA on MachO
"); 6220 llvm::GlobalValue::LinkageTypes LT = 6221 getLinkageTypeForObjCMetadata(CGM, SectionName); 6222 llvm::GlobalVariable *GV = 6223 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, LT, Init, 6226 llvm::Align(CGM.getDataLayout().getABITypeAlignment(Init->getType()))); 6227 GV->setSection(SectionName); 6228 CGM.addCompilerUsedGlobal(GV); 6231 void CGObjCNonFragileABIMac::FinishNonFragileABIModule() { 6232 // nonfragile abi has no module definition. 6234 // Build list of all implemented class addresses in array 6235 // L_OBJC_LABEL_CLASS_$. 6237 for (unsigned i=0, NumClasses=ImplementedClasses.size(); i<NumClasses; i++) { 6238 const ObjCInterfaceDecl *ID = ImplementedClasses[i]; 6240 if (ObjCImplementationDecl *IMP = ID->getImplementation()) 6241 // We are implementing a weak imported interface. Give it external linkage 6242 if (ID->isWeakImported() && !IMP->isWeakImported()) { 6243 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage); 6244 DefinedMetaClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage); 6248 AddModuleClassList(DefinedClasses, "OBJC_LABEL_CLASS_$
", 6249 GetSectionName("__objc_classlist
", 6250 "regular,no_dead_strip
")); 6252 AddModuleClassList(DefinedNonLazyClasses, "OBJC_LABEL_NONLAZY_CLASS_$
", 6253 GetSectionName("__objc_nlclslist
", 6254 "regular,no_dead_strip
")); 6256 // Build list of all implemented category addresses in array 6257 // L_OBJC_LABEL_CATEGORY_$. 6258 AddModuleClassList(DefinedCategories, "OBJC_LABEL_CATEGORY_$
", 6259 GetSectionName("__objc_catlist
", 6260 "regular,no_dead_strip
")); 6261 AddModuleClassList(DefinedStubCategories, "OBJC_LABEL_STUB_CATEGORY_$
", 6262 GetSectionName("__objc_catlist2
", 6263 "regular,no_dead_strip
")); 6264 AddModuleClassList(DefinedNonLazyCategories, "OBJC_LABEL_NONLAZY_CATEGORY_$
", 6265 GetSectionName("__objc_nlcatlist
", 6266 "regular,no_dead_strip
")); 6275 bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
6276 // At various points we've experimented with using vtable-based
6277 // dispatch for all methods.
6278 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
6279 case CodeGenOptions::Legacy:
6281 case CodeGenOptions::NonLegacy:
6283 case CodeGenOptions::Mixed:
6287 // If so, see whether this selector is in the white-list of things which must
6288 // use the new dispatch convention. We lazily build a dense set for this.
6289 if (VTableDispatchMethods.empty()) {
6290 VTableDispatchMethods.insert(GetNullarySelector("alloc
")); 6291 VTableDispatchMethods.insert(GetNullarySelector("class")); 6292 VTableDispatchMethods.insert(GetNullarySelector("self")); 6293 VTableDispatchMethods.insert(GetNullarySelector("isFlipped
")); 6294 VTableDispatchMethods.insert(GetNullarySelector("length")); 6295 VTableDispatchMethods.insert(GetNullarySelector("count
")); 6297 // These are vtable-based if GC is disabled. 6298 // Optimistically use vtable dispatch for hybrid compiles. 6299 if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) { 6300 VTableDispatchMethods.insert(GetNullarySelector("retain
")); 6301 VTableDispatchMethods.insert(GetNullarySelector("release
")); 6302 VTableDispatchMethods.insert(GetNullarySelector("autorelease
")); 6305 VTableDispatchMethods.insert(GetUnarySelector("allocWithZone
")); 6306 VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass
")); 6307 VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector
")); 6308 VTableDispatchMethods.insert(GetUnarySelector("objectForKey
")); 6309 VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex
")); 6310 VTableDispatchMethods.insert(GetUnarySelector("isEqualToString
")); 6311 VTableDispatchMethods.insert(GetUnarySelector("isEqual
")); 6313 // These are vtable-based if GC is enabled. 6314 // Optimistically use vtable dispatch for hybrid compiles. 6315 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) { 6316 VTableDispatchMethods.insert(GetNullarySelector("hash
")); 6317 VTableDispatchMethods.insert(GetUnarySelector("addObject
")); 6319 // "countByEnumeratingWithState:objects:count
" 6320 IdentifierInfo *KeyIdents[] = { 6321 &CGM.getContext().Idents.get("countByEnumeratingWithState
"), 6322 &CGM.getContext().Idents.get("objects
"), 6323 &CGM.getContext().Idents.get("count
") 6325 VTableDispatchMethods.insert( 6326 CGM.getContext().Selectors.getSelector(3, KeyIdents)); 6330 return VTableDispatchMethods.count(Sel); 6348 llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
6350 unsigned InstanceStart,
6351 unsigned InstanceSize,
6352 const ObjCImplementationDecl *ID) {
6353 std::string ClassName = ID->getObjCRuntimeNameAsString();
6355 CharUnits beginInstance = CharUnits::fromQuantity(InstanceStart);
6356 CharUnits endInstance = CharUnits::fromQuantity(InstanceSize);
6358 bool hasMRCWeak = false;
6359 if (CGM.getLangOpts().ObjCAutoRefCount)
6360 flags |= NonFragileABI_Class_CompiledByARC;
6361 else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))
6362 flags |= NonFragileABI_Class_HasMRCWeakIvars;
6364 ConstantInitBuilder builder(CGM);
6365 auto values = builder.beginStruct(ObjCTypes.ClassRonfABITy);
6367 values.addInt(ObjCTypes.IntTy, flags);
6368 values.addInt(ObjCTypes.IntTy, InstanceStart);
6369 values.addInt(ObjCTypes.IntTy, InstanceSize);
6370 values.add((flags & NonFragileABI_Class_Meta)
6371 ? GetIvarLayoutName(nullptr, ObjCTypes)
6372 : BuildStrongIvarLayout(ID, beginInstance, endInstance));
6373 values.add(GetClassName(ID->getObjCRuntimeNameAsString()));
6375 // const struct _method_list_t * const baseMethods;
6376 SmallVector<const ObjCMethodDecl*, 16> methods;
6377 if (flags & NonFragileABI_Class_Meta) {
6378 for (const auto *MD : ID->class_methods())
6379 if (!MD->isDirectMethod())
6380 methods.push_back(MD);
6382 for (const auto *MD : ID->instance_methods())
6383 if (!MD->isDirectMethod())
6384 methods.push_back(MD);
6387 values.add(emitMethodList(ID->getObjCRuntimeNameAsString(),
6388 (flags & NonFragileABI_Class_Meta)
6389 ? MethodListType::ClassMethods
6390 : MethodListType::InstanceMethods,
6393 const ObjCInterfaceDecl *OID = ID->getClassInterface();
6394 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer
"); 6395 values.add(EmitProtocolList("_OBJC_CLASS_PROTOCOLS_$_
" 6396 + OID->getObjCRuntimeNameAsString(), 6397 OID->all_referenced_protocol_begin(), 6398 OID->all_referenced_protocol_end())); 6400 if (flags & NonFragileABI_Class_Meta) { 6401 values.addNullPointer(ObjCTypes.IvarListnfABIPtrTy); 6402 values.add(GetIvarLayoutName(nullptr, ObjCTypes)); 6403 values.add(EmitPropertyList( 6404 "_OBJC_$_CLASS_PROP_LIST_
" + ID->getObjCRuntimeNameAsString(), 6405 ID, ID->getClassInterface(), ObjCTypes, true)); 6407 values.add(EmitIvarList(ID)); 6408 values.add(BuildWeakIvarLayout(ID, beginInstance, endInstance, hasMRCWeak)); 6409 values.add(EmitPropertyList( 6410 "_OBJC_$_PROP_LIST_
" + ID->getObjCRuntimeNameAsString(), 6411 ID, ID->getClassInterface(), ObjCTypes, false)); 6414 llvm::SmallString<64> roLabel; 6415 llvm::raw_svector_ostream(roLabel) 6416 << ((flags & NonFragileABI_Class_Meta) ? "_OBJC_METACLASS_RO_$_
" 6417 : "_OBJC_CLASS_RO_$_
") 6420 return finishAndCreateGlobal(values, roLabel, CGM); 6433 llvm::GlobalVariable *
6434 CGObjCNonFragileABIMac::BuildClassObject(const ObjCInterfaceDecl *CI,
6436 llvm::Constant *IsAGV,
6437 llvm::Constant *SuperClassGV,
6438 llvm::Constant *ClassRoGV,
6439 bool HiddenVisibility) {
6440 ConstantInitBuilder builder(CGM);
6441 auto values = builder.beginStruct(ObjCTypes.ClassnfABITy);
6444 values.add(SuperClassGV);
6446 values.addNullPointer(ObjCTypes.ClassnfABIPtrTy);
6448 values.add(ObjCEmptyCacheVar);
6449 values.add(ObjCEmptyVtableVar);
6450 values.add(ClassRoGV);
6452 llvm::GlobalVariable *GV =
6453 cast<llvm::GlobalVariable>(GetClassGlobal(CI, isMetaclass, ForDefinition));
6454 values.finishAndSetAsInitializer(GV);
6456 if (CGM.getTriple().isOSBinFormatMachO())
6457 GV->setSection("__DATA, __objc_data
"); 6458 GV->setAlignment(llvm::Align( 6459 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassnfABITy))); 6460 if (!CGM.getTriple().isOSBinFormatCOFF()) 6461 if (HiddenVisibility) 6462 GV->setVisibility(llvm::GlobalValue::HiddenVisibility); 6466 bool CGObjCNonFragileABIMac::ImplementationIsNonLazy( 6467 const ObjCImplDecl *OD) const { 6468 return OD->getClassMethod(GetNullarySelector("load
")) != nullptr || 6469 OD->getClassInterface()->hasAttr<ObjCNonLazyClassAttr>() || 6470 OD->hasAttr<ObjCNonLazyClassAttr>(); 6473 void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID, 6474 uint32_t &InstanceStart, 6475 uint32_t &InstanceSize) { 6476 const ASTRecordLayout &RL = 6477 CGM.getContext().getASTObjCImplementationLayout(OID); 6479 // InstanceSize is really instance end. 6480 InstanceSize = RL.getDataSize().getQuantity(); 6482 // If there are no fields, the start is the same as the end. 6483 if (!RL.getFieldCount()) 6484 InstanceStart = InstanceSize; 6486 InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth(); 6489 static llvm::GlobalValue::DLLStorageClassTypes getStorage(CodeGenModule &CGM, 6491 IdentifierInfo &II = CGM.getContext().Idents.get(Name); 6492 TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl(); 6493 DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl); 6495 const VarDecl *VD = nullptr; 6496 for (const auto &Result : DC->lookup(&II)) 6497 if ((VD = dyn_cast<VarDecl>(Result))) 6501 return llvm::GlobalValue::DLLImportStorageClass; 6502 if (VD->hasAttr<DLLExportAttr>()) 6503 return llvm::GlobalValue::DLLExportStorageClass; 6504 if (VD->hasAttr<DLLImportAttr>()) 6505 return llvm::GlobalValue::DLLImportStorageClass; 6506 return llvm::GlobalValue::DefaultStorageClass; 6509 void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { 6510 if (!ObjCEmptyCacheVar) { 6512 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CacheTy, false, 6513 llvm::GlobalValue::ExternalLinkage, nullptr, 6514 "_objc_empty_cache
"); 6515 if (CGM.getTriple().isOSBinFormatCOFF()) 6516 ObjCEmptyCacheVar->setDLLStorageClass(getStorage(CGM, "_objc_empty_cache
")); 6518 // Only OS X with deployment version <10.9 use the empty vtable symbol 6519 const llvm::Triple &Triple = CGM.getTarget().getTriple(); 6520 if (Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 9)) 6521 ObjCEmptyVtableVar = 6522 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ImpnfABITy, false, 6523 llvm::GlobalValue::ExternalLinkage, nullptr, 6524 "_objc_empty_vtable
"); 6526 ObjCEmptyVtableVar = 6527 llvm::ConstantPointerNull::get(ObjCTypes.ImpnfABITy->getPointerTo()); 6530 // FIXME: Is this correct (that meta class size is never computed)? 6531 uint32_t InstanceStart = 6532 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy); 6533 uint32_t InstanceSize = InstanceStart; 6534 uint32_t flags = NonFragileABI_Class_Meta; 6536 llvm::Constant *SuperClassGV, *IsAGV; 6538 const auto *CI = ID->getClassInterface(); 6539 assert(CI && "CGObjCNonFragileABIMac::GenerateClass -
class is 0");
6542 bool classIsHidden = (CGM.
getTriple().isOSBinFormatCOFF())
6543 ? !CI->hasAttr<DLLExportAttr>()
6556 if (!CI->getSuperClass()) {
6573 llvm::GlobalVariable *CLASS_RO_GV =
6574 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
6576 llvm::GlobalVariable *MetaTClass =
6577 BuildClassObject(CI,
true,
6578 IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden);
6580 DefinedMetaClasses.push_back(MetaTClass);
6603 if (!CI->getSuperClass()) {
6605 SuperClassGV =
nullptr;
6608 const auto *Super = CI->getSuperClass();
6612 GetClassSizeInfo(ID, InstanceStart, InstanceSize);
6614 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
6616 llvm::GlobalVariable *ClassMD =
6617 BuildClassObject(CI,
false,
6618 MetaTClass, SuperClassGV, CLASS_RO_GV, classIsHidden);
6620 DefinedClasses.push_back(ClassMD);
6621 ImplementedClasses.push_back(CI);
6624 if (ImplementationIsNonLazy(ID))
6625 DefinedNonLazyClasses.push_back(ClassMD);
6631 MethodDefinitions.clear();
6648 llvm::Constant *Init =
6649 llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD),
6650 ObjCTypes.getExternalProtocolPtrTy());
6652 std::string ProtocolName(
"_OBJC_PROTOCOL_REFERENCE_$_");
6657 llvm::GlobalVariable *PTGV = CGM.
getModule().getGlobalVariable(ProtocolName);
6660 PTGV =
new llvm::GlobalVariable(CGM.
getModule(), Init->getType(),
false,
6661 llvm::GlobalValue::WeakAnyLinkage, Init,
6663 PTGV->setSection(GetSectionName(
"__objc_protorefs",
6664 "coalesced,no_dead_strip"));
6667 if (!CGM.
getTriple().isOSBinFormatMachO())
6668 PTGV->setComdat(CGM.
getModule().getOrInsertComdat(ProtocolName));
6687 const char *Prefix =
"_OBJC_$_CATEGORY_";
6691 ExtCatName +=
"_$_";
6695 auto values = builder.
beginStruct(ObjCTypes.CategorynfABITy);
6699 std::string listName =
6704 for (
const auto *MD : OCD->
methods()) {
6708 instanceMethods.push_back(MD);
6710 classMethods.push_back(MD);
6714 values.add(emitMethodList(listName, MethodListType::CategoryInstanceMethods,
6716 values.add(emitMethodList(listName, MethodListType::CategoryClassMethods,
6725 values.add(EmitProtocolList(
"_OBJC_CATEGORY_PROTOCOLS_$_" 6730 values.add(EmitPropertyList(
"_OBJC_$_PROP_LIST_" + ExtName.str(),
6732 values.add(EmitPropertyList(
"_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(),
6735 values.addNullPointer(ObjCTypes.ProtocolListnfABIPtrTy);
6736 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
6737 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
6740 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.CategorynfABITy);
6741 values.addInt(ObjCTypes.IntTy, Size);
6743 llvm::GlobalVariable *GCATV =
6746 if (Interface->
hasAttr<ObjCClassStubAttr>())
6747 DefinedStubCategories.push_back(GCATV);
6749 DefinedCategories.push_back(GCATV);
6752 if (ImplementationIsNonLazy(OCD))
6753 DefinedNonLazyCategories.push_back(GCATV);
6755 MethodDefinitions.clear();
6770 auto method = builder.
beginStruct(ObjCTypes.MethodTy);
6771 method.addBitCast(GetMethodVarName(MD->
getSelector()),
6772 ObjCTypes.SelectorPtrTy);
6773 method.add(GetMethodVarType(MD));
6777 method.addNullPointer(ObjCTypes.Int8PtrTy);
6779 llvm::Function *fn = GetMethodDefinition(MD);
6780 assert(fn &&
"no definition for method?");
6781 method.addBitCast(fn, ObjCTypes.Int8PtrTy);
6784 method.finishAndAddTo(builder);
6799 if (methods.empty())
6800 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
6805 case MethodListType::CategoryInstanceMethods:
6806 prefix =
"_OBJC_$_CATEGORY_INSTANCE_METHODS_";
6807 forProtocol =
false;
6809 case MethodListType::CategoryClassMethods:
6810 prefix =
"_OBJC_$_CATEGORY_CLASS_METHODS_";
6811 forProtocol =
false;
6813 case MethodListType::InstanceMethods:
6814 prefix =
"_OBJC_$_INSTANCE_METHODS_";
6815 forProtocol =
false;
6817 case MethodListType::ClassMethods:
6818 prefix =
"_OBJC_$_CLASS_METHODS_";
6819 forProtocol =
false;
6822 case MethodListType::ProtocolInstanceMethods:
6823 prefix =
"_OBJC_$_PROTOCOL_INSTANCE_METHODS_";
6826 case MethodListType::ProtocolClassMethods:
6827 prefix =
"_OBJC_$_PROTOCOL_CLASS_METHODS_";
6830 case MethodListType::OptionalProtocolInstanceMethods:
6831 prefix =
"_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_";
6834 case MethodListType::OptionalProtocolClassMethods:
6835 prefix =
"_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_";
6844 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.MethodTy);
6845 values.addInt(ObjCTypes.IntTy, Size);
6847 values.addInt(ObjCTypes.IntTy, methods.size());
6848 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
6849 for (
auto MD : methods)
6850 emitMethodConstant(methodArray, MD, forProtocol);
6851 methodArray.finishAndAddTo(values);
6855 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListnfABIPtrTy);
6860 llvm::GlobalVariable *
6868 llvm::GlobalVariable *IvarOffsetGV = CGM.
getModule().getGlobalVariable(Name);
6869 if (!IvarOffsetGV) {
6871 new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.IvarOffsetVarTy,
6873 nullptr, Name.str());
6874 if (CGM.
getTriple().isOSBinFormatCOFF()) {
6875 bool IsPrivateOrPackage =
6881 if (ContainingID->
hasAttr<DLLImportAttr>())
6883 ->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
6884 else if (ContainingID->
hasAttr<DLLExportAttr>() && !IsPrivateOrPackage)
6886 ->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
6889 return IvarOffsetGV;
6895 unsigned long int Offset) {
6896 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
6897 IvarOffsetGV->setInitializer(
6898 llvm::ConstantInt::get(ObjCTypes.IvarOffsetVarTy, Offset));
6899 IvarOffsetGV->setAlignment(llvm::Align(
6900 CGM.
getDataLayout().getABITypeAlignment(ObjCTypes.IvarOffsetVarTy)));
6902 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
6916 if (isClassLayoutKnownStatically(ID))
6917 IvarOffsetGV->setConstant(
true);
6919 if (CGM.
getTriple().isOSBinFormatMachO())
6920 IvarOffsetGV->setSection(
"__DATA, __objc_ivar");
6921 return IvarOffsetGV;
6941 llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
6946 ivarList.addInt(ObjCTypes.IntTy,
6947 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.IvarnfABITy));
6948 auto ivarCountSlot = ivarList.addPlaceholder();
6949 auto ivars = ivarList.beginArray(ObjCTypes.IvarnfABITy);
6952 assert(OID &&
"CGObjCNonFragileABIMac::EmitIvarList - null interface");
6959 if (!IVD->getDeclName())
6962 auto ivar = ivars.beginStruct(ObjCTypes.IvarnfABITy);
6964 ComputeIvarBaseOffset(CGM, ID, IVD)));
6965 ivar.add(GetMethodVarName(IVD->getIdentifier()));
6966 ivar.add(GetMethodVarType(IVD));
6969 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(FieldTy);
6971 IVD->getType().getTypePtr()) >> 3;
6972 Align = llvm::Log2_32(Align);
6973 ivar.addInt(ObjCTypes.IntTy, Align);
6979 ivar.addInt(ObjCTypes.IntTy, Size);
6980 ivar.finishAndAddTo(ivars);
6983 if (ivars.empty()) {
6986 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
6989 auto ivarCount = ivars.size();
6990 ivars.finishAndAddTo(ivarList);
6991 ivarList.fillPlaceholderWithInt(ivarCountSlot, ObjCTypes.IntTy, ivarCount);
6993 const char *Prefix =
"_OBJC_$_INSTANCE_VARIABLES_";
6997 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy);
7000 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(
7002 llvm::GlobalVariable *&Entry = Protocols[PD->
getIdentifier()];
7009 llvm::raw_svector_ostream(Protocol) <<
"_OBJC_PROTOCOL_$_" 7012 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolnfABITy,
7015 if (!CGM.
getTriple().isOSBinFormatMachO())
7016 Entry->setComdat(CGM.
getModule().getOrInsertComdat(Protocol));
7042 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
7044 llvm::GlobalVariable *Entry = Protocols[PD->
getIdentifier()];
7047 if (Entry && Entry->hasInitializer())
7052 "emitting protocol metadata without definition");
7055 auto methodLists = ProtocolMethodLists::get(PD);
7058 auto values = builder.
beginStruct(ObjCTypes.ProtocolnfABITy);
7061 values.addNullPointer(ObjCTypes.ObjectPtrTy);
7062 values.add(GetClassName(PD->getObjCRuntimeNameAsString()));
7063 values.add(EmitProtocolList(
"_OBJC_$_PROTOCOL_REFS_" 7064 + PD->getObjCRuntimeNameAsString(),
7065 PD->protocol_begin(),
7066 PD->protocol_end()));
7067 values.add(methodLists.emitMethodList(
this, PD,
7068 ProtocolMethodLists::RequiredInstanceMethods));
7069 values.add(methodLists.emitMethodList(
this, PD,
7070 ProtocolMethodLists::RequiredClassMethods));
7071 values.add(methodLists.emitMethodList(
this, PD,
7072 ProtocolMethodLists::OptionalInstanceMethods));
7073 values.add(methodLists.emitMethodList(
this, PD,
7074 ProtocolMethodLists::OptionalClassMethods));
7075 values.add(EmitPropertyList(
7076 "_OBJC_$_PROP_LIST_" + PD->getObjCRuntimeNameAsString(),
7077 nullptr, PD, ObjCTypes,
false));
7079 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
7080 values.addInt(ObjCTypes.IntTy, Size);
7081 values.addInt(ObjCTypes.IntTy, 0);
7082 values.add(EmitProtocolMethodTypes(
"_OBJC_$_PROTOCOL_METHOD_TYPES_" 7083 + PD->getObjCRuntimeNameAsString(),
7084 methodLists.emitExtendedTypesArray(
this),
7088 values.addNullPointer(ObjCTypes.Int8PtrTy);
7090 values.add(EmitPropertyList(
7091 "_OBJC_$_CLASS_PROP_LIST_" + PD->getObjCRuntimeNameAsString(),
7092 nullptr, PD, ObjCTypes,
true));
7096 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
7097 values.finishAndSetAsInitializer(Entry);
7100 llvm::raw_svector_ostream(symbolName)
7101 <<
"_OBJC_PROTOCOL_$_" << PD->getObjCRuntimeNameAsString();
7103 Entry = values.finishAndCreateGlobal(symbolName, CGM.
getPointerAlign(),
7105 llvm::GlobalValue::WeakAnyLinkage);
7106 if (!CGM.
getTriple().isOSBinFormatMachO())
7107 Entry->setComdat(CGM.
getModule().getOrInsertComdat(symbolName));
7109 Protocols[PD->getIdentifier()] = Entry;
7117 llvm::raw_svector_ostream(ProtocolRef) <<
"_OBJC_LABEL_PROTOCOL_$_" 7118 << PD->getObjCRuntimeNameAsString();
7120 llvm::GlobalVariable *PTGV =
7121 new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolnfABIPtrTy,
7122 false, llvm::GlobalValue::WeakAnyLinkage, Entry,
7124 if (!CGM.
getTriple().isOSBinFormatMachO())
7125 PTGV->setComdat(CGM.
getModule().getOrInsertComdat(ProtocolRef));
7126 PTGV->setAlignment(llvm::Align(
7127 CGM.
getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy)));
7128 PTGV->setSection(GetSectionName(
"__objc_protolist",
7129 "coalesced,no_dead_strip"));
7144 CGObjCNonFragileABIMac::EmitProtocolList(Twine Name,
7151 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
7155 Name.toVector(TmpName);
7156 llvm::GlobalVariable *GV =
7157 CGM.
getModule().getGlobalVariable(TmpName.str(),
true);
7159 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy);
7163 auto countSlot = values.addPlaceholder();
7166 auto array = values.beginArray(ObjCTypes.ProtocolnfABIPtrTy);
7167 for (; begin != end; ++begin)
7168 array.add(GetProtocolRef(*begin));
7169 auto count = array.size();
7170 array.addNullPointer(ObjCTypes.ProtocolnfABIPtrTy);
7172 array.finishAndAddTo(values);
7173 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
7177 return llvm::ConstantExpr::getBitCast(GV,
7178 ObjCTypes.ProtocolListnfABIPtrTy);
7187 LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
7192 unsigned CVRQualifiers) {
7194 llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
7195 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
7204 if (isClassLayoutKnownStatically(Interface)) {
7205 IvarOffsetValue = llvm::ConstantInt::get(
7206 ObjCTypes.IvarOffsetVarTy,
7209 llvm::GlobalVariable *GV = ObjCIvarOffsetVariable(Interface, Ivar);
7212 if (IsIvarOffsetKnownIdempotent(CGF, Ivar))
7213 cast<llvm::LoadInst>(IvarOffsetValue)
7214 ->setMetadata(CGM.
getModule().getMDKindID(
"invariant.load"),
7215 llvm::MDNode::get(VMContext,
None));
7221 if (ObjCTypes.IvarOffsetVarTy == ObjCTypes.IntTy)
7222 IvarOffsetValue = CGF.
Builder.CreateIntCast(
7223 IvarOffsetValue, ObjCTypes.LongTy,
true,
"ivar.conv");
7224 return IvarOffsetValue;
7227 static void appendSelectorForMessageRefTable(std::string &buffer,
7234 for (
unsigned i = 0, e = selector.
getNumArgs(); i != e; ++i) {
7272 args.insert(args.end(), formalArgs.begin(), formalArgs.end());
7274 MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);
7276 NullReturnState nullReturn;
7285 llvm::FunctionCallee fn =
nullptr;
7286 std::string messageRefName(
"_");
7289 fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
7290 messageRefName +=
"objc_msgSendSuper2_stret_fixup";
7292 nullReturn.init(CGF, arg0);
7293 fn = ObjCTypes.getMessageSendStretFixupFn();
7294 messageRefName +=
"objc_msgSend_stret_fixup";
7297 fn = ObjCTypes.getMessageSendFpretFixupFn();
7298 messageRefName +=
"objc_msgSend_fpret_fixup";
7301 fn = ObjCTypes.getMessageSendSuper2FixupFn();
7302 messageRefName +=
"objc_msgSendSuper2_fixup";
7304 fn = ObjCTypes.getMessageSendFixupFn();
7305 messageRefName +=
"objc_msgSend_fixup";
7308 assert(fn &&
"CGObjCNonFragileABIMac::EmitMessageSend");
7309 messageRefName +=
'_';
7313 appendSelectorForMessageRefTable(messageRefName, selector);
7315 llvm::GlobalVariable *messageRef
7316 = CGM.
getModule().getGlobalVariable(messageRefName);
7321 values.add(cast<llvm::Constant>(fn.getCallee()));
7322 values.add(GetMethodVarName(selector));
7323 messageRef = values.finishAndCreateGlobal(messageRefName,
7326 llvm::GlobalValue::WeakAnyLinkage);
7328 messageRef->setSection(GetSectionName(
"__objc_msgrefs",
"coalesced"));
7331 bool requiresnullCheck =
false;
7333 for (
const auto *ParamDecl : method->
parameters()) {
7334 if (ParamDecl->hasAttr<NSConsumedAttr>()) {
7335 if (!nullReturn.NullBB)
7336 nullReturn.init(CGF, arg0);
7337 requiresnullCheck =
true;
7356 RValue result = CGF.
EmitCall(MSI.CallInfo, callee, returnSlot, args);
7357 return nullReturn.complete(CGF, returnSlot, result, resultType, formalArgs,
7358 requiresnullCheck ? method :
nullptr);
7371 return isVTableDispatchedSelector(Sel)
7372 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
7374 false, CallArgs, Method)
7375 : EmitMessageSend(CGF, Return, ResultType, Sel,
7377 false, CallArgs, Method, Class, ObjCTypes);
7385 (metaclass ? getMetaclassSymbolPrefix() : getClassSymbolPrefix());
7391 && ID->
hasAttr<DLLImportAttr>());
7395 CGObjCNonFragileABIMac::GetClassGlobal(StringRef Name,
7397 bool Weak,
bool DLLImport) {
7398 llvm::GlobalValue::LinkageTypes L =
7399 Weak ? llvm::GlobalValue::ExternalWeakLinkage
7402 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name);
7403 if (!GV || GV->getType() != ObjCTypes.ClassnfABITy->getPointerTo()) {
7404 auto *NewGV =
new llvm::GlobalVariable(ObjCTypes.ClassnfABITy,
false, L,
7408 NewGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
7411 GV->replaceAllUsesWith(
7412 llvm::ConstantExpr::getBitCast(NewGV, GV->getType()));
7413 GV->eraseFromParent();
7416 CGM.
getModule().getGlobalList().push_back(GV);
7419 assert(GV->getLinkage() == L);
7424 CGObjCNonFragileABIMac::GetClassGlobalForClassRef(
const ObjCInterfaceDecl *ID) {
7425 llvm::Constant *ClassGV = GetClassGlobal(ID,
false,
7428 if (!ID->
hasAttr<ObjCClassStubAttr>())
7431 ClassGV = llvm::ConstantExpr::getPointerCast(ClassGV, ObjCTypes.Int8PtrTy);
7435 auto *Idx = llvm::ConstantInt::get(CGM.
Int32Ty, 1);
7436 return llvm::ConstantExpr::getGetElementPtr(CGM.
Int8Ty, ClassGV, Idx);
7442 llvm::GlobalVariable *Entry) {
7443 if (ID && ID->
hasAttr<ObjCClassStubAttr>()) {
7447 ObjCTypes.getLoadClassrefFn(), Entry,
"load_classref_result");
7458 llvm::GlobalVariable *&Entry = ClassReferences[II];
7461 llvm::Constant *ClassGV;
7463 ClassGV = GetClassGlobalForClassRef(ID);
7465 ClassGV = GetClassGlobal((getClassSymbolPrefix() + II->
getName()).str(),
7467 assert(ClassGV->getType() == ObjCTypes.ClassnfABIPtrTy &&
7468 "classref was emitted with the wrong type?");
7471 std::string SectionName =
7472 GetSectionName(
"__objc_classrefs",
"regular,no_dead_strip");
7473 Entry =
new llvm::GlobalVariable(
7474 CGM.
getModule(), ClassGV->getType(),
false,
7476 "OBJC_CLASSLIST_REFERENCES_$_");
7478 if (!ID || !ID->
hasAttr<ObjCClassStubAttr>())
7479 Entry->setSection(SectionName);
7484 return EmitLoadOfClassRef(CGF, ID, Entry);
7491 if (ID->
hasAttr<ObjCRuntimeVisibleAttr>())
7492 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
7497 llvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(
7500 return EmitClassRefFromId(CGF, II,
nullptr);
7506 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->
getIdentifier()];
7509 llvm::Constant *ClassGV = GetClassGlobalForClassRef(ID);
7510 std::string SectionName =
7511 GetSectionName(
"__objc_superrefs",
"regular,no_dead_strip");
7512 Entry =
new llvm::GlobalVariable(
7513 CGM.
getModule(), ClassGV->getType(),
false,
7515 "OBJC_CLASSLIST_SUP_REFS_$_");
7517 Entry->setSection(SectionName);
7521 return EmitLoadOfClassRef(CGF, ID, Entry);
7531 llvm::GlobalVariable * &Entry = MetaClassReferences[ID->
getIdentifier()];
7534 std::string SectionName =
7535 GetSectionName(
"__objc_superrefs",
"regular,no_dead_strip");
7536 Entry =
new llvm::GlobalVariable(
7537 CGM.
getModule(), ObjCTypes.ClassnfABIPtrTy,
false,
7539 "OBJC_CLASSLIST_SUP_REFS_$_");
7541 Entry->setSection(SectionName);
7555 assert(!isa<llvm::GlobalVariable>(ClassGV) ||
7556 cast<llvm::GlobalVariable>(ClassGV)->hasExternalWeakLinkage());
7559 return EmitClassRef(CGF, ID);
7571 bool isCategoryImpl,
7573 bool IsClassMessage,
7593 Target = EmitSuperClassRef(CGF, Class);
7602 return (isVTableDispatchedSelector(Sel))
7603 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
7604 ObjCSuper.
getPointer(), ObjCTypes.SuperPtrCTy,
7605 true, CallArgs, Method)
7606 : EmitMessageSend(CGF, Return, ResultType, Sel,
7607 ObjCSuper.
getPointer(), ObjCTypes.SuperPtrCTy,
7608 true, CallArgs, Method, Class, ObjCTypes);
7613 Address Addr = EmitSelectorAddr(Sel);
7616 LI->setMetadata(CGM.
getModule().getMDKindID(
"invariant.load"),
7617 llvm::MDNode::get(VMContext,
None));
7622 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
7625 llvm::Constant *Casted =
7626 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
7627 ObjCTypes.SelectorPtrTy);
7628 std::string SectionName =
7629 GetSectionName(
"__objc_selrefs",
"literal_pointers,no_dead_strip");
7630 Entry =
new llvm::GlobalVariable(
7631 CGM.
getModule(), ObjCTypes.SelectorPtrTy,
false,
7633 "OBJC_SELECTOR_REFERENCES_");
7634 Entry->setExternallyInitialized(
true);
7635 Entry->setSection(SectionName);
7651 if (!isa<llvm::PointerType>(SrcTy)) {
7652 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(SrcTy);
7653 assert(Size <= 8 && "does not support size > 8
"); 7654 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 7655 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 7656 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 7658 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 7659 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 7660 llvm::Value *args[] = { src, dst.getPointer(), ivarOffset }; 7661 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args); 7667 void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
7668 CodeGen::CodeGenFunction &CGF,
7669 llvm::Value *src, Address dst) {
7670 llvm::Type * SrcTy = src->getType();
7671 if (!isa<llvm::PointerType>(SrcTy)) {
7672 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7673 assert(Size <= 8 && "does
not support size > 8
"); 7674 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 7675 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 7676 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 7678 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 7679 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 7680 llvm::Value *args[] = { src, dst.getPointer() }; 7681 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), 7682 args, "weakassign
"); 7685 void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable( 7686 CodeGen::CodeGenFunction &CGF, 7689 llvm::Value *Size) { 7690 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy); 7691 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy); 7692 llvm::Value *args[] = { DestPtr.getPointer(), SrcPtr.getPointer(), Size }; 7693 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args); 7699 llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(
7700 CodeGen::CodeGenFunction &CGF,
7701 Address AddrWeakObj) {
7702 llvm::Type *DestTy = AddrWeakObj.getElementType();
7703 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy);
7704 llvm::Value *read_weak =
7705 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(),
7706 AddrWeakObj.getPointer(), "weakread
"); 7707 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy); 7714 void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
7715 llvm::Value *src, Address dst) {
7716 llvm::Type * SrcTy = src->getType();
7717 if (!isa<llvm::PointerType>(SrcTy)) {
7718 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7719 assert(Size <= 8 && "does
not support size > 8
"); 7720 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 7721 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 7722 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 7724 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 7725 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 7726 llvm::Value *args[] = { src, dst.getPointer() }; 7727 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), 7728 args, "weakassign
"); 7734 void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
7735 llvm::Value *src, Address dst,
7737 llvm::Type * SrcTy = src->getType();
7738 if (!isa<llvm::PointerType>(SrcTy)) {
7739 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7740 assert(Size <= 8 && "does
not support size > 8
"); 7741 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 7742 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 7743 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 7745 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 7746 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 7747 llvm::Value *args[] = { src, dst.getPointer() }; 7749 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), 7750 args, "globalassign
"); 7752 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(), 7753 args, "threadlocalassign
"); 7757 CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 7758 const ObjCAtSynchronizedStmt &S) { 7759 EmitAtSynchronizedStmt(CGF, S, ObjCTypes.getSyncEnterFn(), 7760 ObjCTypes.getSyncExitFn()); 7764 CGObjCNonFragileABIMac::GetEHType(QualType T) { 7765 // There's a particular fixed type info for 'id'. 7766 if (T->isObjCIdType() || T->isObjCQualifiedIdType()) { 7767 auto *IDEHType = CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id
"); 7770 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false, 7771 llvm::GlobalValue::ExternalLinkage, nullptr, 7773 if (CGM.getTriple().isOSBinFormatCOFF()) 7774 IDEHType->setDLLStorageClass(getStorage(CGM, "OBJC_EHTYPE_id
")); 7779 // All other types should be Objective-C interface pointer types. 7780 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>(); 7781 assert(PT && "Invalid
@catch type.
"); 7783 const ObjCInterfaceType *IT = PT->getInterfaceType(); 7784 assert(IT && "Invalid
@catch type.
"); 7786 return GetInterfaceEHType(IT->getDecl(), NotForDefinition); 7789 void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, 7790 const ObjCAtTryStmt &S) { 7791 EmitTryCatchStmt(CGF, S, ObjCTypes.getObjCBeginCatchFn(), 7792 ObjCTypes.getObjCEndCatchFn(), 7793 ObjCTypes.getExceptionRethrowFn()); 7797 void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
7798 const ObjCAtThrowStmt &S,
7799 bool ClearInsertionPoint) {
7800 if (const Expr *ThrowExpr = S.getThrowExpr()) {
7801 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
7802 Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
7803 llvm::CallBase *Call =
7804 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception);
7805 Call->setDoesNotReturn();
7807 llvm::CallBase *Call =
7808 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionRethrowFn());
7809 Call->setDoesNotReturn();
7812 CGF.Builder.CreateUnreachable();
7813 if (ClearInsertionPoint)
7814 CGF.Builder.ClearInsertionPoint();
7818 CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
7819 ForDefinition_t IsForDefinition) {
7820 llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
7821 StringRef ClassName = ID->getObjCRuntimeNameAsString();
7823 // If we don't need a definition, return the entry if found or check
7824 // if we use an external reference.
7825 if (!IsForDefinition) {
7829 // If this type (or a super class) has the __objc_exception__
7830 // attribute, emit an external reference.
7831 if (hasObjCExceptionAttribute(CGM.getContext(), ID)) {
7832 std::string EHTypeName = ("OBJC_EHTYPE_$_
" + ClassName).str(); 7833 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, 7834 false, llvm::GlobalValue::ExternalLinkage, 7835 nullptr, EHTypeName); 7836 CGM.setGVProperties(Entry, ID); 7841 // Otherwise we need to either make a new entry or fill in the initializer. 7842 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition
"); 7844 std::string VTableName = "objc_ehtype_vtable
"; 7845 auto *VTableGV = CGM.getModule().getGlobalVariable(VTableName); 7848 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy, false, 7849 llvm::GlobalValue::ExternalLinkage, nullptr, 7851 if (CGM.getTriple().isOSBinFormatCOFF()) 7852 VTableGV->setDLLStorageClass(getStorage(CGM, VTableName)); 7855 llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2); 7856 ConstantInitBuilder builder(CGM); 7857 auto values = builder.beginStruct(ObjCTypes.EHTypeTy); 7859 llvm::ConstantExpr::getInBoundsGetElementPtr(VTableGV->getValueType(), 7860 VTableGV, VTableIdx)); 7861 values.add(GetClassName(ClassName)); 7862 values.add(GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition)); 7864 llvm::GlobalValue::LinkageTypes L = IsForDefinition 7865 ? llvm::GlobalValue::ExternalLinkage 7866 : llvm::GlobalValue::WeakAnyLinkage; 7868 values.finishAndSetAsInitializer(Entry); 7869 Entry->setAlignment(CGM.getPointerAlign().getAsAlign()); 7871 Entry = values.finishAndCreateGlobal("OBJC_EHTYPE_$_
" + ClassName, 7872 CGM.getPointerAlign(), 7875 if (hasObjCExceptionAttribute(CGM.getContext(), ID)) 7876 CGM.setGVProperties(Entry, ID); 7878 assert(Entry->getLinkage() == L); 7880 if (!CGM.getTriple().isOSBinFormatCOFF()) 7881 if (ID->getVisibility() == HiddenVisibility) 7882 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility); 7884 if (IsForDefinition) 7885 if (CGM.getTriple().isOSBinFormatMachO()) 7886 Entry->setSection("__DATA,__objc_const
"); 7893 CodeGen::CGObjCRuntime * 7894 CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) { 7895 switch (CGM.getLangOpts().ObjCRuntime.getKind()) { 7896 case ObjCRuntime::FragileMacOSX: 7897 return new CGObjCMac(CGM); 7899 case ObjCRuntime::MacOSX: 7900 case ObjCRuntime::iOS: 7901 case ObjCRuntime::WatchOS: 7902 return new CGObjCNonFragileABIMac(CGM); 7904 case ObjCRuntime::GNUstep: 7905 case ObjCRuntime::GCC: 7906 case ObjCRuntime::ObjFW: 7907 llvm_unreachable("these runtimes are
not Mac runtimes
"); 7909 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
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
bool Zero(InterpState &S, CodePtr OpPC)
method_range methods() const
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for protocol's metadata.
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.
bool isDirectMethod() const
True if the method is tagged as objc_direct.
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::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
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.
ObjCMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
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.
const T * castAs() const
Member-template castAs<specific type>.
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
ImplicitParamDecl * getSelfDecl() 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="")
std::string getAsString() const
Derive the full selector name (e.g.
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 isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required...
constexpr XRayInstrMask None
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.
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name. ...
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()
JumpDest ReturnBlock
ReturnBlock - Unified return block.
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.
This class organizes the cross-module state that is used while lowering AST types to LLVM types...
protocol_iterator protocol_begin() const
llvm::PointerType * Int8PtrTy
bool isObjCQualifiedIdType() const
param_const_iterator param_begin() const
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for class's metadata.
Represents Objective-C's @finally statement.
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
llvm::IntegerType * PtrDiffTy
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
Reading or writing from this object requires a barrier call.
Selector GetUnarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing an unary selector.
llvm::Type * ConvertType(QualType T)
A specialization of Address that requires the address to be an LLVM Constant.
ObjCIvarDecl - Represents an ObjC instance variable.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
A helper class of ConstantInitBuilder, used for building constant struct initializers.
ASTImporterLookupTable & LT
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
ImplicitParamDecl * getCmdDecl() const
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.
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...
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