29 #include "llvm/ADT/CachedHashString.h" 30 #include "llvm/ADT/DenseSet.h" 31 #include "llvm/ADT/SetVector.h" 32 #include "llvm/ADT/SmallPtrSet.h" 33 #include "llvm/ADT/SmallString.h" 34 #include "llvm/IR/CallSite.h" 35 #include "llvm/IR/DataLayout.h" 36 #include "llvm/IR/InlineAsm.h" 37 #include "llvm/IR/IntrinsicInst.h" 38 #include "llvm/IR/LLVMContext.h" 39 #include "llvm/IR/Module.h" 40 #include "llvm/Support/ScopedPrinter.h" 41 #include "llvm/Support/raw_ostream.h" 44 using namespace clang;
45 using namespace CodeGen;
52 class ObjCCommonTypesHelper {
54 llvm::LLVMContext &VMContext;
64 llvm::Constant *getMessageSendFn()
const {
67 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
68 return CGM.CreateRuntimeFunction(
69 llvm::FunctionType::get(ObjectPtrTy, params,
true),
"objc_msgSend",
70 llvm::AttributeList::get(CGM.getLLVMContext(),
71 llvm::AttributeList::FunctionIndex,
72 llvm::Attribute::NonLazyBind));
80 llvm::Constant *getMessageSendStretFn()
const {
81 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
82 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy,
84 "objc_msgSend_stret");
93 llvm::Constant *getMessageSendFpretFn()
const {
94 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
95 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.DoubleTy,
97 "objc_msgSend_fpret");
106 llvm::Constant *getMessageSendFp2retFn()
const {
107 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
108 llvm::Type *longDoubleType = llvm::Type::getX86_FP80Ty(VMContext);
110 llvm::StructType::get(longDoubleType, longDoubleType);
112 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(resultType,
114 "objc_msgSend_fp2ret");
122 llvm::Constant *getMessageSendSuperFn()
const {
123 llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
124 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
126 "objc_msgSendSuper");
133 llvm::Constant *getMessageSendSuperFn2()
const {
134 llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
135 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
137 "objc_msgSendSuper2");
144 llvm::Constant *getMessageSendSuperStretFn()
const {
145 llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
146 return CGM.CreateRuntimeFunction(
147 llvm::FunctionType::get(CGM.VoidTy, params,
true),
148 "objc_msgSendSuper_stret");
155 llvm::Constant *getMessageSendSuperStretFn2()
const {
156 llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
157 return CGM.CreateRuntimeFunction(
158 llvm::FunctionType::get(CGM.VoidTy, params,
true),
159 "objc_msgSendSuper2_stret");
162 llvm::Constant *getMessageSendSuperFpretFn()
const {
164 return getMessageSendSuperFn();
167 llvm::Constant *getMessageSendSuperFpretFn2()
const {
169 return getMessageSendSuperFn2();
176 llvm::IntegerType *ShortTy, *IntTy, *LongTy;
177 llvm::PointerType *Int8PtrTy, *Int8PtrPtrTy;
181 llvm::PointerType *ObjectPtrTy;
184 llvm::PointerType *PtrObjectPtrTy;
187 llvm::PointerType *SelectorPtrTy;
196 if (!ExternalProtocolPtrTy) {
202 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
205 return ExternalProtocolPtrTy;
214 llvm::StructType *SuperTy;
216 llvm::PointerType *SuperPtrTy;
220 llvm::StructType *PropertyTy;
224 llvm::StructType *PropertyListTy;
226 llvm::PointerType *PropertyListPtrTy;
229 llvm::StructType *MethodTy;
234 llvm::PointerType *CachePtrTy;
236 llvm::Constant *getGetPropertyFn() {
245 llvm::FunctionType *FTy =
251 llvm::Constant *getSetPropertyFn() {
264 llvm::FunctionType *FTy =
270 llvm::Constant *getOptimizedSetPropertyFn(
bool atomic,
bool copy) {
285 Params.push_back(IdType);
286 Params.push_back(SelType);
287 Params.push_back(IdType);
289 llvm::FunctionType *FTy =
294 name =
"objc_setProperty_atomic_copy";
295 else if (atomic && !copy)
296 name =
"objc_setProperty_atomic";
297 else if (!atomic && copy)
298 name =
"objc_setProperty_nonatomic_copy";
300 name =
"objc_setProperty_nonatomic";
305 llvm::Constant *getCopyStructFn() {
313 Params.push_back(Ctx.
BoolTy);
314 Params.push_back(Ctx.
BoolTy);
315 llvm::FunctionType *FTy =
325 llvm::Constant *getCppAtomicObjectFunction() {
333 llvm::FunctionType *FTy =
339 llvm::Constant *getEnumerationMutationFn() {
345 llvm::FunctionType *FTy =
351 llvm::Constant *getLookUpClassFn() {
358 llvm::FunctionType *FTy =
366 llvm::Constant *getGcReadWeakFn() {
368 llvm::Type *args[] = { ObjectPtrTy->getPointerTo() };
369 llvm::FunctionType *FTy =
370 llvm::FunctionType::get(ObjectPtrTy, args,
false);
375 llvm::Constant *getGcAssignWeakFn() {
377 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
378 llvm::FunctionType *FTy =
379 llvm::FunctionType::get(ObjectPtrTy, args,
false);
384 llvm::Constant *getGcAssignGlobalFn() {
386 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
387 llvm::FunctionType *FTy =
388 llvm::FunctionType::get(ObjectPtrTy, args,
false);
393 llvm::Constant *getGcAssignThreadLocalFn() {
395 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
396 llvm::FunctionType *FTy =
397 llvm::FunctionType::get(ObjectPtrTy, args,
false);
402 llvm::Constant *getGcAssignIvarFn() {
404 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo(),
406 llvm::FunctionType *FTy =
407 llvm::FunctionType::get(ObjectPtrTy, args,
false);
412 llvm::Constant *GcMemmoveCollectableFn() {
414 llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, LongTy };
415 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, args,
false);
420 llvm::Constant *getGcAssignStrongCastFn() {
422 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
423 llvm::FunctionType *FTy =
424 llvm::FunctionType::get(ObjectPtrTy, args,
false);
429 llvm::Constant *getExceptionThrowFn() {
432 llvm::FunctionType *FTy =
433 llvm::FunctionType::get(CGM.
VoidTy, args,
false);
438 llvm::Constant *getExceptionRethrowFn() {
440 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
445 llvm::Constant *getSyncEnterFn() {
448 llvm::FunctionType *FTy =
449 llvm::FunctionType::get(CGM.
IntTy, args,
false);
454 llvm::Constant *getSyncExitFn() {
457 llvm::FunctionType *FTy =
458 llvm::FunctionType::get(CGM.
IntTy, args,
false);
462 llvm::Constant *getSendFn(
bool IsSuper)
const {
463 return IsSuper ? getMessageSendSuperFn() : getMessageSendFn();
466 llvm::Constant *getSendFn2(
bool IsSuper)
const {
467 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();
470 llvm::Constant *getSendStretFn(
bool IsSuper)
const {
471 return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();
474 llvm::Constant *getSendStretFn2(
bool IsSuper)
const {
475 return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();
478 llvm::Constant *getSendFpretFn(
bool IsSuper)
const {
479 return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();
482 llvm::Constant *getSendFpretFn2(
bool IsSuper)
const {
483 return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();
486 llvm::Constant *getSendFp2retFn(
bool IsSuper)
const {
487 return IsSuper ? getMessageSendSuperFn() : getMessageSendFp2retFn();
490 llvm::Constant *getSendFp2RetFn2(
bool IsSuper)
const {
491 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFp2retFn();
499 class ObjCTypesHelper :
public ObjCCommonTypesHelper {
502 llvm::StructType *SymtabTy;
504 llvm::PointerType *SymtabPtrTy;
506 llvm::StructType *ModuleTy;
509 llvm::StructType *ProtocolTy;
511 llvm::PointerType *ProtocolPtrTy;
514 llvm::StructType *ProtocolExtensionTy;
517 llvm::PointerType *ProtocolExtensionPtrTy;
520 llvm::StructType *MethodDescriptionTy;
523 llvm::StructType *MethodDescriptionListTy;
526 llvm::PointerType *MethodDescriptionListPtrTy;
528 llvm::StructType *ProtocolListTy;
530 llvm::PointerType *ProtocolListPtrTy;
532 llvm::StructType *CategoryTy;
534 llvm::StructType *ClassTy;
536 llvm::PointerType *ClassPtrTy;
538 llvm::StructType *ClassExtensionTy;
540 llvm::PointerType *ClassExtensionPtrTy;
542 llvm::StructType *IvarTy;
544 llvm::StructType *IvarListTy;
546 llvm::PointerType *IvarListPtrTy;
548 llvm::StructType *MethodListTy;
550 llvm::PointerType *MethodListPtrTy;
553 llvm::StructType *ExceptionDataTy;
556 llvm::Constant *getExceptionTryEnterFn() {
557 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
559 llvm::FunctionType::get(CGM.
VoidTy, params,
false),
560 "objc_exception_try_enter");
564 llvm::Constant *getExceptionTryExitFn() {
565 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
567 llvm::FunctionType::get(CGM.
VoidTy, params,
false),
568 "objc_exception_try_exit");
572 llvm::Constant *getExceptionExtractFn() {
573 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
576 "objc_exception_extract");
580 llvm::Constant *getExceptionMatchFn() {
581 llvm::Type *params[] = { ClassPtrTy, ObjectPtrTy };
583 llvm::FunctionType::get(CGM.
Int32Ty, params,
false),
584 "objc_exception_match");
588 llvm::Constant *getSetJmpFn() {
592 llvm::FunctionType::get(CGM.
Int32Ty, params,
false),
"_setjmp",
594 llvm::AttributeList::FunctionIndex,
595 llvm::Attribute::NonLazyBind));
604 class ObjCNonFragileABITypesHelper :
public ObjCCommonTypesHelper {
607 llvm::StructType *MethodListnfABITy;
610 llvm::PointerType *MethodListnfABIPtrTy;
613 llvm::StructType *ProtocolnfABITy;
616 llvm::PointerType *ProtocolnfABIPtrTy;
619 llvm::StructType *ProtocolListnfABITy;
622 llvm::PointerType *ProtocolListnfABIPtrTy;
625 llvm::StructType *ClassnfABITy;
628 llvm::PointerType *ClassnfABIPtrTy;
631 llvm::StructType *IvarnfABITy;
634 llvm::StructType *IvarListnfABITy;
637 llvm::PointerType *IvarListnfABIPtrTy;
640 llvm::StructType *ClassRonfABITy;
643 llvm::PointerType *ImpnfABITy;
646 llvm::StructType *CategorynfABITy;
655 llvm::StructType *MessageRefTy;
669 llvm::StructType *SuperMessageRefTy;
672 llvm::PointerType *SuperMessageRefPtrTy;
674 llvm::Constant *getMessageSendFixupFn() {
676 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
679 "objc_msgSend_fixup");
682 llvm::Constant *getMessageSendFpretFixupFn() {
684 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
687 "objc_msgSend_fpret_fixup");
690 llvm::Constant *getMessageSendStretFixupFn() {
692 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
695 "objc_msgSend_stret_fixup");
698 llvm::Constant *getMessageSendSuper2FixupFn() {
701 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
704 "objc_msgSendSuper2_fixup");
707 llvm::Constant *getMessageSendSuper2StretFixupFn() {
710 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
713 "objc_msgSendSuper2_stret_fixup");
716 llvm::Constant *getObjCEndCatchFn() {
722 llvm::Constant *getObjCBeginCatchFn() {
729 llvm::StructType *EHTypeTy;
748 SKIP_SCAN(
unsigned _skip = 0,
unsigned _scan = 0)
749 : skip(_skip), scan(_scan) {}
756 enum BLOCK_LAYOUT_OPCODE {
763 BLOCK_LAYOUT_OPERATOR = 0,
769 BLOCK_LAYOUT_NON_OBJECT_BYTES = 1,
774 BLOCK_LAYOUT_NON_OBJECT_WORDS = 2,
778 BLOCK_LAYOUT_STRONG = 3,
781 BLOCK_LAYOUT_BYREF = 4,
785 BLOCK_LAYOUT_WEAK = 5,
789 BLOCK_LAYOUT_UNRETAINED = 6
806 enum BLOCK_LAYOUT_OPCODE opcode;
809 RUN_SKIP(
enum BLOCK_LAYOUT_OPCODE Opcode = BLOCK_LAYOUT_OPERATOR,
812 : opcode(Opcode), block_var_bytepos(BytePos), block_var_size(Size) {}
815 bool operator<(
const RUN_SKIP &b)
const {
816 return block_var_bytepos < b.block_var_bytepos;
821 llvm::LLVMContext &VMContext;
830 llvm::SetVector<IdentifierInfo*> LazySymbols;
836 llvm::SetVector<IdentifierInfo*> DefinedSymbols;
839 llvm::StringMap<llvm::GlobalVariable*> ClassNames;
842 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
849 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
853 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
856 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
859 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
862 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
867 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
890 llvm::WeakTrackingVH ConstantStringClassRef;
893 llvm::StructType *NSConstantStringType =
nullptr;
895 llvm::StringMap<llvm::GlobalVariable *> NSConstantStringMap;
905 llvm::Constant *GetMethodVarName(
Selector Sel);
913 bool Extended =
false);
914 llvm::Constant *GetMethodVarType(
const FieldDecl *D);
922 const Decl *Container);
927 llvm::Constant *GetClassName(StringRef RuntimeName);
941 bool forStrongLayout,
947 return BuildIvarLayout(OI, beginOffset, endOffset,
true,
false);
953 bool hasMRCWeakIvars) {
954 return BuildIvarLayout(OI, beginOffset, endOffset,
false, hasMRCWeakIvars);
959 void UpdateRunSkipBlockVars(
bool IsByref,
964 void BuildRCBlockVarRecordLayout(
const RecordType *RT,
966 bool ByrefLayout=
false);
968 void BuildRCRecordLayout(
const llvm::StructLayout *RecLayout,
976 llvm::Constant *getBitmapBlockLayout(
bool ComputeByrefLayout);
981 const ObjCCommonTypesHelper &ObjCTypes);
985 llvm::Constant *EmitPropertyList(Twine Name,
986 const Decl *Container,
988 const ObjCCommonTypesHelper &ObjCTypes,
989 bool IsClassProperty);
993 llvm::Constant *EmitProtocolMethodTypes(Twine Name,
995 const ObjCCommonTypesHelper &ObjCTypes);
1006 ObjCCommonTypesHelper &ObjCTypes);
1008 std::string GetSectionName(StringRef Section, StringRef MachOAttributes);
1025 llvm::GlobalVariable *CreateMetadataVar(Twine Name,
1029 llvm::GlobalVariable *CreateMetadataVar(Twine Name,
1030 llvm::Constant *Init,
1034 llvm::GlobalVariable *CreateCStringLiteral(StringRef Name,
1036 bool ForceNonFragileABI =
false,
1037 bool NullTerminate =
true);
1050 const ObjCCommonTypesHelper &ObjCTypes);
1054 void EmitImageInfo();
1060 bool isNonFragileABI()
const {
1061 return ObjCABI == 2;
1081 virtual llvm::Constant *GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD)=0;
1083 virtual llvm::Constant *getNSConstantStringClassRef() = 0;
1102 CategoryInstanceMethods,
1103 CategoryClassMethods,
1106 ProtocolInstanceMethods,
1107 ProtocolClassMethods,
1108 OptionalProtocolInstanceMethods,
1109 OptionalProtocolClassMethods,
1114 class ProtocolMethodLists {
1117 RequiredInstanceMethods,
1118 RequiredClassMethods,
1119 OptionalInstanceMethods,
1120 OptionalClassMethods
1123 NumProtocolMethodLists = 4
1128 case RequiredInstanceMethods:
1129 return MethodListType::ProtocolInstanceMethods;
1130 case RequiredClassMethods:
1131 return MethodListType::ProtocolClassMethods;
1132 case OptionalInstanceMethods:
1133 return MethodListType::OptionalProtocolInstanceMethods;
1134 case OptionalClassMethods:
1135 return MethodListType::OptionalProtocolClassMethods;
1137 llvm_unreachable(
"bad kind");
1143 ProtocolMethodLists result;
1145 for (
auto MD : PD->methods()) {
1146 size_t index = (2 *
size_t(MD->isOptional()))
1147 + (
size_t(MD->isClassMethod()));
1148 result.Methods[index].push_back(MD);
1154 template <
class Self>
1165 for (
auto &list : Methods) {
1166 for (
auto MD : list) {
1167 result.push_back(self->GetMethodVarType(MD,
true));
1174 template <
class Self>
1178 getMethodListKind(kind), Methods[
kind]);
1184 class CGObjCMac :
public CGObjCCommonMac {
1186 friend ProtocolMethodLists;
1188 ObjCTypesHelper ObjCTypes;
1192 void EmitModuleInfo();
1196 llvm::Constant *EmitModuleSymbols();
1200 void FinishModule();
1239 llvm::Constant *Protocols,
1270 const ProtocolMethodLists &methodLists);
1274 llvm::Constant *EmitProtocolList(Twine Name,
1286 llvm::Constant *getNSConstantStringClassRef()
override;
1288 llvm::Function *ModuleInitFunction()
override;
1317 llvm::Constant *GetEHType(
QualType T)
override;
1328 llvm::Constant *GetPropertyGetFunction()
override;
1329 llvm::Constant *GetPropertySetFunction()
override;
1330 llvm::Constant *GetOptimizedPropertySetFunction(
bool atomic,
1331 bool copy)
override;
1332 llvm::Constant *GetGetStructFunction()
override;
1333 llvm::Constant *GetSetStructFunction()
override;
1334 llvm::Constant *GetCppAtomicObjectGetFunction()
override;
1335 llvm::Constant *GetCppAtomicObjectSetFunction()
override;
1336 llvm::Constant *EnumerationMutationFunction()
override;
1344 bool ClearInsertionPoint=
true)
override;
1346 Address AddrWeakObj)
override;
1351 bool threadlocal =
false)
override;
1363 unsigned CVRQualifiers)
override;
1369 class CGObjCNonFragileABIMac :
public CGObjCCommonMac {
1371 friend ProtocolMethodLists;
1372 ObjCNonFragileABITypesHelper ObjCTypes;
1373 llvm::GlobalVariable* ObjCEmptyCacheVar;
1374 llvm::Constant* ObjCEmptyVtableVar;
1377 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences;
1380 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences;
1383 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences;
1390 std::vector<llvm::GlobalValue*> DefinedMetaClasses;
1394 bool isVTableDispatchedSelector(
Selector Sel);
1398 void FinishNonFragileABIModule();
1403 StringRef SymbolName, StringRef SectionName);
1405 llvm::GlobalVariable * BuildClassRoTInitializer(
unsigned flags,
1406 unsigned InstanceStart,
1407 unsigned InstanceSize,
1411 llvm::Constant *IsAGV,
1412 llvm::Constant *SuperClassGV,
1413 llvm::Constant *ClassRoGV,
1434 unsigned long int offset);
1449 llvm::Constant *EmitProtocolList(Twine Name,
1465 llvm::Constant *GetClassGlobal(StringRef Name,
1467 bool Weak =
false,
bool DLLImport =
false);
1496 llvm::GlobalVariable * ObjCIvarOffsetVariable(
1510 StringRef getMetaclassSymbolPrefix()
const {
return "OBJC_METACLASS_$_"; }
1512 StringRef getClassSymbolPrefix()
const {
return "OBJC_CLASS_$_"; }
1515 uint32_t &InstanceStart,
1516 uint32_t &InstanceSize);
1531 bool ImplementationIsNonLazy(
const ObjCImplDecl *OD)
const;
1546 dyn_cast_or_null<ObjCMethodDecl>(CGF.
CurFuncDecl))
1556 llvm::Constant *getNSConstantStringClassRef()
override;
1558 llvm::Function *ModuleInitFunction()
override;
1580 {
return EmitSelector(CGF, Sel); }
1582 {
return EmitSelectorAddr(CGF, Sel); }
1588 {
return EmitSelector(CGF, Method->
getSelector()); }
1599 llvm::Constant *GetEHType(
QualType T)
override;
1601 llvm::Constant *GetPropertyGetFunction()
override {
1602 return ObjCTypes.getGetPropertyFn();
1604 llvm::Constant *GetPropertySetFunction()
override {
1605 return ObjCTypes.getSetPropertyFn();
1608 llvm::Constant *GetOptimizedPropertySetFunction(
bool atomic,
1609 bool copy)
override {
1610 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
1613 llvm::Constant *GetSetStructFunction()
override {
1614 return ObjCTypes.getCopyStructFn();
1617 llvm::Constant *GetGetStructFunction()
override {
1618 return ObjCTypes.getCopyStructFn();
1621 llvm::Constant *GetCppAtomicObjectSetFunction()
override {
1622 return ObjCTypes.getCppAtomicObjectFunction();
1625 llvm::Constant *GetCppAtomicObjectGetFunction()
override {
1626 return ObjCTypes.getCppAtomicObjectFunction();
1629 llvm::Constant *EnumerationMutationFunction()
override {
1630 return ObjCTypes.getEnumerationMutationFn();
1638 bool ClearInsertionPoint=
true)
override;
1640 Address AddrWeakObj)
override;
1645 bool threadlocal =
false)
override;
1656 unsigned CVRQualifiers)
override;
1664 struct NullReturnState {
1665 llvm::BasicBlock *NullBB;
1666 NullReturnState() : NullBB(
nullptr) {}
1679 CGF.
Builder.CreateCondBr(isNull, NullBB, callBB);
1694 if (!NullBB)
return result;
1698 llvm::BasicBlock *contBB =
nullptr;
1701 llvm::BasicBlock *callBB = CGF.
Builder.GetInsertBlock();
1712 CallArgList::const_iterator I = CallArgs.begin();
1714 e = Method->
param_end(); i != e; ++i, ++I) {
1716 if (ParamDecl->
hasAttr<NSConsumedAttr>()) {
1717 RValue RV = I->getRValue(CGF);
1719 "NullReturnState::complete - arg not on object");
1726 assert(CGF.
Builder.GetInsertBlock() == NullBB);
1745 llvm::PHINode *phi = CGF.
Builder.CreatePHI(null->getType(), 2);
1747 phi->addIncoming(null, NullBB);
1756 assert(result.
isAggregate() &&
"null init of non-aggregate result?");
1768 llvm::Type *scalarTy = callResult.first->getType();
1769 llvm::Constant *scalarZero = llvm::Constant::getNullValue(scalarTy);
1772 llvm::PHINode *real = CGF.
Builder.CreatePHI(scalarTy, 2);
1773 real->addIncoming(callResult.first, callBB);
1774 real->addIncoming(scalarZero, NullBB);
1775 llvm::PHINode *imag = CGF.
Builder.CreatePHI(scalarTy, 2);
1776 imag->addIncoming(callResult.second, callBB);
1777 imag->addIncoming(scalarZero, NullBB);
1788 llvm::GlobalVariable *C,
unsigned idx0,
1791 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),
1792 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)
1794 return llvm::ConstantExpr::getGetElementPtr(C->getValueType(), C, Idxs);
1801 if (OID->
hasAttr<ObjCExceptionAttr>())
1820 return EmitClassRef(CGF, ID);
1825 return EmitSelector(CGF, Sel);
1828 return EmitSelectorAddr(CGF, Sel);
1835 llvm::Constant *CGObjCMac::GetEHType(
QualType T) {
1849 llvm_unreachable(
"asking for catch type for ObjC type in fragile runtime");
1872 CGObjCCommonMac::GenerateConstantString(
const StringLiteral *SL) {
1875 : GenerateConstantNSString(SL));
1878 static llvm::StringMapEntry<llvm::GlobalVariable *> &
1881 StringRef String = Literal->
getString();
1882 StringLength = String.size();
1883 return *Map.insert(std::make_pair(String,
nullptr)).first;
1886 llvm::Constant *CGObjCMac::getNSConstantStringClassRef() {
1888 return cast<llvm::Constant>(V);
1892 StringClass.empty() ?
"_NSConstantStringClassReference" 1893 :
"_" + StringClass +
"ClassReference";
1897 auto V = llvm::ConstantExpr::getBitCast(GV, CGM.
IntTy->getPointerTo());
1898 ConstantStringClassRef = V;
1902 llvm::Constant *CGObjCNonFragileABIMac::getNSConstantStringClassRef() {
1904 return cast<llvm::Constant>(V);
1908 StringClass.empty() ?
"OBJC_CLASS_$_NSConstantString" 1909 :
"OBJC_CLASS_$_" + StringClass;
1913 auto V = llvm::ConstantExpr::getBitCast(GV, CGM.
IntTy->getPointerTo());
1915 ConstantStringClassRef = V;
1920 CGObjCCommonMac::GenerateConstantNSString(
const StringLiteral *Literal) {
1921 unsigned StringLength = 0;
1922 llvm::StringMapEntry<llvm::GlobalVariable *> &Entry =
1925 if (
auto *C = Entry.second)
1929 llvm::Constant *Class = getNSConstantStringClassRef();
1932 if (!NSConstantStringType) {
1933 NSConstantStringType =
1938 },
"struct.__builtin_NSString");
1942 auto Fields = Builder.beginStruct(NSConstantStringType);
1949 llvm::ConstantDataArray::getString(VMContext, Entry.first());
1951 llvm::GlobalValue::LinkageTypes
Linkage = llvm::GlobalValue::PrivateLinkage;
1952 bool isConstant = !CGM.
getLangOpts().WritableStrings;
1954 auto *GV =
new llvm::GlobalVariable(CGM.
getModule(), C->getType(), isConstant,
1956 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1959 GV->setAlignment(1);
1963 Fields.addInt(CGM.
IntTy, StringLength);
1967 GV = Fields.finishAndCreateGlobal(
"_unnamed_nsstring_", Alignment,
1969 llvm::GlobalVariable::PrivateLinkage);
1970 const char *NSStringSection =
"__OBJC,__cstring_object,regular,no_dead_strip";
1971 const char *NSStringNonFragileABISection =
1972 "__DATA,__objc_stringobj,regular,no_dead_strip";
1975 ? NSStringNonFragileABISection
1995 bool isCategoryImpl,
1997 bool IsClassMessage,
2013 if (IsClassMessage) {
2014 if (isCategoryImpl) {
2025 llvm::Constant *MetaClassPtr = EmitMetaClassRef(Class);
2032 }
else if (isCategoryImpl)
2046 return EmitMessageSend(CGF, Return, ResultType,
2047 EmitSelector(CGF, Sel),
2048 ObjCSuper.
getPointer(), ObjCTypes.SuperPtrCTy,
2049 true, CallArgs, Method, Class, ObjCTypes);
2061 return EmitMessageSend(CGF, Return, ResultType,
2062 EmitSelector(CGF, Sel),
2064 false, CallArgs, Method, Class, ObjCTypes);
2087 const ObjCCommonTypesHelper &ObjCTypes) {
2096 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2101 "Result type mismatch!");
2103 bool ReceiverCanBeNull =
true;
2108 ReceiverCanBeNull =
false;
2112 }
else if (ClassReceiver && Method && Method->
isClassMethod()) {
2117 }
else if (
auto CurMethod =
2118 dyn_cast_or_null<ObjCMethodDecl>(CGF.
CurCodeDecl)) {
2119 auto Self = CurMethod->getSelfDecl();
2120 if (Self->getType().isConstQualified()) {
2121 if (
auto LI = dyn_cast<llvm::LoadInst>(Arg0->stripPointerCasts())) {
2123 if (SelfAddr == LI->getPointerOperand()) {
2124 ReceiverCanBeNull =
false;
2130 bool RequiresNullCheck =
false;
2132 llvm::Constant *Fn =
nullptr;
2134 if (ReceiverCanBeNull) RequiresNullCheck =
true;
2135 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
2136 : ObjCTypes.getSendStretFn(IsSuper);
2138 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
2139 : ObjCTypes.getSendFpretFn(IsSuper);
2141 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)
2142 : ObjCTypes.getSendFp2retFn(IsSuper);
2147 RequiresNullCheck =
true;
2148 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
2149 : ObjCTypes.getSendFn(IsSuper);
2155 RequiresNullCheck =
false;
2158 if (!RequiresNullCheck && CGM.
getLangOpts().ObjCAutoRefCount && Method) {
2159 for (
const auto *ParamDecl : Method->
parameters()) {
2160 if (ParamDecl->hasAttr<NSConsumedAttr>()) {
2161 RequiresNullCheck =
true;
2167 NullReturnState nullReturn;
2168 if (RequiresNullCheck) {
2169 nullReturn.init(CGF, Arg0);
2172 llvm::Instruction *CallSite;
2173 Fn = llvm::ConstantExpr::getBitCast(Fn, MSI.MessengerType);
2175 RValue rvalue = CGF.
EmitCall(MSI.CallInfo, Callee, Return, ActualArgs,
2180 if (Method && Method->
hasAttr<NoReturnAttr>() && !ReceiverCanBeNull) {
2181 llvm::CallSite(CallSite).setDoesNotReturn();
2184 return nullReturn.complete(CGF, Return, rvalue, ResultType, CallArgs,
2185 RequiresNullCheck ? Method :
nullptr);
2189 bool pointee =
false) {
2202 switch (ownership) {
2209 llvm_unreachable(
"bad objc ownership");
2228 uint64_t SizeInWords;
2229 IvarInfo(
CharUnits offset, uint64_t sizeInWords)
2230 :
Offset(offset), SizeInWords(sizeInWords) {}
2233 bool operator<(
const IvarInfo &other)
const {
2234 return Offset < other.Offset;
2239 class IvarLayoutBuilder {
2250 bool ForStrongLayout;
2253 bool IsDisordered =
false;
2259 CharUnits instanceEnd,
bool forStrongLayout)
2260 : CGM(CGM), InstanceBegin(instanceBegin), InstanceEnd(instanceEnd),
2261 ForStrongLayout(forStrongLayout) {
2266 template <
class Iterator,
class GetOffsetFn>
2267 void visitAggregate(Iterator begin, Iterator end,
2269 const GetOffsetFn &getOffset);
2277 bool hasBitmapData()
const {
return !IvarsInfo.empty(); }
2279 llvm::Constant *buildBitmap(CGObjCCommonMac &CGObjC,
2283 const unsigned char *s = buffer.data();
2284 for (
unsigned i = 0, e = buffer.size(); i < e; i++)
2286 printf(
"0x0%x%s", s[i], s[i] != 0 ?
", " :
"");
2288 printf(
"0x%x%s", s[i], s[i] != 0 ?
", " :
"");
2294 llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(
CodeGenModule &CGM,
2297 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2304 builder.visitBlock(blockInfo);
2306 if (!builder.hasBitmapData())
2310 llvm::Constant *C = builder.buildBitmap(*
this, buffer);
2311 if (CGM.
getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
2312 printf(
"\n block variable layout for block: ");
2313 builder.dump(buffer);
2319 void IvarLayoutBuilder::visitBlock(
const CGBlockInfo &blockInfo) {
2332 for (
const auto &CI : blockDecl->
captures()) {
2333 const VarDecl *variable = CI.getVariable();
2345 if (fieldOffset < lastFieldOffset)
2346 IsDisordered =
true;
2347 lastFieldOffset = fieldOffset;
2351 IvarsInfo.push_back(IvarInfo(fieldOffset, 1));
2355 assert(!type->
isArrayType() &&
"array variable should not be caught");
2357 visitRecord(record, fieldOffset);
2366 IvarsInfo.push_back(IvarInfo(fieldOffset, 1));
2391 void CGObjCCommonMac::UpdateRunSkipBlockVars(
bool IsByref,
2397 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset,
2400 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset,
2403 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset,
2406 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset,
2409 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES,
2414 void CGObjCCommonMac::BuildRCRecordLayout(
const llvm::StructLayout *RecLayout,
2419 bool IsUnion = (RD && RD->
isUnion());
2422 const FieldDecl *LastFieldBitfieldOrUnnamed =
nullptr;
2426 if (RecFields.empty())
2430 for (
unsigned i = 0, e = RecFields.size(); i != e; ++i) {
2440 LastFieldBitfieldOrUnnamed = Field;
2441 LastBitfieldOrUnnamedOffset = FieldOffset;
2445 LastFieldBitfieldOrUnnamed =
nullptr;
2452 BytePos + FieldOffset, HasUnion);
2458 dyn_cast_or_null<ConstantArrayType>(Array);
2459 uint64_t ElCount = CArray->
getSize().getZExtValue();
2460 assert(CArray &&
"only array with known element size is supported");
2464 dyn_cast_or_null<ConstantArrayType>(Array);
2465 ElCount *= CArray->
getSize().getZExtValue();
2469 int OldIndex = RunSkipBlockVars.size() - 1;
2471 BuildRCBlockVarRecordLayout(RT, BytePos + FieldOffset,
2477 for (
int FirstIndex = RunSkipBlockVars.size() - 1 ;ElIx < ElCount; ElIx++) {
2479 for (
int i = OldIndex+1; i <= FirstIndex; ++i)
2480 RunSkipBlockVars.push_back(
2481 RUN_SKIP(RunSkipBlockVars[i].opcode,
2482 RunSkipBlockVars[i].block_var_bytepos + Size*ElIx,
2483 RunSkipBlockVars[i].block_var_size));
2491 if (UnionIvarSize > MaxUnionSize) {
2492 MaxUnionSize = UnionIvarSize;
2494 MaxFieldOffset = FieldOffset;
2497 UpdateRunSkipBlockVars(
false,
2498 getBlockCaptureLifetime(FQT, ByrefLayout),
2499 BytePos + FieldOffset,
2504 if (LastFieldBitfieldOrUnnamed) {
2505 if (LastFieldBitfieldOrUnnamed->
isBitField()) {
2507 uint64_t BitFieldSize
2509 unsigned UnsSize = (BitFieldSize / ByteSizeInBits) +
2510 ((BitFieldSize % ByteSizeInBits) != 0);
2512 Size += LastBitfieldOrUnnamedOffset;
2513 UpdateRunSkipBlockVars(
false,
2514 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
2516 BytePos + LastBitfieldOrUnnamedOffset,
2519 assert(!LastFieldBitfieldOrUnnamed->
getIdentifier() &&
"Expected unnamed");
2523 UpdateRunSkipBlockVars(
false,
2524 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
2526 BytePos + LastBitfieldOrUnnamedOffset,
2532 UpdateRunSkipBlockVars(
false,
2533 getBlockCaptureLifetime(MaxField->
getType(), ByrefLayout),
2534 BytePos + MaxFieldOffset,
2538 void CGObjCCommonMac::BuildRCBlockVarRecordLayout(
const RecordType *RT,
2545 const llvm::StructLayout *RecLayout =
2546 CGM.
getDataLayout().getStructLayout(cast<llvm::StructType>(Ty));
2548 BuildRCRecordLayout(RecLayout, RD, Fields, BytePos, HasUnion, ByrefLayout);
2560 uint64_t CGObjCCommonMac::InlineLayoutInstruction(
2562 uint64_t Result = 0;
2563 if (Layout.size() <= 3) {
2564 unsigned size = Layout.size();
2565 unsigned strong_word_count = 0, byref_word_count=0, weak_word_count=0;
2567 enum BLOCK_LAYOUT_OPCODE opcode ;
2571 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2572 if (opcode == BLOCK_LAYOUT_STRONG)
2573 strong_word_count = (inst & 0xF)+1;
2577 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2578 if (opcode == BLOCK_LAYOUT_BYREF)
2579 byref_word_count = (inst & 0xF)+1;
2583 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2584 if (opcode == BLOCK_LAYOUT_WEAK)
2585 weak_word_count = (inst & 0xF)+1;
2592 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2593 if (opcode == BLOCK_LAYOUT_STRONG) {
2594 strong_word_count = (inst & 0xF)+1;
2596 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2597 if (opcode == BLOCK_LAYOUT_BYREF)
2598 byref_word_count = (inst & 0xF)+1;
2599 else if (opcode == BLOCK_LAYOUT_WEAK)
2600 weak_word_count = (inst & 0xF)+1;
2604 else if (opcode == BLOCK_LAYOUT_BYREF) {
2605 byref_word_count = (inst & 0xF)+1;
2607 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2608 if (opcode == BLOCK_LAYOUT_WEAK)
2609 weak_word_count = (inst & 0xF)+1;
2619 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2620 if (opcode == BLOCK_LAYOUT_STRONG)
2621 strong_word_count = (inst & 0xF)+1;
2622 else if (opcode == BLOCK_LAYOUT_BYREF)
2623 byref_word_count = (inst & 0xF)+1;
2624 else if (opcode == BLOCK_LAYOUT_WEAK)
2625 weak_word_count = (inst & 0xF)+1;
2637 if (strong_word_count == 16 || byref_word_count == 16 || weak_word_count == 16)
2641 (strong_word_count != 0) + (byref_word_count != 0) + (weak_word_count != 0);
2643 if (size == count) {
2644 if (strong_word_count)
2645 Result = strong_word_count;
2647 if (byref_word_count)
2648 Result += byref_word_count;
2650 if (weak_word_count)
2651 Result += weak_word_count;
2657 llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(
bool ComputeByrefLayout) {
2658 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2659 if (RunSkipBlockVars.empty())
2663 unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2667 llvm::array_pod_sort(RunSkipBlockVars.begin(), RunSkipBlockVars.end());
2670 unsigned size = RunSkipBlockVars.size();
2671 for (
unsigned i = 0; i < size; i++) {
2672 enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode;
2673 CharUnits start_byte_pos = RunSkipBlockVars[i].block_var_bytepos;
2674 CharUnits end_byte_pos = start_byte_pos;
2677 if (opcode == RunSkipBlockVars[j].opcode) {
2678 end_byte_pos = RunSkipBlockVars[j++].block_var_bytepos;
2685 end_byte_pos - start_byte_pos + RunSkipBlockVars[j-1].block_var_size;
2688 RunSkipBlockVars[j].block_var_bytepos -
2689 RunSkipBlockVars[j-1].block_var_bytepos - RunSkipBlockVars[j-1].block_var_size;
2690 size_in_bytes += gap;
2693 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) {
2694 residue_in_bytes = size_in_bytes % WordSizeInBytes;
2695 size_in_bytes -= residue_in_bytes;
2696 opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS;
2699 unsigned size_in_words = size_in_bytes.
getQuantity() / WordSizeInBytes;
2700 while (size_in_words >= 16) {
2703 unsigned char inst = (opcode << 4) | 0xf;
2704 Layout.push_back(inst);
2705 size_in_words -= 16;
2707 if (size_in_words > 0) {
2710 unsigned char inst = (opcode << 4) | (size_in_words-1);
2711 Layout.push_back(inst);
2714 unsigned char inst =
2715 (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) | (residue_in_bytes.
getQuantity()-1);
2716 Layout.push_back(inst);
2720 while (!Layout.empty()) {
2721 unsigned char inst = Layout.back();
2722 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2723 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES || opcode == BLOCK_LAYOUT_NON_OBJECT_WORDS)
2729 uint64_t Result = InlineLayoutInstruction(Layout);
2733 if (ComputeByrefLayout)
2734 printf(
"\n Inline BYREF variable layout: ");
2736 printf(
"\n Inline block variable layout: ");
2737 printf(
"0x0%" PRIx64
"", Result);
2738 if (
auto numStrong = (Result & 0xF00) >> 8)
2739 printf(
", BL_STRONG:%d", (
int) numStrong);
2740 if (
auto numByref = (Result & 0x0F0) >> 4)
2741 printf(
", BL_BYREF:%d", (
int) numByref);
2742 if (
auto numWeak = (Result & 0x00F) >> 0)
2743 printf(
", BL_WEAK:%d", (
int) numWeak);
2744 printf(
", BL_OPERATOR:0\n");
2746 return llvm::ConstantInt::get(CGM.
IntPtrTy, Result);
2749 unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0;
2750 Layout.push_back(inst);
2752 for (
unsigned i = 0, e = Layout.size(); i != e; i++)
2753 BitMap += Layout[i];
2756 if (ComputeByrefLayout)
2757 printf(
"\n Byref variable layout: ");
2759 printf(
"\n Block variable layout: ");
2760 for (
unsigned i = 0, e = BitMap.size(); i != e; i++) {
2761 unsigned char inst = BitMap[i];
2762 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2765 case BLOCK_LAYOUT_OPERATOR:
2769 case BLOCK_LAYOUT_NON_OBJECT_BYTES:
2770 printf(
"BL_NON_OBJECT_BYTES:");
2772 case BLOCK_LAYOUT_NON_OBJECT_WORDS:
2773 printf(
"BL_NON_OBJECT_WORD:");
2775 case BLOCK_LAYOUT_STRONG:
2778 case BLOCK_LAYOUT_BYREF:
2781 case BLOCK_LAYOUT_WEAK:
2784 case BLOCK_LAYOUT_UNRETAINED:
2785 printf(
"BL_UNRETAINED:");
2790 printf(
"%d", (inst & 0xf) + delta);
2798 auto *Entry = CreateCStringLiteral(BitMap, ObjCLabelType::ClassName,
2806 bool HasCopyDisposeHelpers) {
2808 for (
const CGObjCCommonMac::RUN_SKIP &R : RunSkipBlockVars) {
2809 if (R.opcode == CGObjCCommonMac::BLOCK_LAYOUT_UNRETAINED) {
2813 }
else if (HasCopyDisposeHelpers) {
2821 case CGObjCCommonMac::BLOCK_LAYOUT_STRONG:
2824 case CGObjCCommonMac::BLOCK_LAYOUT_BYREF:
2827 case CGObjCCommonMac::BLOCK_LAYOUT_WEAK:
2834 Str += llvm::to_string(R.block_var_bytepos.getQuantity());
2835 Str +=
"l" + llvm::to_string(R.block_var_size.getQuantity());
2840 void CGObjCCommonMac::fillRunSkipBlockVars(
CodeGenModule &CGM,
2844 RunSkipBlockVars.clear();
2845 bool hasUnion =
false;
2849 unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2854 const llvm::StructLayout *layout =
2864 for (
const auto &CI : blockDecl->
captures()) {
2865 const VarDecl *variable = CI.getVariable();
2876 assert(!type->
isArrayType() &&
"array variable should not be caught");
2879 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion);
2887 UpdateRunSkipBlockVars(CI.isByRef(), getBlockCaptureLifetime(type,
false),
2888 fieldOffset, fieldSize);
2895 fillRunSkipBlockVars(CGM, blockInfo);
2896 return getBitmapBlockLayout(
false);
2899 std::string CGObjCCommonMac::getRCBlockLayoutStr(
CodeGenModule &CGM,
2901 fillRunSkipBlockVars(CGM, blockInfo);
2909 assert(!T->
isArrayType() &&
"__block array variable should not be caught");
2911 RunSkipBlockVars.clear();
2912 bool hasUnion =
false;
2914 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion,
true );
2915 llvm::Constant *Result = getBitmapBlockLayout(
true);
2916 if (isa<llvm::ConstantInt>(Result))
2917 Result = llvm::ConstantExpr::getIntToPtr(Result, CGM.
Int8PtrTy);
2920 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2930 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
2931 ObjCTypes.getExternalProtocolPtrTy());
2943 GetOrEmitProtocol(PD);
2946 llvm::Constant *CGObjCCommonMac::GetProtocolRef(
const ObjCProtocolDecl *PD) {
2948 return GetOrEmitProtocol(PD);
2950 return GetOrEmitProtocolRef(PD);
2953 llvm::Value *CGObjCCommonMac::EmitClassRefViaRuntime(
2956 ObjCCommonTypesHelper &ObjCTypes) {
2957 llvm::Constant *lookUpClassFn = ObjCTypes.getLookUpClassFn();
2967 llvm::CallInst *call = CGF.
Builder.CreateCall(lookUpClassFn, className);
2968 call->setDoesNotThrow();
2985 llvm::GlobalVariable *Entry = Protocols[PD->
getIdentifier()];
2988 if (Entry && Entry->hasInitializer())
3000 auto methodLists = ProtocolMethodLists::get(PD);
3003 auto values = builder.
beginStruct(ObjCTypes.ProtocolTy);
3004 values.add(EmitProtocolExtension(PD, methodLists));
3006 values.add(EmitProtocolList(
"OBJC_PROTOCOL_REFS_" + PD->
getName(),
3008 values.add(methodLists.emitMethodList(
this, PD,
3009 ProtocolMethodLists::RequiredInstanceMethods));
3010 values.add(methodLists.emitMethodList(
this, PD,
3011 ProtocolMethodLists::RequiredClassMethods));
3015 assert(Entry->hasPrivateLinkage());
3016 values.finishAndSetAsInitializer(Entry);
3018 Entry = values.finishAndCreateGlobal(
"OBJC_PROTOCOL_" + PD->
getName(),
3021 llvm::GlobalValue::PrivateLinkage);
3022 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
3031 llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD) {
3032 llvm::GlobalVariable *&Entry = Protocols[PD->
getIdentifier()];
3038 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolTy,
3039 false, llvm::GlobalValue::PrivateLinkage,
3040 nullptr,
"OBJC_PROTOCOL_" + PD->
getName());
3041 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
3043 Entry->setAlignment(4);
3061 const ProtocolMethodLists &methodLists) {
3062 auto optInstanceMethods =
3063 methodLists.emitMethodList(
this, PD,
3064 ProtocolMethodLists::OptionalInstanceMethods);
3065 auto optClassMethods =
3066 methodLists.emitMethodList(
this, PD,
3067 ProtocolMethodLists::OptionalClassMethods);
3069 auto extendedMethodTypes =
3070 EmitProtocolMethodTypes(
"OBJC_PROTOCOL_METHOD_TYPES_" + PD->
getName(),
3071 methodLists.emitExtendedTypesArray(
this),
3074 auto instanceProperties =
3075 EmitPropertyList(
"OBJC_$_PROP_PROTO_LIST_" + PD->
getName(),
nullptr, PD,
3077 auto classProperties =
3078 EmitPropertyList(
"OBJC_$_CLASS_PROP_PROTO_LIST_" + PD->
getName(),
nullptr,
3079 PD, ObjCTypes,
true);
3082 if (optInstanceMethods->isNullValue() &&
3083 optClassMethods->isNullValue() &&
3084 extendedMethodTypes->isNullValue() &&
3085 instanceProperties->isNullValue() &&
3086 classProperties->isNullValue()) {
3087 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
3091 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
3094 auto values = builder.
beginStruct(ObjCTypes.ProtocolExtensionTy);
3095 values.addInt(ObjCTypes.IntTy, size);
3096 values.add(optInstanceMethods);
3097 values.add(optClassMethods);
3098 values.add(instanceProperties);
3099 values.add(extendedMethodTypes);
3100 values.add(classProperties);
3103 return CreateMetadataVar(
"\01l_OBJC_PROTOCOLEXT_" + PD->
getName(), values,
3115 CGObjCMac::EmitProtocolList(Twine name,
3120 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
3126 values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
3129 auto countSlot = values.addPlaceholder();
3131 auto refsArray = values.beginArray(ObjCTypes.ProtocolPtrTy);
3132 for (; begin != end; ++begin) {
3133 refsArray.add(GetProtocolRef(*begin));
3135 auto count = refsArray.size();
3138 refsArray.addNullPointer(ObjCTypes.ProtocolPtrTy);
3140 refsArray.finishAndAddTo(values);
3141 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
3144 if (CGM.
getTriple().isOSBinFormatMachO())
3145 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3147 llvm::GlobalVariable *GV =
3148 CreateMetadataVar(name, values, section, CGM.
getPointerAlign(),
false);
3149 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
3156 bool IsClassProperty) {
3161 if (IsClassProperty != PD->isClassProperty())
3165 Properties.push_back(PD);
3181 llvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name,
3182 const Decl *Container,
3184 const ObjCCommonTypesHelper &ObjCTypes,
3185 bool IsClassProperty) {
3186 if (IsClassProperty) {
3190 if ((Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 11)) ||
3191 (Triple.isiOS() && Triple.isOSVersionLT(9)))
3192 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3196 llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
3201 if (IsClassProperty != PD->isClassProperty())
3204 Properties.push_back(PD);
3208 if (IsClassProperty != PD->isClassProperty())
3214 Properties.push_back(PD);
3218 for (
const auto *
P : OID->all_referenced_protocols())
3222 for (
const auto *
P : CD->protocols())
3227 if (Properties.empty())
3228 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3230 unsigned propertySize =
3235 values.addInt(ObjCTypes.IntTy, propertySize);
3236 values.addInt(ObjCTypes.IntTy, Properties.size());
3237 auto propertiesArray = values.beginArray(ObjCTypes.PropertyTy);
3238 for (
auto PD : Properties) {
3239 auto property = propertiesArray.beginStruct(ObjCTypes.PropertyTy);
3241 property.add(GetPropertyTypeString(PD, Container));
3242 property.finishAndAddTo(propertiesArray);
3244 propertiesArray.finishAndAddTo(values);
3247 if (CGM.
getTriple().isOSBinFormatMachO())
3248 Section = (ObjCABI == 2) ?
"__DATA, __objc_const" 3249 :
"__OBJC,__property,regular,no_dead_strip";
3251 llvm::GlobalVariable *GV =
3252 CreateMetadataVar(Name, values, Section, CGM.
getPointerAlign(),
true);
3253 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy);
3257 CGObjCCommonMac::EmitProtocolMethodTypes(Twine Name,
3259 const ObjCCommonTypesHelper &ObjCTypes) {
3261 if (MethodTypes.empty())
3262 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy);
3264 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
3265 MethodTypes.size());
3266 llvm::Constant *Init = llvm::ConstantArray::get(AT, MethodTypes);
3269 if (CGM.
getTriple().isOSBinFormatMachO() && ObjCABI == 2)
3270 Section =
"__DATA, __objc_const";
3272 llvm::GlobalVariable *GV =
3274 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.Int8PtrPtrTy);
3290 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.CategoryTy);
3301 llvm::raw_svector_ostream(ExtName) << Interface->
getName() <<
'_' 3305 auto Values = Builder.
beginStruct(ObjCTypes.CategoryTy);
3313 for (
const auto *MD : OCD->
methods()) {
3314 Methods[unsigned(MD->isClassMethod())].push_back(MD);
3317 Values.add(GetClassName(OCD->
getName()));
3321 Values.add(emitMethodList(ExtName, MethodListType::CategoryInstanceMethods,
3322 Methods[InstanceMethods]));
3323 Values.add(emitMethodList(ExtName, MethodListType::CategoryClassMethods,
3324 Methods[ClassMethods]));
3327 EmitProtocolList(
"OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
3330 Values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
3332 Values.addInt(ObjCTypes.IntTy, Size);
3336 Values.add(EmitPropertyList(
"\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
3338 Values.add(EmitPropertyList(
"\01l_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(),
3341 Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
3342 Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
3345 llvm::GlobalVariable *GV =
3346 CreateMetadataVar(
"OBJC_CATEGORY_" + ExtName.str(), Values,
3347 "__OBJC,__category,regular,no_dead_strip",
3349 DefinedCategories.push_back(GV);
3350 DefinedCategoryNames.insert(llvm::CachedHashString(ExtName));
3352 MethodDefinitions.clear();
3412 for (
auto field : recType->getDecl()->fields()) {
3461 DefinedSymbols.insert(RuntimeName);
3467 llvm::Constant *Protocols =
3468 EmitProtocolList(
"OBJC_CLASS_PROTOCOLS_" + ID->
getName(),
3475 bool hasMRCWeak =
false;
3495 for (
const auto *MD : ID->
methods()) {
3496 Methods[unsigned(MD->isClassMethod())].push_back(MD);
3504 if (GetMethodDefinition(MD))
3505 Methods[InstanceMethods].push_back(MD);
3507 if (GetMethodDefinition(MD))
3508 Methods[InstanceMethods].push_back(MD);
3513 auto values = builder.
beginStruct(ObjCTypes.ClassTy);
3514 values.add(EmitMetaClass(ID, Protocols, Methods[ClassMethods]));
3517 LazySymbols.insert(Super->getIdentifier());
3519 values.addBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
3520 ObjCTypes.ClassPtrTy);
3522 values.addNullPointer(ObjCTypes.ClassPtrTy);
3526 values.addInt(ObjCTypes.LongTy, 0);
3527 values.addInt(ObjCTypes.LongTy, Flags);
3528 values.addInt(ObjCTypes.LongTy, Size.
getQuantity());
3529 values.add(EmitIvarList(ID,
false));
3530 values.add(emitMethodList(ID->
getName(), MethodListType::InstanceMethods,
3531 Methods[InstanceMethods]));
3533 values.addNullPointer(ObjCTypes.CachePtrTy);
3534 values.add(Protocols);
3536 values.add(EmitClassExtension(ID, Size, hasMRCWeak,
3539 std::string Name(
"OBJC_CLASS_");
3541 const char *Section =
"__OBJC,__class,regular,no_dead_strip";
3543 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3545 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3546 "Forward metaclass reference has incorrect type.");
3547 values.finishAndSetAsInitializer(GV);
3548 GV->setSection(Section);
3552 GV = CreateMetadataVar(Name, values, Section, CGM.
getPointerAlign(),
true);
3553 DefinedClasses.push_back(GV);
3554 ImplementedClasses.push_back(Interface);
3556 MethodDefinitions.clear();
3560 llvm::Constant *Protocols,
3563 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ClassTy);
3569 auto values = builder.
beginStruct(ObjCTypes.ClassTy);
3575 ObjCTypes.ClassPtrTy);
3580 values.addBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
3581 ObjCTypes.ClassPtrTy);
3583 values.addNullPointer(ObjCTypes.ClassPtrTy);
3587 values.addInt(ObjCTypes.LongTy, 0);
3588 values.addInt(ObjCTypes.LongTy, Flags);
3589 values.addInt(ObjCTypes.LongTy, Size);
3590 values.add(EmitIvarList(ID,
true));
3591 values.add(emitMethodList(ID->
getName(), MethodListType::ClassMethods,
3594 values.addNullPointer(ObjCTypes.CachePtrTy);
3595 values.add(Protocols);
3597 values.addNullPointer(ObjCTypes.Int8PtrTy);
3602 std::string Name(
"OBJC_METACLASS_");
3606 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3608 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3609 "Forward metaclass reference has incorrect type.");
3610 values.finishAndSetAsInitializer(GV);
3614 llvm::GlobalValue::PrivateLinkage);
3616 GV->setSection(
"__OBJC,__meta_class,regular,no_dead_strip");
3633 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3635 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
3636 llvm::GlobalValue::PrivateLinkage,
nullptr,
3639 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3640 "Forward metaclass reference has incorrect type.");
3646 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3649 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
3650 llvm::GlobalValue::PrivateLinkage,
nullptr,
3653 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3654 "Forward class metadata reference has incorrect type.");
3674 llvm::Constant *layout;
3676 layout = llvm::ConstantPointerNull::get(CGM.
Int8PtrTy);
3683 llvm::Constant *propertyList =
3684 EmitPropertyList((isMetaclass ? Twine(
"\01l_OBJC_$_CLASS_PROP_LIST_")
3685 : Twine(
"\01l_OBJC_$_PROP_LIST_"))
3690 if (layout->isNullValue() && propertyList->isNullValue()) {
3691 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
3695 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
3698 auto values = builder.
beginStruct(ObjCTypes.ClassExtensionTy);
3699 values.addInt(ObjCTypes.IntTy, size);
3701 values.add(propertyList);
3703 return CreateMetadataVar(
"OBJC_CLASSEXT_" + ID->
getName(), values,
3704 "__OBJC,__class_ext,regular,no_dead_strip",
3728 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3734 auto countSlot = ivarList.addPlaceholder();
3735 auto ivars = ivarList.beginArray(ObjCTypes.IvarTy);
3740 if (!IVD->getDeclName())
3743 auto ivar = ivars.beginStruct(ObjCTypes.IvarTy);
3744 ivar.add(GetMethodVarName(IVD->getIdentifier()));
3745 ivar.add(GetMethodVarType(IVD));
3746 ivar.addInt(ObjCTypes.IntTy, ComputeIvarBaseOffset(CGM, OID, IVD));
3747 ivar.finishAndAddTo(ivars);
3751 auto count = ivars.size();
3755 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3758 ivars.finishAndAddTo(ivarList);
3759 ivarList.fillPlaceholderWithInt(countSlot, ObjCTypes.IntTy, count);
3761 llvm::GlobalVariable *GV;
3764 CreateMetadataVar(
"OBJC_CLASS_VARIABLES_" + ID->
getName(), ivarList,
3765 "__OBJC,__class_vars,regular,no_dead_strip",
3768 GV = CreateMetadataVar(
"OBJC_INSTANCE_VARIABLES_" + ID->
getName(), ivarList,
3769 "__OBJC,__instance_vars,regular,no_dead_strip",
3771 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy);
3782 auto description = builder.
beginStruct(ObjCTypes.MethodDescriptionTy);
3783 description.addBitCast(GetMethodVarName(MD->
getSelector()),
3784 ObjCTypes.SelectorPtrTy);
3785 description.add(GetMethodVarType(MD));
3786 description.finishAndAddTo(builder);
3798 llvm::Function *fn = GetMethodDefinition(MD);
3799 assert(fn &&
"no definition registered for method");
3801 auto method = builder.
beginStruct(ObjCTypes.MethodTy);
3802 method.addBitCast(GetMethodVarName(MD->
getSelector()),
3803 ObjCTypes.SelectorPtrTy);
3804 method.add(GetMethodVarType(MD));
3805 method.addBitCast(fn, ObjCTypes.Int8PtrTy);
3806 method.finishAndAddTo(builder);
3822 llvm::Constant *CGObjCMac::emitMethodList(Twine name,
MethodListType MLT,
3826 bool forProtocol =
false;
3828 case MethodListType::CategoryInstanceMethods:
3829 prefix =
"OBJC_CATEGORY_INSTANCE_METHODS_";
3830 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
3831 forProtocol =
false;
3833 case MethodListType::CategoryClassMethods:
3834 prefix =
"OBJC_CATEGORY_CLASS_METHODS_";
3835 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3836 forProtocol =
false;
3838 case MethodListType::InstanceMethods:
3839 prefix =
"OBJC_INSTANCE_METHODS_";
3840 section =
"__OBJC,__inst_meth,regular,no_dead_strip";
3841 forProtocol =
false;
3843 case MethodListType::ClassMethods:
3844 prefix =
"OBJC_CLASS_METHODS_";
3845 section =
"__OBJC,__cls_meth,regular,no_dead_strip";
3846 forProtocol =
false;
3848 case MethodListType::ProtocolInstanceMethods:
3849 prefix =
"OBJC_PROTOCOL_INSTANCE_METHODS_";
3850 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
3853 case MethodListType::ProtocolClassMethods:
3854 prefix =
"OBJC_PROTOCOL_CLASS_METHODS_";
3855 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3858 case MethodListType::OptionalProtocolInstanceMethods:
3859 prefix =
"OBJC_PROTOCOL_INSTANCE_METHODS_OPT_";
3860 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
3863 case MethodListType::OptionalProtocolClassMethods:
3864 prefix =
"OBJC_PROTOCOL_CLASS_METHODS_OPT_";
3865 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3871 if (methods.empty())
3872 return llvm::Constant::getNullValue(forProtocol
3873 ? ObjCTypes.MethodDescriptionListPtrTy
3874 : ObjCTypes.MethodListPtrTy);
3881 values.addInt(ObjCTypes.IntTy, methods.size());
3882 auto methodArray = values.beginArray(ObjCTypes.MethodDescriptionTy);
3883 for (
auto MD : methods) {
3884 emitMethodDescriptionConstant(methodArray, MD);
3886 methodArray.finishAndAddTo(values);
3888 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
3890 return llvm::ConstantExpr::getBitCast(GV,
3891 ObjCTypes.MethodDescriptionListPtrTy);
3897 values.addNullPointer(ObjCTypes.Int8PtrTy);
3898 values.addInt(ObjCTypes.IntTy, methods.size());
3899 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
3900 for (
auto MD : methods) {
3901 emitMethodConstant(methodArray, MD);
3903 methodArray.finishAndAddTo(values);
3905 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
3907 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListPtrTy);
3910 llvm::Function *CGObjCCommonMac::GenerateMethod(
const ObjCMethodDecl *OMD,
3913 GetNameForMethod(OMD, CD, Name);
3916 llvm::FunctionType *MethodTy =
3918 llvm::Function *Method =
3923 MethodDefinitions.insert(std::make_pair(OMD, Method));
3928 llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
3933 llvm::GlobalVariable *GV =
3935 llvm::GlobalValue::PrivateLinkage);
3936 if (!Section.empty())
3937 GV->setSection(Section);
3943 llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
3944 llvm::Constant *Init,
3949 llvm::GlobalVariable *GV =
3950 new llvm::GlobalVariable(CGM.
getModule(), Ty,
false,
3951 llvm::GlobalValue::PrivateLinkage, Init, Name);
3952 if (!Section.empty())
3953 GV->setSection(Section);
3960 llvm::GlobalVariable *
3962 bool ForceNonFragileABI,
3963 bool NullTerminate) {
3966 case ObjCLabelType::ClassName: Label =
"OBJC_CLASS_NAME_";
break;
3967 case ObjCLabelType::MethodVarName: Label =
"OBJC_METH_VAR_NAME_";
break;
3968 case ObjCLabelType::MethodVarType: Label =
"OBJC_METH_VAR_TYPE_";
break;
3969 case ObjCLabelType::PropertyName: Label =
"OBJC_PROP_NAME_ATTR_";
break;
3972 bool NonFragile = ForceNonFragileABI || isNonFragileABI();
3976 case ObjCLabelType::ClassName:
3977 Section = NonFragile ?
"__TEXT,__objc_classname,cstring_literals" 3978 :
"__TEXT,__cstring,cstring_literals";
3980 case ObjCLabelType::MethodVarName:
3981 Section = NonFragile ?
"__TEXT,__objc_methname,cstring_literals" 3982 :
"__TEXT,__cstring,cstring_literals";
3984 case ObjCLabelType::MethodVarType:
3985 Section = NonFragile ?
"__TEXT,__objc_methtype,cstring_literals" 3986 :
"__TEXT,__cstring,cstring_literals";
3988 case ObjCLabelType::PropertyName:
3989 Section =
"__TEXT,__cstring,cstring_literals";
3993 llvm::Constant *
Value =
3994 llvm::ConstantDataArray::getString(VMContext, Name, NullTerminate);
3995 llvm::GlobalVariable *GV =
3996 new llvm::GlobalVariable(CGM.
getModule(), Value->getType(),
3998 llvm::GlobalValue::PrivateLinkage,
Value,
Label);
3999 if (CGM.
getTriple().isOSBinFormatMachO())
4000 GV->setSection(Section);
4001 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4008 llvm::Function *CGObjCMac::ModuleInitFunction() {
4014 llvm::Constant *CGObjCMac::GetPropertyGetFunction() {
4015 return ObjCTypes.getGetPropertyFn();
4018 llvm::Constant *CGObjCMac::GetPropertySetFunction() {
4019 return ObjCTypes.getSetPropertyFn();
4022 llvm::Constant *CGObjCMac::GetOptimizedPropertySetFunction(
bool atomic,
4024 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
4027 llvm::Constant *CGObjCMac::GetGetStructFunction() {
4028 return ObjCTypes.getCopyStructFn();
4031 llvm::Constant *CGObjCMac::GetSetStructFunction() {
4032 return ObjCTypes.getCopyStructFn();
4035 llvm::Constant *CGObjCMac::GetCppAtomicObjectGetFunction() {
4036 return ObjCTypes.getCppAtomicObjectFunction();
4039 llvm::Constant *CGObjCMac::GetCppAtomicObjectSetFunction() {
4040 return ObjCTypes.getCppAtomicObjectFunction();
4043 llvm::Constant *CGObjCMac::EnumerationMutationFunction() {
4044 return ObjCTypes.getEnumerationMutationFn();
4048 return EmitTryOrSynchronizedStmt(CGF, S);
4053 return EmitTryOrSynchronizedStmt(CGF, S);
4062 ObjCTypesHelper &ObjCTypes;
4063 PerformFragileFinally(
const Stmt *S,
4067 ObjCTypesHelper *ObjCTypes)
4068 : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
4069 ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
4074 llvm::BasicBlock *FinallyCallExit =
4076 llvm::BasicBlock *FinallyNoCallExit =
4079 FinallyCallExit, FinallyNoCallExit);
4087 if (isa<ObjCAtTryStmt>(S)) {
4089 cast<ObjCAtTryStmt>(S).getFinallyStmt()) {
4091 if (flags.isForEHCleanup())
return;
4098 CGF.
EmitStmt(FinallyStmt->getFinallyBody());
4117 class FragileHazards {
4122 llvm::InlineAsm *ReadHazard;
4123 llvm::InlineAsm *WriteHazard;
4125 llvm::FunctionType *GetAsmFnType();
4127 void collectLocals();
4133 void emitWriteHazard();
4134 void emitHazardsInNewBlocks();
4146 if (Locals.empty())
return;
4149 for (llvm::Function::iterator
4150 I = CGF.
CurFn->begin(), E = CGF.
CurFn->end(); I != E; ++I)
4151 BlocksBeforeTry.insert(&*I);
4153 llvm::FunctionType *AsmFnTy = GetAsmFnType();
4161 std::string Constraint;
4162 for (
unsigned I = 0, E = Locals.size(); I != E; ++I) {
4163 if (I) Constraint +=
',';
4167 ReadHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
4175 std::string Constraint;
4176 for (
unsigned I = 0, E = Locals.size(); I != E; ++I) {
4177 if (I) Constraint +=
',';
4178 Constraint +=
"=*m";
4181 WriteHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
4186 void FragileHazards::emitWriteHazard() {
4187 if (Locals.empty())
return;
4192 void FragileHazards::emitReadHazard(
CGBuilderTy &Builder) {
4193 assert(!Locals.empty());
4194 llvm::CallInst *call = Builder.CreateCall(ReadHazard, Locals);
4195 call->setDoesNotThrow();
4201 void FragileHazards::emitHazardsInNewBlocks() {
4202 if (Locals.empty())
return;
4207 for (llvm::Function::iterator
4208 FI = CGF.
CurFn->begin(), FE = CGF.
CurFn->end(); FI != FE; ++FI) {
4209 llvm::BasicBlock &BB = *FI;
4210 if (BlocksBeforeTry.count(&BB))
continue;
4213 for (llvm::BasicBlock::iterator
4214 BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) {
4215 llvm::Instruction &I = *BI;
4219 if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I))
continue;
4220 if (isa<llvm::IntrinsicInst>(I))
4225 llvm::CallSite CS(&I);
4226 if (CS.doesNotThrow())
continue;
4233 Builder.SetInsertPoint(&BB, BI);
4234 emitReadHazard(Builder);
4243 void FragileHazards::collectLocals() {
4251 llvm::BasicBlock &Entry = CGF.
CurFn->getEntryBlock();
4252 for (llvm::BasicBlock::iterator
4253 I = Entry.begin(), E = Entry.end(); I != E; ++I)
4254 if (isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I))
4255 Locals.push_back(&*I);
4258 llvm::FunctionType *FragileHazards::GetAsmFnType() {
4260 for (
unsigned i = 0, e = Locals.size(); i != e; ++i)
4261 tys[i] = Locals[i]->getType();
4262 return llvm::FunctionType::get(CGF.
VoidTy, tys,
false);
4379 bool isTry = isa<ObjCAtTryStmt>(S);
4399 CGF.
EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
4412 "exceptiondata.ptr");
4418 FragileHazards Hazards(CGF);
4447 ExceptionData.getPointer());
4450 llvm::Constant *Zero = llvm::ConstantInt::get(CGF.
Builder.getInt32Ty(), 0);
4453 ObjCTypes.ExceptionDataTy, ExceptionData.getPointer(), GEPIndexes,
4456 ObjCTypes.getSetJmpFn(), SetJmpBuffer,
"setjmp_result");
4457 SetJmpResult->setCanReturnTwice();
4464 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
4465 CGF.
Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
4470 CGF.
EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
4471 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
4473 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.
Builder.saveAndClearIP();
4479 Hazards.emitWriteHazard();
4483 if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
4492 llvm::CallInst *Caught =
4494 ExceptionData.getPointer(),
"caught");
4504 llvm::BasicBlock *CatchBlock =
nullptr;
4505 llvm::BasicBlock *CatchHandler =
nullptr;
4511 "propagating_exception");
4517 ExceptionData.getPointer());
4519 llvm::CallInst *SetJmpResult =
4521 SetJmpBuffer,
"setjmp.result");
4522 SetJmpResult->setCanReturnTwice();
4525 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
4529 CGF.
Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
4539 bool AllMatched =
false;
4569 EmitInitOfCatchParam(CGF, Caught, CatchParam);
4581 assert(OPT &&
"Unexpected non-object pointer type in @catch");
4586 assert(IDecl &&
"Catch parameter must have Objective-C type!");
4592 llvm::CallInst *Match =
4594 matchArgs,
"match");
4599 CGF.
Builder.CreateCondBr(CGF.
Builder.CreateIsNotNull(Match,
"matched"),
4600 MatchedBlock, NextCatchBlock);
4616 EmitInitOfCatchParam(CGF, Tmp, CatchParam);
4632 if (Caught->use_empty())
4633 Caught->eraseFromParent();
4649 assert(PropagatingExnVar.
isValid());
4650 llvm::CallInst *NewCaught =
4652 ExceptionData.getPointer(),
"caught");
4662 Hazards.emitHazardsInNewBlocks();
4665 CGF.
Builder.restoreIP(TryFallthroughIP);
4669 CGF.
EmitBlock(FinallyEnd.getBlock(),
true);
4672 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
4677 if (PropagatingExnVar.
isValid()) {
4682 llvm::CallInst *Caught =
4684 ExceptionData.getPointer());
4685 PropagatingExn = Caught;
4690 CGF.
Builder.CreateUnreachable();
4693 CGF.
Builder.restoreIP(SavedIP);
4698 bool ClearInsertionPoint) {
4707 "Unexpected rethrow outside @catch block.");
4711 CGF.
EmitRuntimeCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
4712 ->setDoesNotReturn();
4713 CGF.
Builder.CreateUnreachable();
4716 if (ClearInsertionPoint)
4717 CGF.
Builder.ClearInsertionPoint();
4727 ObjCTypes.PtrObjectPtrTy);
4741 if (!isa<llvm::PointerType>(SrcTy)) {
4742 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(SrcTy);
4743 assert(Size <= 8 && "does not support size > 8
"); 4744 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty) 4745 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty); 4746 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 4748 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 4749 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 4750 llvm::Value *args[] = { src, dst.getPointer() }; 4751 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), 4752 args, "weakassign
"); 4758 void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
4759 llvm::Value *src, Address dst,
4761 llvm::Type * SrcTy = src->getType();
4762 if (!isa<llvm::PointerType>(SrcTy)) {
4763 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4764 assert(Size <= 8 && "does
not support size > 8
"); 4765 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty) 4766 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty); 4767 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 4769 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 4770 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 4771 llvm::Value *args[] = { src, dst.getPointer() }; 4773 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), 4774 args, "globalassign
"); 4776 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(), 4777 args, "threadlocalassign
"); 4783 void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
4784 llvm::Value *src, Address dst,
4785 llvm::Value *ivarOffset) {
4786 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is
NULL"); 4787 llvm::Type * SrcTy = src->getType(); 4788 if (!isa<llvm::PointerType>(SrcTy)) { 4789 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy); 4790 assert(Size <= 8 && "does
not support size > 8
"); 4791 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty) 4792 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty); 4793 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 4795 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 4796 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 4797 llvm::Value *args[] = { src, dst.getPointer(), ivarOffset }; 4798 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args); 4804 void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
4805 llvm::Value *src, Address dst) {
4806 llvm::Type * SrcTy = src->getType();
4807 if (!isa<llvm::PointerType>(SrcTy)) {
4808 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4809 assert(Size <= 8 && "does
not support size > 8
"); 4810 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty) 4811 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty); 4812 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 4814 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 4815 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 4816 llvm::Value *args[] = { src, dst.getPointer() }; 4817 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), 4818 args, "strongassign
"); 4821 void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, 4824 llvm::Value *size) { 4825 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy); 4826 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy); 4827 llvm::Value *args[] = { DestPtr.getPointer(), SrcPtr.getPointer(), size }; 4828 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args); 4833 LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
4835 llvm::Value *BaseValue,
4836 const ObjCIvarDecl *Ivar,
4837 unsigned CVRQualifiers) {
4838 const ObjCInterfaceDecl *ID =
4839 ObjectTy->getAs<ObjCObjectType>()->getInterface();
4840 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
4841 EmitIvarOffset(CGF, ID, Ivar));
4844 llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
4845 const ObjCInterfaceDecl *Interface,
4846 const ObjCIvarDecl *Ivar) {
4847 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
4848 return llvm::ConstantInt::get(
4849 CGM.getTypes().ConvertType(CGM.getContext().LongTy),
4853 /* *** Private Interface *** */
4855 std::string CGObjCCommonMac::GetSectionName(StringRef Section,
4856 StringRef MachOAttributes) {
4857 switch (CGM.getTriple().getObjectFormat()) {
4859 llvm_unreachable("unexpected
object file format
"); 4860 case llvm::Triple::MachO: { 4861 if (MachOAttributes.empty()) 4862 return ("__DATA,
" + Section).str(); 4863 return ("__DATA,
" + Section + ",
" + MachOAttributes).str(); 4865 case llvm::Triple::ELF: 4866 assert(Section.substr(0, 2) == "__
" && 4867 "expected the name to begin with __
"); 4868 return Section.substr(2).str(); 4869 case llvm::Triple::COFF: 4870 assert(Section.substr(0, 2) == "__
" && 4871 "expected the name to begin with __
"); 4872 return (".
" + Section.substr(2) + "$B
").str(); 4884 enum ImageInfoFlags {
4885 eImageInfo_FixAndContinue = (1 << 0), // This flag is no longer set by clang.
4886 eImageInfo_GarbageCollected = (1 << 1),
4887 eImageInfo_GCOnly = (1 << 2),
4888 eImageInfo_OptimizedByDyld = (1 << 3), // This flag is set by the dyld shared cache.
4890 // A flag indicating that the module has no instances of a @synthesize of a
4891 // superclass variable. <rdar://problem/6803242>
4892 eImageInfo_CorrectedSynthesize = (1 << 4), // This flag is no longer set by clang.
4893 eImageInfo_ImageIsSimulated = (1 << 5),
4894 eImageInfo_ClassProperties = (1 << 6)
4897 void CGObjCCommonMac::EmitImageInfo() {
4898 unsigned version = 0; // Version is unused?
4899 std::string Section =
4901 ? "__OBJC,__image_info,regular
" 4902 : GetSectionName("__objc_imageinfo
", "regular,no_dead_strip
"); 4904 // Generate module-level named metadata to convey this information to the 4905 // linker and code-gen. 4906 llvm::Module &Mod = CGM.getModule(); 4908 // Add the ObjC ABI version to the module flags. 4909 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Version
", ObjCABI); 4910 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Version
", 4912 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Section
", 4913 llvm::MDString::get(VMContext, Section)); 4915 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) { 4916 // Non-GC overrides those files which specify GC. 4917 Mod.addModuleFlag(llvm::Module::Override, 4918 "Objective-C Garbage Collection
", (uint32_t)0); 4920 // Add the ObjC garbage collection value. 4921 Mod.addModuleFlag(llvm::Module::Error, 4922 "Objective-C Garbage Collection
", 4923 eImageInfo_GarbageCollected); 4925 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) { 4926 // Add the ObjC GC Only value. 4927 Mod.addModuleFlag(llvm::Module::Error, "Objective-C GC Only
", 4930 // Require that GC be specified and set to eImageInfo_GarbageCollected. 4931 llvm::Metadata *Ops[2] = { 4932 llvm::MDString::get(VMContext, "Objective-C Garbage Collection
"), 4933 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( 4934 llvm::Type::getInt32Ty(VMContext), eImageInfo_GarbageCollected))}; 4935 Mod.addModuleFlag(llvm::Module::Require, "Objective-C GC Only
", 4936 llvm::MDNode::get(VMContext, Ops)); 4940 // Indicate whether we're compiling this to run on a simulator. 4941 if (CGM.getTarget().getTriple().isSimulatorEnvironment()) 4942 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Is Simulated
", 4943 eImageInfo_ImageIsSimulated); 4945 // Indicate whether we are generating class properties. 4946 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Class Properties
", 4947 eImageInfo_ClassProperties); 4950 // struct objc_module { 4951 // unsigned long version; 4952 // unsigned long size; 4953 // const char *name; 4957 // FIXME: Get from somewhere 4958 static const int ModuleVersion = 7; 4960 void CGObjCMac::EmitModuleInfo() { 4961 uint64_t Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ModuleTy); 4963 ConstantInitBuilder builder(CGM); 4964 auto values = builder.beginStruct(ObjCTypes.ModuleTy); 4965 values.addInt(ObjCTypes.LongTy, ModuleVersion); 4966 values.addInt(ObjCTypes.LongTy, Size); 4967 // This used to be the filename, now it is unused. <rdr://4327263> 4968 values.add(GetClassName(StringRef(""))); 4969 values.add(EmitModuleSymbols()); 4970 CreateMetadataVar("OBJC_MODULES
", values, 4971 "__OBJC,__module_info,regular,no_dead_strip
", 4972 CGM.getPointerAlign(), true); 4975 llvm::Constant *CGObjCMac::EmitModuleSymbols() { 4976 unsigned NumClasses = DefinedClasses.size(); 4977 unsigned NumCategories = DefinedCategories.size(); 4979 // Return null if no symbols were defined. 4980 if (!NumClasses && !NumCategories) 4981 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy); 4983 ConstantInitBuilder builder(CGM); 4984 auto values = builder.beginStruct(); 4985 values.addInt(ObjCTypes.LongTy, 0); 4986 values.addNullPointer(ObjCTypes.SelectorPtrTy); 4987 values.addInt(ObjCTypes.ShortTy, NumClasses); 4988 values.addInt(ObjCTypes.ShortTy, NumCategories); 4990 // The runtime expects exactly the list of defined classes followed 4991 // by the list of defined categories, in a single array. 4992 auto array = values.beginArray(ObjCTypes.Int8PtrTy); 4993 for (unsigned i=0; i<NumClasses; i++) { 4994 const ObjCInterfaceDecl *ID = ImplementedClasses[i]; 4996 if (ObjCImplementationDecl *IMP = ID->getImplementation()) 4997 // We are implementing a weak imported interface. Give it external linkage 4998 if (ID->isWeakImported() && !IMP->isWeakImported()) 4999 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage); 5001 array.addBitCast(DefinedClasses[i], ObjCTypes.Int8PtrTy); 5003 for (unsigned i=0; i<NumCategories; i++) 5004 array.addBitCast(DefinedCategories[i], ObjCTypes.Int8PtrTy); 5006 array.finishAndAddTo(values); 5008 llvm::GlobalVariable *GV = CreateMetadataVar( 5009 "OBJC_SYMBOLS
", values, "__OBJC,__symbols,regular,no_dead_strip
", 5010 CGM.getPointerAlign(), true); 5011 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy); 5014 llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF, 5015 IdentifierInfo *II) { 5016 LazySymbols.insert(II); 5018 llvm::GlobalVariable *&Entry = ClassReferences[II]; 5021 llvm::Constant *Casted = 5022 llvm::ConstantExpr::getBitCast(GetClassName(II->getName()), 5023 ObjCTypes.ClassPtrTy); 5024 Entry = CreateMetadataVar( 5025 "OBJC_CLASS_REFERENCES_
", Casted, 5026 "__OBJC,__cls_refs,literal_pointers,no_dead_strip
", 5027 CGM.getPointerAlign(), true); 5030 return CGF.Builder.CreateAlignedLoad(Entry, CGF.getPointerAlign()); 5033 llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF, 5034 const ObjCInterfaceDecl *ID) { 5035 // If the class has the objc_runtime_visible attribute, we need to 5036 // use the Objective-C runtime to get the class. 5037 if (ID->hasAttr<ObjCRuntimeVisibleAttr>()) 5038 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes); 5040 IdentifierInfo *RuntimeName = 5041 &CGM.getContext().Idents.get(ID->getObjCRuntimeNameAsString()); 5042 return EmitClassRefFromId(CGF, RuntimeName); 5045 llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) { 5046 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool
"); 5047 return EmitClassRefFromId(CGF, II); 5050 llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel) { 5051 return CGF.Builder.CreateLoad(EmitSelectorAddr(CGF, Sel)); 5054 Address CGObjCMac::EmitSelectorAddr(CodeGenFunction &CGF, Selector Sel) { 5055 CharUnits Align = CGF.getPointerAlign(); 5057 llvm::GlobalVariable *&Entry = SelectorReferences[Sel]; 5059 llvm::Constant *Casted = 5060 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel), 5061 ObjCTypes.SelectorPtrTy); 5062 Entry = CreateMetadataVar( 5063 "OBJC_SELECTOR_REFERENCES_
", Casted, 5064 "__OBJC,__message_refs,literal_pointers,no_dead_strip
", Align, true); 5065 Entry->setExternallyInitialized(true); 5068 return Address(Entry, Align); 5071 llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) { 5072 llvm::GlobalVariable *&Entry = ClassNames[RuntimeName]; 5074 Entry = CreateCStringLiteral(RuntimeName, ObjCLabelType::ClassName); 5075 return getConstantGEP(VMContext, Entry, 0, 0); 5078 llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) { 5079 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*>::iterator 5080 I = MethodDefinitions.find(MD); 5081 if (I != MethodDefinitions.end()) 5089 llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
5090 const ObjCCommonTypesHelper &ObjCTypes) {
5091 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
5094 void IvarLayoutBuilder::visitRecord(const RecordType *RT,
5096 const RecordDecl *RD = RT->getDecl();
5098 // If this is a union, remember that we had one, because it might mess
5099 // up the ordering of layout entries.
5101 IsDisordered = true;
5103 const ASTRecordLayout *recLayout = nullptr;
5104 visitAggregate(RD->field_begin(), RD->field_end(), offset,
5105 [&](const FieldDecl *field) -> CharUnits {
5107 recLayout = &CGM.getContext().getASTRecordLayout(RD);
5108 auto offsetInBits = recLayout->getFieldOffset(field->getFieldIndex());
5109 return CGM.getContext().toCharUnitsFromBits(offsetInBits);
5113 template <class Iterator, class GetOffsetFn>
5114 void IvarLayoutBuilder::visitAggregate(Iterator begin, Iterator end,
5115 CharUnits aggregateOffset,
5116 const GetOffsetFn &getOffset) {
5117 for (; begin != end; ++begin) {
5118 auto field = *begin;
5120 // Skip over bitfields.
5121 if (field->isBitField()) {
5125 // Compute the offset of the field within the aggregate.
5126 CharUnits fieldOffset = aggregateOffset + getOffset(field);
5128 visitField(field, fieldOffset);
5133 void IvarLayoutBuilder::visitField(const FieldDecl *field,
5134 CharUnits fieldOffset) {
5135 QualType fieldType = field->getType();
5137 // Drill down into arrays.
5138 uint64_t numElts = 1;
5139 if (auto arrayType = CGM.getContext().getAsIncompleteArrayType(fieldType)) {
5141 fieldType = arrayType->getElementType();
5143 // Unlike incomplete arrays, constant arrays can be nested.
5144 while (auto arrayType = CGM.getContext().getAsConstantArrayType(fieldType)) {
5145 numElts *= arrayType->getSize().getZExtValue();
5146 fieldType = arrayType->getElementType();
5149 assert(!fieldType->isArrayType() && "ivar of non-constant array
type?
"); 5151 // If we ended up with a zero-sized array, we've done what we can do within 5152 // the limits of this layout encoding. 5153 if (numElts == 0) return; 5155 // Recurse if the base element type is a record type. 5156 if (auto recType = fieldType->getAs<RecordType>()) { 5157 size_t oldEnd = IvarsInfo.size(); 5159 visitRecord(recType, fieldOffset); 5161 // If we have an array, replicate the first entry's layout information. 5162 auto numEltEntries = IvarsInfo.size() - oldEnd; 5163 if (numElts != 1 && numEltEntries != 0) { 5164 CharUnits eltSize = CGM.getContext().getTypeSizeInChars(recType); 5165 for (uint64_t eltIndex = 1; eltIndex != numElts; ++eltIndex) { 5166 // Copy the last numEltEntries onto the end of the array, adjusting 5167 // each for the element size. 5168 for (size_t i = 0; i != numEltEntries; ++i) { 5169 auto firstEntry = IvarsInfo[oldEnd + i]; 5170 IvarsInfo.push_back(IvarInfo(firstEntry.Offset + eltIndex * eltSize, 5171 firstEntry.SizeInWords)); 5179 // Classify the element type. 5180 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), fieldType); 5182 // If it matches what we're looking for, add an entry. 5183 if ((ForStrongLayout && GCAttr == Qualifiers::Strong) 5184 || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) { 5185 assert(CGM.getContext().getTypeSizeInChars(fieldType) 5186 == CGM.getPointerSize()); 5187 IvarsInfo.push_back(IvarInfo(fieldOffset, numElts)); 5194 llvm::Constant *IvarLayoutBuilder::buildBitmap(CGObjCCommonMac &CGObjC,
5195 llvm::SmallVectorImpl<unsigned char> &buffer) {
5196 // The bitmap is a series of skip/scan instructions, aligned to word
5197 // boundaries. The skip is performed first.
5198 const unsigned char MaxNibble = 0xF;
5199 const unsigned char SkipMask = 0xF0, SkipShift = 4;
5200 const unsigned char ScanMask = 0x0F, ScanShift = 0;
5202 assert(!IvarsInfo.empty() && "generating bitmap
for no data
"); 5204 // Sort the ivar info on byte position in case we encounterred a 5205 // union nested in the ivar list. 5207 // This isn't a stable sort, but our algorithm should handle it fine. 5208 llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end()); 5210 assert(std::is_sorted(IvarsInfo.begin(), IvarsInfo.end())); 5212 assert(IvarsInfo.back().Offset < InstanceEnd); 5214 assert(buffer.empty()); 5216 // Skip the next N words. 5217 auto skip = [&](unsigned numWords) { 5218 assert(numWords > 0); 5220 // Try to merge into the previous byte. Since scans happen second, we 5221 // can't do this if it includes a scan. 5222 if (!buffer.empty() && !(buffer.back() & ScanMask)) { 5223 unsigned lastSkip = buffer.back() >> SkipShift; 5224 if (lastSkip < MaxNibble) { 5225 unsigned claimed = std::min(MaxNibble - lastSkip, numWords); 5226 numWords -= claimed; 5227 lastSkip += claimed; 5228 buffer.back() = (lastSkip << SkipShift); 5232 while (numWords >= MaxNibble) { 5233 buffer.push_back(MaxNibble << SkipShift); 5234 numWords -= MaxNibble; 5237 buffer.push_back(numWords << SkipShift); 5241 // Scan the next N words. 5242 auto scan = [&](unsigned numWords) { 5243 assert(numWords > 0); 5245 // Try to merge into the previous byte. Since scans happen second, we can 5246 // do this even if it includes a skip. 5247 if (!buffer.empty()) { 5248 unsigned lastScan = (buffer.back() & ScanMask) >> ScanShift; 5249 if (lastScan < MaxNibble) { 5250 unsigned claimed = std::min(MaxNibble - lastScan, numWords); 5251 numWords -= claimed; 5252 lastScan += claimed; 5253 buffer.back() = (buffer.back() & SkipMask) | (lastScan << ScanShift); 5257 while (numWords >= MaxNibble) { 5258 buffer.push_back(MaxNibble << ScanShift); 5259 numWords -= MaxNibble; 5262 buffer.push_back(numWords << ScanShift); 5266 // One past the end of the last scan. 5267 unsigned endOfLastScanInWords = 0; 5268 const CharUnits WordSize = CGM.getPointerSize(); 5270 // Consider all the scan requests. 5271 for (auto &request : IvarsInfo) { 5272 CharUnits beginOfScan = request.Offset - InstanceBegin; 5274 // Ignore scan requests that don't start at an even multiple of the 5275 // word size. We can't encode them. 5276 if ((beginOfScan % WordSize) != 0) continue; 5278 // Ignore scan requests that start before the instance start. 5279 // This assumes that scans never span that boundary. The boundary 5280 // isn't the true start of the ivars, because in the fragile-ARC case 5281 // it's rounded up to word alignment, but the test above should leave 5282 // us ignoring that possibility. 5283 if (beginOfScan.isNegative()) { 5284 assert(request.Offset + request.SizeInWords * WordSize <= InstanceBegin); 5288 unsigned beginOfScanInWords = beginOfScan / WordSize; 5289 unsigned endOfScanInWords = beginOfScanInWords + request.SizeInWords; 5291 // If the scan starts some number of words after the last one ended, 5293 if (beginOfScanInWords > endOfLastScanInWords) { 5294 skip(beginOfScanInWords - endOfLastScanInWords); 5296 // Otherwise, start scanning where the last left off. 5298 beginOfScanInWords = endOfLastScanInWords; 5300 // If that leaves us with nothing to scan, ignore this request. 5301 if (beginOfScanInWords >= endOfScanInWords) continue; 5304 // Scan to the end of the request. 5305 assert(beginOfScanInWords < endOfScanInWords); 5306 scan(endOfScanInWords - beginOfScanInWords); 5307 endOfLastScanInWords = endOfScanInWords; 5311 return llvm::ConstantPointerNull::get(CGM.Int8PtrTy); 5313 // For GC layouts, emit a skip to the end of the allocation so that we 5314 // have precise information about the entire thing. This isn't useful 5315 // or necessary for the ARC-style layout strings. 5316 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) { 5317 unsigned lastOffsetInWords = 5318 (InstanceEnd - InstanceBegin + WordSize - CharUnits::One()) / WordSize; 5319 if (lastOffsetInWords > endOfLastScanInWords) { 5320 skip(lastOffsetInWords - endOfLastScanInWords); 5324 // Null terminate the string. 5325 buffer.push_back(0); 5327 auto *Entry = CGObjC.CreateCStringLiteral( 5328 reinterpret_cast<char *>(buffer.data()), ObjCLabelType::ClassName); 5329 return getConstantGEP(CGM.getLLVMContext(), Entry, 0, 0); 5349 CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD,
5350 CharUnits beginOffset, CharUnits endOffset,
5351 bool ForStrongLayout, bool HasMRCWeakIvars) {
5352 // If this is MRC, and we're either building a strong layout or there
5353 // are no weak ivars, bail out early.
5354 llvm::Type *PtrTy = CGM.Int8PtrTy;
5355 if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
5356 !CGM.getLangOpts().ObjCAutoRefCount &&
5357 (ForStrongLayout || !HasMRCWeakIvars))
5358 return llvm::Constant::getNullValue(PtrTy);
5360 const ObjCInterfaceDecl *OI = OMD->getClassInterface();
5361 SmallVector<const ObjCIvarDecl*, 32> ivars;
5363 // GC layout strings include the complete object layout, possibly
5364 // inaccurately in the non-fragile ABI; the runtime knows how to fix this
5367 // ARC layout strings only include the class's ivars. In non-fragile
5368 // runtimes, that means starting at InstanceStart, rounded up to word
5369 // alignment. In fragile runtimes, there's no InstanceStart, so it means
5370 // starting at the offset of the first ivar, rounded up to word alignment.
5372 // MRC weak layout strings follow the ARC style.
5373 CharUnits baseOffset;
5374 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
5375 for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();
5376 IVD; IVD = IVD->getNextIvar())
5377 ivars.push_back(IVD);
5379 if (isNonFragileABI()) {
5380 baseOffset = beginOffset; // InstanceStart
5381 } else if (!ivars.empty()) {
5383 CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivars[0]));
5385 baseOffset = CharUnits::Zero();
5388 baseOffset = baseOffset.alignTo(CGM.getPointerAlign());
5391 CGM.getContext().DeepCollectObjCIvars(OI, true, ivars);
5393 baseOffset = CharUnits::Zero();
5397 return llvm::Constant::getNullValue(PtrTy);
5399 IvarLayoutBuilder builder(CGM, baseOffset, endOffset, ForStrongLayout);
5401 builder.visitAggregate(ivars.begin(), ivars.end(), CharUnits::Zero(),
5402 [&](const ObjCIvarDecl *ivar) -> CharUnits {
5403 return CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivar));
5406 if (!builder.hasBitmapData())
5407 return llvm::Constant::getNullValue(PtrTy);
5409 llvm::SmallVector<unsigned char, 4> buffer;
5410 llvm::Constant *C = builder.buildBitmap(*this, buffer);
5412 if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
5413 printf("\n%s ivar layout
for class '%s':
", 5414 ForStrongLayout ? "strong
" : "weak
", 5415 OMD->getClassInterface()->getName().str().c_str()); 5416 builder.dump(buffer); 5421 llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) { 5422 llvm::GlobalVariable *&Entry = MethodVarNames[Sel]; 5423 // FIXME: Avoid std::string in "Sel.getAsString()
" 5425 Entry = CreateCStringLiteral(Sel.getAsString(), ObjCLabelType::MethodVarName); 5426 return getConstantGEP(VMContext, Entry, 0, 0); 5429 // FIXME: Merge into a single cstring creation function. 5430 llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) { 5431 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID)); 5434 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) { 5435 std::string TypeStr; 5436 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field); 5438 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr]; 5440 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType); 5441 return getConstantGEP(VMContext, Entry, 0, 0); 5444 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D, 5446 std::string TypeStr = 5447 CGM.getContext().getObjCEncodingForMethodDecl(D, Extended); 5449 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr]; 5451 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType); 5452 return getConstantGEP(VMContext, Entry, 0, 0); 5455 // FIXME: Merge into a single cstring creation function. 5456 llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) { 5457 llvm::GlobalVariable *&Entry = PropertyNames[Ident]; 5459 Entry = CreateCStringLiteral(Ident->getName(), ObjCLabelType::PropertyName); 5460 return getConstantGEP(VMContext, Entry, 0, 0); 5463 // FIXME: Merge into a single cstring creation function. 5464 // FIXME: This Decl should be more precise. 5466 CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD, 5467 const Decl *Container) { 5468 std::string TypeStr = 5469 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container); 5470 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr)); 5473 void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D, 5474 const ObjCContainerDecl *CD, 5475 SmallVectorImpl<char> &Name) { 5476 llvm::raw_svector_ostream OS(Name); 5477 assert (CD && "Missing container
decl in GetNameForMethod
"); 5478 OS << '\01' << (D->isInstanceMethod() ? '-' : '+') 5479 << '[' << CD->getName(); 5480 if (const ObjCCategoryImplDecl *CID = 5481 dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext())) 5482 OS << '(' << *CID << ')'; 5483 OS << ' ' << D->getSelector().getAsString() << ']'; 5486 void CGObjCMac::FinishModule() { 5489 // Emit the dummy bodies for any protocols which were referenced but 5491 for (auto &entry : Protocols) { 5492 llvm::GlobalVariable *global = entry.second; 5493 if (global->hasInitializer()) 5496 ConstantInitBuilder builder(CGM); 5497 auto values = builder.beginStruct(ObjCTypes.ProtocolTy); 5498 values.addNullPointer(ObjCTypes.ProtocolExtensionPtrTy); 5499 values.add(GetClassName(entry.first->getName())); 5500 values.addNullPointer(ObjCTypes.ProtocolListPtrTy); 5501 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy); 5502 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy); 5503 values.finishAndSetAsInitializer(global); 5504 CGM.addCompilerUsedGlobal(global); 5507 // Add assembler directives to add lazy undefined symbol references 5508 // for classes which are referenced but not defined. This is 5509 // important for correct linker interaction. 5511 // FIXME: It would be nice if we had an LLVM construct for this. 5512 if ((!LazySymbols.empty() || !DefinedSymbols.empty()) && 5513 CGM.getTriple().isOSBinFormatMachO()) { 5514 SmallString<256> Asm; 5515 Asm += CGM.getModule().getModuleInlineAsm(); 5516 if (!Asm.empty() && Asm.back() != '\n') 5519 llvm::raw_svector_ostream OS(Asm); 5520 for (const auto *Sym : DefinedSymbols) 5521 OS << "\t.objc_class_name_
" << Sym->getName() << "=0\n
" 5522 << "\t.globl .objc_class_name_
" << Sym->getName() << "\n
"; 5523 for (const auto *Sym : LazySymbols) 5524 OS << "\t.lazy_reference .objc_class_name_
" << Sym->getName() << "\n
"; 5525 for (const auto &Category : DefinedCategoryNames) 5526 OS << "\t.objc_category_name_
" << Category << "=0\n
" 5527 << "\t.globl .objc_category_name_
" << Category << "\n
"; 5529 CGM.getModule().setModuleInlineAsm(OS.str()); 5533 CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm) 5534 : CGObjCCommonMac(cgm), ObjCTypes(cgm), ObjCEmptyCacheVar(nullptr), 5535 ObjCEmptyVtableVar(nullptr) { 5541 ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm) 5542 : VMContext(cgm.getLLVMContext()), CGM(cgm), ExternalProtocolPtrTy(nullptr) 5544 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 5545 ASTContext &Ctx = CGM.getContext(); 5547 ShortTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.ShortTy)); 5549 LongTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.LongTy)); 5550 Int8PtrTy = CGM.Int8PtrTy; 5551 Int8PtrPtrTy = CGM.Int8PtrPtrTy; 5553 // arm64 targets use "int" ivar offset variables. All others, 5554 // including OS X x86_64 and Windows x86_64, use "long" ivar offsets. 5555 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::aarch64) 5556 IvarOffsetVarTy = IntTy; 5558 IvarOffsetVarTy = LongTy; 5561 cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCIdType())); 5563 llvm::PointerType::getUnqual(ObjectPtrTy); 5565 cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCSelType())); 5567 // I'm not sure I like this. The implicit coordination is a bit 5568 // gross. We should solve this in a reasonable fashion because this 5569 // is a pretty common task (match some runtime data structure with 5570 // an LLVM data structure). 5572 // FIXME: This is leaked. 5573 // FIXME: Merge with rewriter code? 5575 // struct _objc_super { 5579 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct, 5580 Ctx.getTranslationUnitDecl(), 5581 SourceLocation(), SourceLocation(), 5582 &Ctx.Idents.get("_objc_super
")); 5583 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 5584 nullptr, Ctx.getObjCIdType(), nullptr, nullptr, 5585 false, ICIS_NoInit)); 5586 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 5587 nullptr, Ctx.getObjCClassType(), nullptr, 5588 nullptr, false, ICIS_NoInit)); 5589 RD->completeDefinition(); 5591 SuperCTy = Ctx.getTagDeclType(RD); 5592 SuperPtrCTy = Ctx.getPointerType(SuperCTy); 5594 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy)); 5595 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy); 5599 // char *attributes; 5601 PropertyTy = llvm::StructType::create("struct._prop_t
", Int8PtrTy, Int8PtrTy); 5603 // struct _prop_list_t { 5604 // uint32_t entsize; // sizeof(struct _prop_t) 5605 // uint32_t count_of_properties; 5606 // struct _prop_t prop_list[count_of_properties]; 5608 PropertyListTy = llvm::StructType::create( 5609 "struct._prop_list_t
", IntTy, IntTy, llvm::ArrayType::get(PropertyTy, 0)); 5610 // struct _prop_list_t * 5611 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy); 5613 // struct _objc_method { 5615 // char *method_type; 5618 MethodTy = llvm::StructType::create("struct._objc_method
", SelectorPtrTy, 5619 Int8PtrTy, Int8PtrTy); 5621 // struct _objc_cache * 5622 CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache
"); 5623 CachePtrTy = llvm::PointerType::getUnqual(CacheTy); 5626 ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) 5627 : ObjCCommonTypesHelper(cgm) { 5628 // struct _objc_method_description { 5632 MethodDescriptionTy = llvm::StructType::create( 5633 "struct._objc_method_description
", SelectorPtrTy, Int8PtrTy); 5635 // struct _objc_method_description_list { 5637 // struct _objc_method_description[1]; 5639 MethodDescriptionListTy = 5640 llvm::StructType::create("struct._objc_method_description_list
", IntTy, 5641 llvm::ArrayType::get(MethodDescriptionTy, 0)); 5643 // struct _objc_method_description_list * 5644 MethodDescriptionListPtrTy = 5645 llvm::PointerType::getUnqual(MethodDescriptionListTy); 5647 // Protocol description structures 5649 // struct _objc_protocol_extension { 5650 // uint32_t size; // sizeof(struct _objc_protocol_extension) 5651 // struct _objc_method_description_list *optional_instance_methods; 5652 // struct _objc_method_description_list *optional_class_methods; 5653 // struct _objc_property_list *instance_properties; 5654 // const char ** extendedMethodTypes; 5655 // struct _objc_property_list *class_properties; 5657 ProtocolExtensionTy = llvm::StructType::create( 5658 "struct._objc_protocol_extension
", IntTy, MethodDescriptionListPtrTy, 5659 MethodDescriptionListPtrTy, PropertyListPtrTy, Int8PtrPtrTy, 5662 // struct _objc_protocol_extension * 5663 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy); 5665 // Handle recursive construction of Protocol and ProtocolList types 5668 llvm::StructType::create(VMContext, "struct._objc_protocol
"); 5671 llvm::StructType::create(VMContext, "struct._objc_protocol_list
"); 5672 ProtocolListTy->setBody(llvm::PointerType::getUnqual(ProtocolListTy), LongTy, 5673 llvm::ArrayType::get(ProtocolTy, 0)); 5675 // struct _objc_protocol { 5676 // struct _objc_protocol_extension *isa; 5677 // char *protocol_name; 5678 // struct _objc_protocol **_objc_protocol_list; 5679 // struct _objc_method_description_list *instance_methods; 5680 // struct _objc_method_description_list *class_methods; 5682 ProtocolTy->setBody(ProtocolExtensionPtrTy, Int8PtrTy, 5683 llvm::PointerType::getUnqual(ProtocolListTy), 5684 MethodDescriptionListPtrTy, MethodDescriptionListPtrTy); 5686 // struct _objc_protocol_list * 5687 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy); 5689 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy); 5691 // Class description structures 5693 // struct _objc_ivar { 5698 IvarTy = llvm::StructType::create("struct._objc_ivar
", Int8PtrTy, Int8PtrTy, 5701 // struct _objc_ivar_list * 5703 llvm::StructType::create(VMContext, "struct._objc_ivar_list
"); 5704 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy); 5706 // struct _objc_method_list * 5708 llvm::StructType::create(VMContext, "struct._objc_method_list
"); 5709 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy); 5711 // struct _objc_class_extension * 5712 ClassExtensionTy = llvm::StructType::create( 5713 "struct._objc_class_extension
", IntTy, Int8PtrTy, PropertyListPtrTy); 5714 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy); 5716 ClassTy = llvm::StructType::create(VMContext, "struct._objc_class
"); 5718 // struct _objc_class { 5720 // Class super_class; 5724 // long instance_size; 5725 // struct _objc_ivar_list *ivars; 5726 // struct _objc_method_list *methods; 5727 // struct _objc_cache *cache; 5728 // struct _objc_protocol_list *protocols; 5729 // char *ivar_layout; 5730 // struct _objc_class_ext *ext; 5732 ClassTy->setBody(llvm::PointerType::getUnqual(ClassTy), 5733 llvm::PointerType::getUnqual(ClassTy), Int8PtrTy, LongTy, 5734 LongTy, LongTy, IvarListPtrTy, MethodListPtrTy, CachePtrTy, 5735 ProtocolListPtrTy, Int8PtrTy, ClassExtensionPtrTy); 5737 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy); 5739 // struct _objc_category { 5740 // char *category_name; 5741 // char *class_name; 5742 // struct _objc_method_list *instance_method; 5743 // struct _objc_method_list *class_method; 5744 // struct _objc_protocol_list *protocols; 5745 // uint32_t size; // sizeof(struct _objc_category) 5746 // struct _objc_property_list *instance_properties;// category's @property 5747 // struct _objc_property_list *class_properties; 5749 CategoryTy = llvm::StructType::create( 5750 "struct._objc_category
", Int8PtrTy, Int8PtrTy, MethodListPtrTy, 5751 MethodListPtrTy, ProtocolListPtrTy, IntTy, PropertyListPtrTy, 5754 // Global metadata structures 5756 // struct _objc_symtab { 5757 // long sel_ref_cnt; 5759 // short cls_def_cnt; 5760 // short cat_def_cnt; 5761 // char *defs[cls_def_cnt + cat_def_cnt]; 5763 SymtabTy = llvm::StructType::create("struct._objc_symtab
", LongTy, 5764 SelectorPtrTy, ShortTy, ShortTy, 5765 llvm::ArrayType::get(Int8PtrTy, 0)); 5766 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy); 5768 // struct _objc_module { 5770 // long size; // sizeof(struct _objc_module) 5772 // struct _objc_symtab* symtab; 5774 ModuleTy = llvm::StructType::create("struct._objc_module
", LongTy, LongTy, 5775 Int8PtrTy, SymtabPtrTy); 5777 // FIXME: This is the size of the setjmp buffer and should be target 5778 // specific. 18 is what's used on 32-bit X86. 5779 uint64_t SetJmpBufferSize = 18; 5782 llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4); 5784 ExceptionDataTy = llvm::StructType::create( 5785 "struct._objc_exception_data
", 5786 llvm::ArrayType::get(CGM.Int32Ty, SetJmpBufferSize), StackPtrTy); 5789 ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm) 5790 : ObjCCommonTypesHelper(cgm) { 5791 // struct _method_list_t { 5792 // uint32_t entsize; // sizeof(struct _objc_method) 5793 // uint32_t method_count; 5794 // struct _objc_method method_list[method_count]; 5797 llvm::StructType::create("struct.__method_list_t
", IntTy, IntTy, 5798 llvm::ArrayType::get(MethodTy, 0)); 5799 // struct method_list_t * 5800 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy); 5802 // struct _protocol_t { 5804 // const char * const protocol_name; 5805 // const struct _protocol_list_t * protocol_list; // super protocols 5806 // const struct method_list_t * const instance_methods; 5807 // const struct method_list_t * const class_methods; 5808 // const struct method_list_t *optionalInstanceMethods; 5809 // const struct method_list_t *optionalClassMethods; 5810 // const struct _prop_list_t * properties; 5811 // const uint32_t size; // sizeof(struct _protocol_t) 5812 // const uint32_t flags; // = 0 5813 // const char ** extendedMethodTypes; 5814 // const char *demangledName; 5815 // const struct _prop_list_t * class_properties; 5818 // Holder for struct _protocol_list_t * 5819 ProtocolListnfABITy = 5820 llvm::StructType::create(VMContext, "struct._objc_protocol_list
"); 5822 ProtocolnfABITy = llvm::StructType::create( 5823 "struct._protocol_t
", ObjectPtrTy, Int8PtrTy, 5824 llvm::PointerType::getUnqual(ProtocolListnfABITy), MethodListnfABIPtrTy, 5825 MethodListnfABIPtrTy, MethodListnfABIPtrTy, MethodListnfABIPtrTy, 5826 PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy, Int8PtrTy, 5829 // struct _protocol_t* 5830 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy); 5832 // struct _protocol_list_t { 5833 // long protocol_count; // Note, this is 32/64 bit 5834 // struct _protocol_t *[protocol_count]; 5836 ProtocolListnfABITy->setBody(LongTy, 5837 llvm::ArrayType::get(ProtocolnfABIPtrTy, 0)); 5839 // struct _objc_protocol_list* 5840 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy); 5843 // unsigned [long] int *offset; // pointer to ivar offset location 5846 // uint32_t alignment; 5849 IvarnfABITy = llvm::StructType::create( 5850 "struct._ivar_t
", llvm::PointerType::getUnqual(IvarOffsetVarTy), 5851 Int8PtrTy, Int8PtrTy, IntTy, IntTy); 5853 // struct _ivar_list_t { 5854 // uint32 entsize; // sizeof(struct _ivar_t) 5856 // struct _iver_t list[count]; 5859 llvm::StructType::create("struct._ivar_list_t
", IntTy, IntTy, 5860 llvm::ArrayType::get(IvarnfABITy, 0)); 5862 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy); 5864 // struct _class_ro_t { 5865 // uint32_t const flags; 5866 // uint32_t const instanceStart; 5867 // uint32_t const instanceSize; 5868 // uint32_t const reserved; // only when building for 64bit targets 5869 // const uint8_t * const ivarLayout; 5870 // const char *const name; 5871 // const struct _method_list_t * const baseMethods; 5872 // const struct _objc_protocol_list *const baseProtocols; 5873 // const struct _ivar_list_t *const ivars; 5874 // const uint8_t * const weakIvarLayout; 5875 // const struct _prop_list_t * const properties; 5878 // FIXME. Add 'reserved' field in 64bit abi mode! 5879 ClassRonfABITy = llvm::StructType::create( 5880 "struct._class_ro_t
", IntTy, IntTy, IntTy, Int8PtrTy, Int8PtrTy, 5881 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, IvarListnfABIPtrTy, 5882 Int8PtrTy, PropertyListPtrTy); 5884 // ImpnfABITy - LLVM for id (*)(id, SEL, ...) 5885 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy }; 5886 ImpnfABITy = llvm::FunctionType::get(ObjectPtrTy, params, false) 5889 // struct _class_t { 5890 // struct _class_t *isa; 5891 // struct _class_t * const superclass; 5894 // struct class_ro_t *ro; 5897 ClassnfABITy = llvm::StructType::create(VMContext, "struct._class_t
"); 5898 ClassnfABITy->setBody(llvm::PointerType::getUnqual(ClassnfABITy), 5899 llvm::PointerType::getUnqual(ClassnfABITy), CachePtrTy, 5900 llvm::PointerType::getUnqual(ImpnfABITy), 5901 llvm::PointerType::getUnqual(ClassRonfABITy)); 5903 // LLVM for struct _class_t * 5904 ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy); 5906 // struct _category_t { 5907 // const char * const name; 5908 // struct _class_t *const cls; 5909 // const struct _method_list_t * const instance_methods; 5910 // const struct _method_list_t * const class_methods; 5911 // const struct _protocol_list_t * const protocols; 5912 // const struct _prop_list_t * const properties; 5913 // const struct _prop_list_t * const class_properties; 5914 // const uint32_t size; 5916 CategorynfABITy = llvm::StructType::create( 5917 "struct._category_t
", Int8PtrTy, ClassnfABIPtrTy, MethodListnfABIPtrTy, 5918 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, PropertyListPtrTy, 5919 PropertyListPtrTy, IntTy); 5921 // New types for nonfragile abi messaging. 5922 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 5923 ASTContext &Ctx = CGM.getContext(); 5925 // MessageRefTy - LLVM for: 5926 // struct _message_ref_t { 5931 // First the clang type for struct _message_ref_t 5932 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct, 5933 Ctx.getTranslationUnitDecl(), 5934 SourceLocation(), SourceLocation(), 5935 &Ctx.Idents.get("_message_ref_t
")); 5936 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 5937 nullptr, Ctx.VoidPtrTy, nullptr, nullptr, false, 5939 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 5940 nullptr, Ctx.getObjCSelType(), nullptr, nullptr, 5941 false, ICIS_NoInit)); 5942 RD->completeDefinition(); 5944 MessageRefCTy = Ctx.getTagDeclType(RD); 5945 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy); 5946 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy)); 5948 // MessageRefPtrTy - LLVM for struct _message_ref_t* 5949 MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy); 5951 // SuperMessageRefTy - LLVM for: 5952 // struct _super_message_ref_t { 5953 // SUPER_IMP messenger; 5956 SuperMessageRefTy = llvm::StructType::create("struct._super_message_ref_t
", 5957 ImpnfABITy, SelectorPtrTy); 5959 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t* 5960 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy); 5963 // struct objc_typeinfo { 5964 // const void** vtable; // objc_ehtype_vtable + 2 5965 // const char* name; // c++ typeinfo string 5968 EHTypeTy = llvm::StructType::create("struct._objc_typeinfo
", 5969 llvm::PointerType::getUnqual(Int8PtrTy), 5970 Int8PtrTy, ClassnfABIPtrTy); 5971 EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy); 5974 llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() { 5975 FinishNonFragileABIModule(); 5980 void CGObjCNonFragileABIMac::AddModuleClassList( 5981 ArrayRef<llvm::GlobalValue *> Container, StringRef SymbolName, 5982 StringRef SectionName) { 5983 unsigned NumClasses = Container.size(); 5988 SmallVector<llvm::Constant*, 8> Symbols(NumClasses); 5989 for (unsigned i=0; i<NumClasses; i++) 5990 Symbols[i] = llvm::ConstantExpr::getBitCast(Container[i], 5991 ObjCTypes.Int8PtrTy); 5992 llvm::Constant *Init = 5993 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy, 5997 llvm::GlobalVariable *GV = 5998 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, 5999 llvm::GlobalValue::PrivateLinkage, 6002 GV->setAlignment(CGM.getDataLayout().getABITypeAlignment(Init->getType())); 6003 GV->setSection(SectionName); 6004 CGM.addCompilerUsedGlobal(GV); 6007 void CGObjCNonFragileABIMac::FinishNonFragileABIModule() { 6008 // nonfragile abi has no module definition. 6010 // Build list of all implemented class addresses in array 6011 // L_OBJC_LABEL_CLASS_$. 6013 for (unsigned i=0, NumClasses=ImplementedClasses.size(); i<NumClasses; i++) { 6014 const ObjCInterfaceDecl *ID = ImplementedClasses[i]; 6016 if (ObjCImplementationDecl *IMP = ID->getImplementation()) 6017 // We are implementing a weak imported interface. Give it external linkage 6018 if (ID->isWeakImported() && !IMP->isWeakImported()) { 6019 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage); 6020 DefinedMetaClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage); 6024 AddModuleClassList(DefinedClasses, "OBJC_LABEL_CLASS_$
", 6025 GetSectionName("__objc_classlist
", 6026 "regular,no_dead_strip
")); 6028 AddModuleClassList(DefinedNonLazyClasses, "OBJC_LABEL_NONLAZY_CLASS_$
", 6029 GetSectionName("__objc_nlclslist
", 6030 "regular,no_dead_strip
")); 6032 // Build list of all implemented category addresses in array 6033 // L_OBJC_LABEL_CATEGORY_$. 6034 AddModuleClassList(DefinedCategories, "OBJC_LABEL_CATEGORY_$
", 6035 GetSectionName("__objc_catlist
", 6036 "regular,no_dead_strip
")); 6037 AddModuleClassList(DefinedNonLazyCategories, "OBJC_LABEL_NONLAZY_CATEGORY_$
", 6038 GetSectionName("__objc_nlcatlist
", 6039 "regular,no_dead_strip
")); 6048 bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
6049 // At various points we've experimented with using vtable-based
6050 // dispatch for all methods.
6051 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
6052 case CodeGenOptions::Legacy:
6054 case CodeGenOptions::NonLegacy:
6056 case CodeGenOptions::Mixed:
6060 // If so, see whether this selector is in the white-list of things which must
6061 // use the new dispatch convention. We lazily build a dense set for this.
6062 if (VTableDispatchMethods.empty()) {
6063 VTableDispatchMethods.insert(GetNullarySelector("alloc
")); 6064 VTableDispatchMethods.insert(GetNullarySelector("class")); 6065 VTableDispatchMethods.insert(GetNullarySelector("self")); 6066 VTableDispatchMethods.insert(GetNullarySelector("isFlipped
")); 6067 VTableDispatchMethods.insert(GetNullarySelector("length")); 6068 VTableDispatchMethods.insert(GetNullarySelector("count
")); 6070 // These are vtable-based if GC is disabled. 6071 // Optimistically use vtable dispatch for hybrid compiles. 6072 if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) { 6073 VTableDispatchMethods.insert(GetNullarySelector("retain
")); 6074 VTableDispatchMethods.insert(GetNullarySelector("release
")); 6075 VTableDispatchMethods.insert(GetNullarySelector("autorelease
")); 6078 VTableDispatchMethods.insert(GetUnarySelector("allocWithZone
")); 6079 VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass
")); 6080 VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector
")); 6081 VTableDispatchMethods.insert(GetUnarySelector("objectForKey
")); 6082 VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex
")); 6083 VTableDispatchMethods.insert(GetUnarySelector("isEqualToString
")); 6084 VTableDispatchMethods.insert(GetUnarySelector("isEqual
")); 6086 // These are vtable-based if GC is enabled. 6087 // Optimistically use vtable dispatch for hybrid compiles. 6088 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) { 6089 VTableDispatchMethods.insert(GetNullarySelector("hash
")); 6090 VTableDispatchMethods.insert(GetUnarySelector("addObject
")); 6092 // "countByEnumeratingWithState:objects:count
" 6093 IdentifierInfo *KeyIdents[] = { 6094 &CGM.getContext().Idents.get("countByEnumeratingWithState
"), 6095 &CGM.getContext().Idents.get("objects
"), 6096 &CGM.getContext().Idents.get("count
") 6098 VTableDispatchMethods.insert( 6099 CGM.getContext().Selectors.getSelector(3, KeyIdents)); 6103 return VTableDispatchMethods.count(Sel); 6121 llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
6123 unsigned InstanceStart,
6124 unsigned InstanceSize,
6125 const ObjCImplementationDecl *ID) {
6126 std::string ClassName = ID->getObjCRuntimeNameAsString();
6128 CharUnits beginInstance = CharUnits::fromQuantity(InstanceStart);
6129 CharUnits endInstance = CharUnits::fromQuantity(InstanceSize);
6131 bool hasMRCWeak = false;
6132 if (CGM.getLangOpts().ObjCAutoRefCount)
6133 flags |= NonFragileABI_Class_CompiledByARC;
6134 else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))
6135 flags |= NonFragileABI_Class_HasMRCWeakIvars;
6137 ConstantInitBuilder builder(CGM);
6138 auto values = builder.beginStruct(ObjCTypes.ClassRonfABITy);
6140 values.addInt(ObjCTypes.IntTy, flags);
6141 values.addInt(ObjCTypes.IntTy, InstanceStart);
6142 values.addInt(ObjCTypes.IntTy, InstanceSize);
6143 values.add((flags & NonFragileABI_Class_Meta)
6144 ? GetIvarLayoutName(nullptr, ObjCTypes)
6145 : BuildStrongIvarLayout(ID, beginInstance, endInstance));
6146 values.add(GetClassName(ID->getObjCRuntimeNameAsString()));
6148 // const struct _method_list_t * const baseMethods;
6149 SmallVector<const ObjCMethodDecl*, 16> methods;
6150 if (flags & NonFragileABI_Class_Meta) {
6151 for (const auto *MD : ID->class_methods())
6152 methods.push_back(MD);
6154 for (const auto *MD : ID->instance_methods())
6155 methods.push_back(MD);
6157 for (const auto *PID : ID->property_impls()) {
6158 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){
6159 ObjCPropertyDecl *PD = PID->getPropertyDecl();
6161 if (auto MD = PD->getGetterMethodDecl())
6162 if (GetMethodDefinition(MD))
6163 methods.push_back(MD);
6164 if (auto MD = PD->getSetterMethodDecl())
6165 if (GetMethodDefinition(MD))
6166 methods.push_back(MD);
6171 values.add(emitMethodList(ID->getObjCRuntimeNameAsString(),
6172 (flags & NonFragileABI_Class_Meta)
6173 ? MethodListType::ClassMethods
6174 : MethodListType::InstanceMethods,
6177 const ObjCInterfaceDecl *OID = ID->getClassInterface();
6178 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer
"); 6179 values.add(EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_
" 6180 + OID->getObjCRuntimeNameAsString(), 6181 OID->all_referenced_protocol_begin(), 6182 OID->all_referenced_protocol_end())); 6184 if (flags & NonFragileABI_Class_Meta) { 6185 values.addNullPointer(ObjCTypes.IvarListnfABIPtrTy); 6186 values.add(GetIvarLayoutName(nullptr, ObjCTypes)); 6187 values.add(EmitPropertyList( 6188 "\01l_OBJC_$_CLASS_PROP_LIST_
" + ID->getObjCRuntimeNameAsString(), 6189 ID, ID->getClassInterface(), ObjCTypes, true)); 6191 values.add(EmitIvarList(ID)); 6192 values.add(BuildWeakIvarLayout(ID, beginInstance, endInstance, hasMRCWeak)); 6193 values.add(EmitPropertyList( 6194 "\01l_OBJC_$_PROP_LIST_
" + ID->getObjCRuntimeNameAsString(), 6195 ID, ID->getClassInterface(), ObjCTypes, false)); 6198 llvm::SmallString<64> roLabel; 6199 llvm::raw_svector_ostream(roLabel) 6200 << ((flags & NonFragileABI_Class_Meta) ? "\01l_OBJC_METACLASS_RO_$_
" 6201 : "\01l_OBJC_CLASS_RO_$_
") 6204 llvm::GlobalVariable *CLASS_RO_GV = 6205 values.finishAndCreateGlobal(roLabel, CGM.getPointerAlign(), 6207 llvm::GlobalValue::PrivateLinkage); 6208 if (CGM.getTriple().isOSBinFormatMachO()) 6209 CLASS_RO_GV->setSection("__DATA, __objc_const
"); 6223 llvm::GlobalVariable *
6224 CGObjCNonFragileABIMac::BuildClassObject(const ObjCInterfaceDecl *CI,
6226 llvm::Constant *IsAGV,
6227 llvm::Constant *SuperClassGV,
6228 llvm::Constant *ClassRoGV,
6229 bool HiddenVisibility) {
6230 ConstantInitBuilder builder(CGM);
6231 auto values = builder.beginStruct(ObjCTypes.ClassnfABITy);
6234 values.add(SuperClassGV);
6236 values.addNullPointer(ObjCTypes.ClassnfABIPtrTy);
6238 values.add(ObjCEmptyCacheVar);
6239 values.add(ObjCEmptyVtableVar);
6240 values.add(ClassRoGV);
6242 llvm::GlobalVariable *GV =
6243 cast<llvm::GlobalVariable>(GetClassGlobal(CI, isMetaclass, ForDefinition));
6244 values.finishAndSetAsInitializer(GV);
6246 if (CGM.getTriple().isOSBinFormatMachO())
6247 GV->setSection("__DATA, __objc_data
"); 6249 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassnfABITy)); 6250 if (!CGM.getTriple().isOSBinFormatCOFF()) 6251 if (HiddenVisibility) 6252 GV->setVisibility(llvm::GlobalValue::HiddenVisibility); 6257 CGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const { 6258 return OD->getClassMethod(GetNullarySelector("load
")) != nullptr; 6261 void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID, 6262 uint32_t &InstanceStart, 6263 uint32_t &InstanceSize) { 6264 const ASTRecordLayout &RL = 6265 CGM.getContext().getASTObjCImplementationLayout(OID); 6267 // InstanceSize is really instance end. 6268 InstanceSize = RL.getDataSize().getQuantity(); 6270 // If there are no fields, the start is the same as the end. 6271 if (!RL.getFieldCount()) 6272 InstanceStart = InstanceSize; 6274 InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth(); 6277 static llvm::GlobalValue::DLLStorageClassTypes getStorage(CodeGenModule &CGM, 6279 IdentifierInfo &II = CGM.getContext().Idents.get(Name); 6280 TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl(); 6281 DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl); 6283 const VarDecl *VD = nullptr; 6284 for (const auto &Result : DC->lookup(&II)) 6285 if ((VD = dyn_cast<VarDecl>(Result))) 6289 return llvm::GlobalValue::DLLImportStorageClass; 6290 if (VD->hasAttr<DLLExportAttr>()) 6291 return llvm::GlobalValue::DLLExportStorageClass; 6292 if (VD->hasAttr<DLLImportAttr>()) 6293 return llvm::GlobalValue::DLLImportStorageClass; 6294 return llvm::GlobalValue::DefaultStorageClass; 6297 void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { 6298 if (!ObjCEmptyCacheVar) { 6300 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CacheTy, false, 6301 llvm::GlobalValue::ExternalLinkage, nullptr, 6302 "_objc_empty_cache
"); 6303 if (CGM.getTriple().isOSBinFormatCOFF()) 6304 ObjCEmptyCacheVar->setDLLStorageClass(getStorage(CGM, "_objc_empty_cache
")); 6306 // Only OS X with deployment version <10.9 use the empty vtable symbol 6307 const llvm::Triple &Triple = CGM.getTarget().getTriple(); 6308 if (Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 9)) 6309 ObjCEmptyVtableVar = 6310 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ImpnfABITy, false, 6311 llvm::GlobalValue::ExternalLinkage, nullptr, 6312 "_objc_empty_vtable
"); 6314 ObjCEmptyVtableVar = 6315 llvm::ConstantPointerNull::get(ObjCTypes.ImpnfABITy->getPointerTo()); 6318 // FIXME: Is this correct (that meta class size is never computed)? 6319 uint32_t InstanceStart = 6320 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy); 6321 uint32_t InstanceSize = InstanceStart; 6322 uint32_t flags = NonFragileABI_Class_Meta; 6324 llvm::Constant *SuperClassGV, *IsAGV; 6326 const auto *CI = ID->getClassInterface(); 6327 assert(CI && "CGObjCNonFragileABIMac::GenerateClass -
class is 0");
6330 bool classIsHidden = (CGM.
getTriple().isOSBinFormatCOFF())
6331 ? !CI->hasAttr<DLLExportAttr>()
6344 if (!CI->getSuperClass()) {
6361 llvm::GlobalVariable *CLASS_RO_GV =
6362 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
6364 llvm::GlobalVariable *MetaTClass =
6365 BuildClassObject(CI,
true,
6366 IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden);
6368 DefinedMetaClasses.push_back(MetaTClass);
6391 if (!CI->getSuperClass()) {
6393 SuperClassGV =
nullptr;
6396 const auto *Super = CI->getSuperClass();
6400 GetClassSizeInfo(ID, InstanceStart, InstanceSize);
6402 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
6404 llvm::GlobalVariable *ClassMD =
6405 BuildClassObject(CI,
false,
6406 MetaTClass, SuperClassGV, CLASS_RO_GV, classIsHidden);
6408 DefinedClasses.push_back(ClassMD);
6409 ImplementedClasses.push_back(CI);
6412 if (ImplementationIsNonLazy(ID))
6413 DefinedNonLazyClasses.push_back(ClassMD);
6419 MethodDefinitions.clear();
6436 llvm::Constant *Init =
6437 llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD),
6438 ObjCTypes.getExternalProtocolPtrTy());
6440 std::string ProtocolName(
"\01l_OBJC_PROTOCOL_REFERENCE_$_");
6445 llvm::GlobalVariable *PTGV = CGM.
getModule().getGlobalVariable(ProtocolName);
6448 PTGV =
new llvm::GlobalVariable(CGM.
getModule(), Init->getType(),
false,
6449 llvm::GlobalValue::WeakAnyLinkage, Init,
6451 PTGV->setSection(GetSectionName(
"__objc_protorefs",
6452 "coalesced,no_dead_strip"));
6455 if (!CGM.
getTriple().isOSBinFormatMachO())
6456 PTGV->setComdat(CGM.
getModule().getOrInsertComdat(ProtocolName));
6475 const char *Prefix =
"\01l_OBJC_$_CATEGORY_";
6479 ExtCatName +=
"_$_";
6483 auto values = builder.
beginStruct(ObjCTypes.CategorynfABITy);
6487 std::string listName =
6492 for (
const auto *MD : OCD->
methods()) {
6494 instanceMethods.push_back(MD);
6496 classMethods.push_back(MD);
6500 values.add(emitMethodList(listName, MethodListType::CategoryInstanceMethods,
6502 values.add(emitMethodList(listName, MethodListType::CategoryClassMethods,
6511 values.add(EmitProtocolList(
"\01l_OBJC_CATEGORY_PROTOCOLS_$_" 6516 values.add(EmitPropertyList(
"\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
6518 values.add(EmitPropertyList(
"\01l_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(),
6521 values.addNullPointer(ObjCTypes.ProtocolListnfABIPtrTy);
6522 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
6523 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
6526 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.CategorynfABITy);
6527 values.addInt(ObjCTypes.IntTy, Size);
6529 llvm::GlobalVariable *GCATV =
6532 llvm::GlobalValue::PrivateLinkage);
6533 if (CGM.
getTriple().isOSBinFormatMachO())
6534 GCATV->setSection(
"__DATA, __objc_const");
6536 DefinedCategories.push_back(GCATV);
6539 if (ImplementationIsNonLazy(OCD))
6540 DefinedNonLazyCategories.push_back(GCATV);
6542 MethodDefinitions.clear();
6557 auto method = builder.
beginStruct(ObjCTypes.MethodTy);
6558 method.addBitCast(GetMethodVarName(MD->
getSelector()),
6559 ObjCTypes.SelectorPtrTy);
6560 method.add(GetMethodVarType(MD));
6564 method.addNullPointer(ObjCTypes.Int8PtrTy);
6566 llvm::Function *fn = GetMethodDefinition(MD);
6567 assert(fn &&
"no definition for method?");
6568 method.addBitCast(fn, ObjCTypes.Int8PtrTy);
6571 method.finishAndAddTo(builder);
6586 if (methods.empty())
6587 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
6592 case MethodListType::CategoryInstanceMethods:
6593 prefix =
"\01l_OBJC_$_CATEGORY_INSTANCE_METHODS_";
6594 forProtocol =
false;
6596 case MethodListType::CategoryClassMethods:
6597 prefix =
"\01l_OBJC_$_CATEGORY_CLASS_METHODS_";
6598 forProtocol =
false;
6600 case MethodListType::InstanceMethods:
6601 prefix =
"\01l_OBJC_$_INSTANCE_METHODS_";
6602 forProtocol =
false;
6604 case MethodListType::ClassMethods:
6605 prefix =
"\01l_OBJC_$_CLASS_METHODS_";
6606 forProtocol =
false;
6609 case MethodListType::ProtocolInstanceMethods:
6610 prefix =
"\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_";
6613 case MethodListType::ProtocolClassMethods:
6614 prefix =
"\01l_OBJC_$_PROTOCOL_CLASS_METHODS_";
6617 case MethodListType::OptionalProtocolInstanceMethods:
6618 prefix =
"\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_";
6621 case MethodListType::OptionalProtocolClassMethods:
6622 prefix =
"\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_";
6631 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.MethodTy);
6632 values.addInt(ObjCTypes.IntTy, Size);
6634 values.addInt(ObjCTypes.IntTy, methods.size());
6635 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
6636 for (
auto MD : methods) {
6637 emitMethodConstant(methodArray, MD, forProtocol);
6639 methodArray.finishAndAddTo(values);
6641 auto *GV = values.finishAndCreateGlobal(prefix + name, CGM.
getPointerAlign(),
6643 llvm::GlobalValue::PrivateLinkage);
6644 if (CGM.
getTriple().isOSBinFormatMachO())
6645 GV->setSection(
"__DATA, __objc_const");
6647 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListnfABIPtrTy);
6652 llvm::GlobalVariable *
6660 llvm::GlobalVariable *IvarOffsetGV = CGM.
getModule().getGlobalVariable(Name);
6661 if (!IvarOffsetGV) {
6663 new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.IvarOffsetVarTy,
6665 nullptr, Name.str());
6666 if (CGM.
getTriple().isOSBinFormatCOFF()) {
6667 bool IsPrivateOrPackage =
6673 if (ContainingID->
hasAttr<DLLImportAttr>())
6675 ->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
6676 else if (ContainingID->
hasAttr<DLLExportAttr>() && !IsPrivateOrPackage)
6678 ->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
6681 return IvarOffsetGV;
6687 unsigned long int Offset) {
6688 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
6689 IvarOffsetGV->setInitializer(
6690 llvm::ConstantInt::get(ObjCTypes.IvarOffsetVarTy, Offset));
6691 IvarOffsetGV->setAlignment(
6692 CGM.
getDataLayout().getABITypeAlignment(ObjCTypes.IvarOffsetVarTy));
6694 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
6705 if (CGM.
getTriple().isOSBinFormatMachO())
6706 IvarOffsetGV->setSection(
"__DATA, __objc_ivar");
6707 return IvarOffsetGV;
6727 llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
6732 ivarList.addInt(ObjCTypes.IntTy,
6733 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.IvarnfABITy));
6734 auto ivarCountSlot = ivarList.addPlaceholder();
6735 auto ivars = ivarList.beginArray(ObjCTypes.IvarnfABITy);
6738 assert(OID &&
"CGObjCNonFragileABIMac::EmitIvarList - null interface");
6745 if (!IVD->getDeclName())
6748 auto ivar = ivars.beginStruct(ObjCTypes.IvarnfABITy);
6750 ComputeIvarBaseOffset(CGM, ID, IVD)));
6751 ivar.add(GetMethodVarName(IVD->getIdentifier()));
6752 ivar.add(GetMethodVarType(IVD));
6755 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(FieldTy);
6757 IVD->getType().getTypePtr()) >> 3;
6758 Align = llvm::Log2_32(Align);
6759 ivar.addInt(ObjCTypes.IntTy, Align);
6765 ivar.addInt(ObjCTypes.IntTy, Size);
6766 ivar.finishAndAddTo(ivars);
6769 if (ivars.empty()) {
6772 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
6775 auto ivarCount = ivars.size();
6776 ivars.finishAndAddTo(ivarList);
6777 ivarList.fillPlaceholderWithInt(ivarCountSlot, ObjCTypes.IntTy, ivarCount);
6779 const char *Prefix =
"\01l_OBJC_$_INSTANCE_VARIABLES_";
6780 llvm::GlobalVariable *GV =
6783 llvm::GlobalValue::PrivateLinkage);
6784 if (CGM.
getTriple().isOSBinFormatMachO())
6785 GV->setSection(
"__DATA, __objc_const");
6787 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy);
6790 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(
6792 llvm::GlobalVariable *&Entry = Protocols[PD->
getIdentifier()];
6799 llvm::raw_svector_ostream(Protocol) <<
"\01l_OBJC_PROTOCOL_$_" 6802 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolnfABITy,
6805 if (!CGM.
getTriple().isOSBinFormatMachO())
6806 Entry->setComdat(CGM.
getModule().getOrInsertComdat(Protocol));
6832 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
6834 llvm::GlobalVariable *Entry = Protocols[PD->
getIdentifier()];
6837 if (Entry && Entry->hasInitializer())
6842 "emitting protocol metadata without definition");
6845 auto methodLists = ProtocolMethodLists::get(PD);
6848 auto values = builder.
beginStruct(ObjCTypes.ProtocolnfABITy);
6851 values.addNullPointer(ObjCTypes.ObjectPtrTy);
6852 values.add(GetClassName(PD->getObjCRuntimeNameAsString()));
6853 values.add(EmitProtocolList(
"\01l_OBJC_$_PROTOCOL_REFS_" 6854 + PD->getObjCRuntimeNameAsString(),
6855 PD->protocol_begin(),
6856 PD->protocol_end()));
6857 values.add(methodLists.emitMethodList(
this, PD,
6858 ProtocolMethodLists::RequiredInstanceMethods));
6859 values.add(methodLists.emitMethodList(
this, PD,
6860 ProtocolMethodLists::RequiredClassMethods));
6861 values.add(methodLists.emitMethodList(
this, PD,
6862 ProtocolMethodLists::OptionalInstanceMethods));
6863 values.add(methodLists.emitMethodList(
this, PD,
6864 ProtocolMethodLists::OptionalClassMethods));
6865 values.add(EmitPropertyList(
6866 "\01l_OBJC_$_PROP_LIST_" + PD->getObjCRuntimeNameAsString(),
6867 nullptr, PD, ObjCTypes,
false));
6869 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
6870 values.addInt(ObjCTypes.IntTy, Size);
6871 values.addInt(ObjCTypes.IntTy, 0);
6872 values.add(EmitProtocolMethodTypes(
"\01l_OBJC_$_PROTOCOL_METHOD_TYPES_" 6873 + PD->getObjCRuntimeNameAsString(),
6874 methodLists.emitExtendedTypesArray(
this),
6878 values.addNullPointer(ObjCTypes.Int8PtrTy);
6880 values.add(EmitPropertyList(
6881 "\01l_OBJC_$_CLASS_PROP_LIST_" + PD->getObjCRuntimeNameAsString(),
6882 nullptr, PD, ObjCTypes,
true));
6886 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
6887 values.finishAndSetAsInitializer(Entry);
6890 llvm::raw_svector_ostream(symbolName)
6891 <<
"\01l_OBJC_PROTOCOL_$_" << PD->getObjCRuntimeNameAsString();
6893 Entry = values.finishAndCreateGlobal(symbolName, CGM.
getPointerAlign(),
6895 llvm::GlobalValue::WeakAnyLinkage);
6896 if (!CGM.
getTriple().isOSBinFormatMachO())
6897 Entry->setComdat(CGM.
getModule().getOrInsertComdat(symbolName));
6899 Protocols[PD->getIdentifier()] = Entry;
6907 llvm::raw_svector_ostream(ProtocolRef) <<
"\01l_OBJC_LABEL_PROTOCOL_$_" 6908 << PD->getObjCRuntimeNameAsString();
6910 llvm::GlobalVariable *PTGV =
6911 new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolnfABIPtrTy,
6912 false, llvm::GlobalValue::WeakAnyLinkage, Entry,
6914 if (!CGM.
getTriple().isOSBinFormatMachO())
6915 PTGV->setComdat(CGM.
getModule().getOrInsertComdat(ProtocolRef));
6917 CGM.
getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy));
6918 PTGV->setSection(GetSectionName(
"__objc_protolist",
6919 "coalesced,no_dead_strip"));
6934 CGObjCNonFragileABIMac::EmitProtocolList(Twine Name,
6941 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
6945 Name.toVector(TmpName);
6946 llvm::GlobalVariable *GV =
6947 CGM.
getModule().getGlobalVariable(TmpName.str(),
true);
6949 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy);
6953 auto countSlot = values.addPlaceholder();
6956 auto array = values.beginArray(ObjCTypes.ProtocolnfABIPtrTy);
6957 for (; begin != end; ++begin)
6958 array.add(GetProtocolRef(*begin));
6959 auto count = array.size();
6960 array.addNullPointer(ObjCTypes.ProtocolnfABIPtrTy);
6962 array.finishAndAddTo(values);
6963 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
6967 llvm::GlobalValue::PrivateLinkage);
6968 if (CGM.
getTriple().isOSBinFormatMachO())
6969 GV->setSection(
"__DATA, __objc_const");
6971 return llvm::ConstantExpr::getBitCast(GV,
6972 ObjCTypes.ProtocolListnfABIPtrTy);
6981 LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
6986 unsigned CVRQualifiers) {
6988 llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
6989 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
6993 llvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset(
6997 llvm::Value *IvarOffsetValue = ObjCIvarOffsetVariable(Interface, Ivar);
7000 if (IsIvarOffsetKnownIdempotent(CGF, Ivar))
7001 cast<llvm::LoadInst>(IvarOffsetValue)
7002 ->setMetadata(CGM.
getModule().getMDKindID(
"invariant.load"),
7003 llvm::MDNode::get(VMContext,
None));
7008 if (ObjCTypes.IvarOffsetVarTy == ObjCTypes.IntTy)
7009 IvarOffsetValue = CGF.
Builder.CreateIntCast(
7010 IvarOffsetValue, ObjCTypes.LongTy,
true,
"ivar.conv");
7011 return IvarOffsetValue;
7014 static void appendSelectorForMessageRefTable(std::string &buffer,
7021 for (
unsigned i = 0, e = selector.
getNumArgs(); i != e; ++i) {
7059 args.insert(args.end(), formalArgs.begin(), formalArgs.end());
7061 MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);
7063 NullReturnState nullReturn;
7072 llvm::Constant *fn =
nullptr;
7073 std::string messageRefName(
"\01l_");
7076 fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
7077 messageRefName +=
"objc_msgSendSuper2_stret_fixup";
7079 nullReturn.init(CGF, arg0);
7080 fn = ObjCTypes.getMessageSendStretFixupFn();
7081 messageRefName +=
"objc_msgSend_stret_fixup";
7084 fn = ObjCTypes.getMessageSendFpretFixupFn();
7085 messageRefName +=
"objc_msgSend_fpret_fixup";
7088 fn = ObjCTypes.getMessageSendSuper2FixupFn();
7089 messageRefName +=
"objc_msgSendSuper2_fixup";
7091 fn = ObjCTypes.getMessageSendFixupFn();
7092 messageRefName +=
"objc_msgSend_fixup";
7095 assert(fn &&
"CGObjCNonFragileABIMac::EmitMessageSend");
7096 messageRefName +=
'_';
7100 appendSelectorForMessageRefTable(messageRefName, selector);
7102 llvm::GlobalVariable *messageRef
7103 = CGM.
getModule().getGlobalVariable(messageRefName);
7109 values.add(GetMethodVarName(selector));
7110 messageRef = values.finishAndCreateGlobal(messageRefName,
7113 llvm::GlobalValue::WeakAnyLinkage);
7115 messageRef->setSection(GetSectionName(
"__objc_msgrefs",
"coalesced"));
7118 bool requiresnullCheck =
false;
7120 for (
const auto *ParamDecl : method->
parameters()) {
7121 if (ParamDecl->hasAttr<NSConsumedAttr>()) {
7122 if (!nullReturn.NullBB)
7123 nullReturn.init(CGF, arg0);
7124 requiresnullCheck =
true;
7144 RValue result = CGF.
EmitCall(MSI.CallInfo, callee, returnSlot, args);
7145 return nullReturn.complete(CGF, returnSlot, result, resultType, formalArgs,
7146 requiresnullCheck ? method :
nullptr);
7159 return isVTableDispatchedSelector(Sel)
7160 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
7162 false, CallArgs, Method)
7163 : EmitMessageSend(CGF, Return, ResultType,
7164 EmitSelector(CGF, Sel),
7166 false, CallArgs, Method, Class, ObjCTypes);
7174 (metaclass ? getMetaclassSymbolPrefix() : getClassSymbolPrefix());
7180 && ID->
hasAttr<DLLImportAttr>());
7184 CGObjCNonFragileABIMac::GetClassGlobal(StringRef Name,
7186 bool Weak,
bool DLLImport) {
7187 llvm::GlobalValue::LinkageTypes L =
7188 Weak ? llvm::GlobalValue::ExternalWeakLinkage
7191 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name);
7192 if (!GV || GV->getType() != ObjCTypes.ClassnfABITy->getPointerTo()) {
7193 auto *NewGV =
new llvm::GlobalVariable(ObjCTypes.ClassnfABITy,
false, L,
7197 NewGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
7200 GV->replaceAllUsesWith(
7201 llvm::ConstantExpr::getBitCast(NewGV, GV->getType()));
7202 GV->eraseFromParent();
7205 CGM.
getModule().getGlobalList().push_back(GV);
7208 assert(GV->getLinkage() == L);
7217 llvm::GlobalVariable *&Entry = ClassReferences[II];
7220 llvm::Constant *ClassGV;
7224 ClassGV = GetClassGlobal((getClassSymbolPrefix() + II->
getName()).
str(),
7228 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassnfABIPtrTy,
7229 false, llvm::GlobalValue::PrivateLinkage,
7230 ClassGV,
"OBJC_CLASSLIST_REFERENCES_$_");
7232 Entry->setSection(GetSectionName(
"__objc_classrefs",
7233 "regular,no_dead_strip"));
7243 if (ID->
hasAttr<ObjCRuntimeVisibleAttr>())
7244 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
7249 llvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(
7252 return EmitClassRefFromId(CGF, II,
nullptr);
7259 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->
getIdentifier()];
7263 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassnfABIPtrTy,
7264 false, llvm::GlobalValue::PrivateLinkage,
7265 ClassGV,
"OBJC_CLASSLIST_SUP_REFS_$_");
7267 Entry->setSection(GetSectionName(
"__objc_superrefs",
7268 "regular,no_dead_strip"));
7281 llvm::GlobalVariable * &Entry = MetaClassReferences[ID->
getIdentifier()];
7285 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassnfABIPtrTy,
7286 false, llvm::GlobalValue::PrivateLinkage,
7287 MetaClassGV,
"OBJC_CLASSLIST_SUP_REFS_$_");
7290 Entry->setSection(GetSectionName(
"__objc_superrefs",
7291 "regular,no_dead_strip"));
7305 assert(!isa<llvm::GlobalVariable>(ClassGV) ||
7306 cast<llvm::GlobalVariable>(ClassGV)->hasExternalWeakLinkage());
7309 return EmitClassRef(CGF, ID);
7321 bool isCategoryImpl,
7323 bool IsClassMessage,
7344 Target = EmitSuperClassRef(CGF, Class);
7354 return (isVTableDispatchedSelector(Sel))
7355 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
7356 ObjCSuper.
getPointer(), ObjCTypes.SuperPtrCTy,
7357 true, CallArgs, Method)
7358 : EmitMessageSend(CGF, Return, ResultType,
7359 EmitSelector(CGF, Sel),
7360 ObjCSuper.
getPointer(), ObjCTypes.SuperPtrCTy,
7361 true, CallArgs, Method, Class, ObjCTypes);
7366 Address Addr = EmitSelectorAddr(CGF, Sel);
7369 LI->setMetadata(CGM.
getModule().getMDKindID(
"invariant.load"),
7370 llvm::MDNode::get(VMContext,
None));
7376 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
7380 llvm::Constant *Casted =
7381 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
7382 ObjCTypes.SelectorPtrTy);
7383 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.SelectorPtrTy,
7384 false, llvm::GlobalValue::PrivateLinkage,
7385 Casted,
"OBJC_SELECTOR_REFERENCES_");
7386 Entry->setExternallyInitialized(
true);
7387 Entry->setSection(GetSectionName(
"__objc_selrefs",
7388 "literal_pointers,no_dead_strip"));
7404 if (!isa<llvm::PointerType>(SrcTy)) {
7405 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(SrcTy);
7406 assert(Size <= 8 && "does not support size > 8
"); 7407 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 7408 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 7409 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 7411 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 7412 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 7413 llvm::Value *args[] = { src, dst.getPointer(), ivarOffset }; 7414 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args); 7420 void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
7421 CodeGen::CodeGenFunction &CGF,
7422 llvm::Value *src, Address dst) {
7423 llvm::Type * SrcTy = src->getType();
7424 if (!isa<llvm::PointerType>(SrcTy)) {
7425 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7426 assert(Size <= 8 && "does
not support size > 8
"); 7427 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 7428 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 7429 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 7431 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 7432 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 7433 llvm::Value *args[] = { src, dst.getPointer() }; 7434 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(), 7435 args, "weakassign
"); 7438 void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable( 7439 CodeGen::CodeGenFunction &CGF, 7442 llvm::Value *Size) { 7443 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy); 7444 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy); 7445 llvm::Value *args[] = { DestPtr.getPointer(), SrcPtr.getPointer(), Size }; 7446 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args); 7452 llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(
7453 CodeGen::CodeGenFunction &CGF,
7454 Address AddrWeakObj) {
7455 llvm::Type *DestTy = AddrWeakObj.getElementType();
7456 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy);
7457 llvm::Value *read_weak =
7458 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(),
7459 AddrWeakObj.getPointer(), "weakread
"); 7460 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy); 7467 void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
7468 llvm::Value *src, Address dst) {
7469 llvm::Type * SrcTy = src->getType();
7470 if (!isa<llvm::PointerType>(SrcTy)) {
7471 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7472 assert(Size <= 8 && "does
not support size > 8
"); 7473 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 7474 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 7475 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 7477 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 7478 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 7479 llvm::Value *args[] = { src, dst.getPointer() }; 7480 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(), 7481 args, "weakassign
"); 7487 void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
7488 llvm::Value *src, Address dst,
7490 llvm::Type * SrcTy = src->getType();
7491 if (!isa<llvm::PointerType>(SrcTy)) {
7492 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7493 assert(Size <= 8 && "does
not support size > 8
"); 7494 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 7495 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 7496 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 7498 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 7499 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 7500 llvm::Value *args[] = { src, dst.getPointer() }; 7502 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(), 7503 args, "globalassign
"); 7505 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(), 7506 args, "threadlocalassign
"); 7510 CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 7511 const ObjCAtSynchronizedStmt &S) { 7512 EmitAtSynchronizedStmt(CGF, S, 7513 cast<llvm::Function>(ObjCTypes.getSyncEnterFn()), 7514 cast<llvm::Function>(ObjCTypes.getSyncExitFn())); 7518 CGObjCNonFragileABIMac::GetEHType(QualType T) { 7519 // There's a particular fixed type info for 'id'. 7520 if (T->isObjCIdType() || T->isObjCQualifiedIdType()) { 7521 auto *IDEHType = CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id
"); 7524 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false, 7525 llvm::GlobalValue::ExternalLinkage, nullptr, 7527 if (CGM.getTriple().isOSBinFormatCOFF()) 7528 IDEHType->setDLLStorageClass(getStorage(CGM, "OBJC_EHTYPE_id
")); 7533 // All other types should be Objective-C interface pointer types. 7534 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>(); 7535 assert(PT && "Invalid
@catch type.
"); 7537 const ObjCInterfaceType *IT = PT->getInterfaceType(); 7538 assert(IT && "Invalid
@catch type.
"); 7540 return GetInterfaceEHType(IT->getDecl(), NotForDefinition); 7543 void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, 7544 const ObjCAtTryStmt &S) { 7545 EmitTryCatchStmt(CGF, S, 7546 cast<llvm::Function>(ObjCTypes.getObjCBeginCatchFn()), 7547 cast<llvm::Function>(ObjCTypes.getObjCEndCatchFn()), 7548 cast<llvm::Function>(ObjCTypes.getExceptionRethrowFn())); 7552 void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
7553 const ObjCAtThrowStmt &S,
7554 bool ClearInsertionPoint) {
7555 if (const Expr *ThrowExpr = S.getThrowExpr()) {
7556 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
7557 Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
7558 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception)
7559 .setDoesNotReturn();
7561 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionRethrowFn())
7562 .setDoesNotReturn();
7565 CGF.Builder.CreateUnreachable();
7566 if (ClearInsertionPoint)
7567 CGF.Builder.ClearInsertionPoint();
7571 CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
7572 ForDefinition_t IsForDefinition) {
7573 llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
7574 StringRef ClassName = ID->getObjCRuntimeNameAsString();
7576 // If we don't need a definition, return the entry if found or check
7577 // if we use an external reference.
7578 if (!IsForDefinition) {
7582 // If this type (or a super class) has the __objc_exception__
7583 // attribute, emit an external reference.
7584 if (hasObjCExceptionAttribute(CGM.getContext(), ID)) {
7585 std::string EHTypeName = ("OBJC_EHTYPE_$_
" + ClassName).str(); 7586 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, 7587 false, llvm::GlobalValue::ExternalLinkage, 7588 nullptr, EHTypeName); 7589 CGM.setGVProperties(Entry, ID); 7594 // Otherwise we need to either make a new entry or fill in the initializer. 7595 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition
"); 7597 std::string VTableName = "objc_ehtype_vtable
"; 7598 auto *VTableGV = CGM.getModule().getGlobalVariable(VTableName); 7601 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy, false, 7602 llvm::GlobalValue::ExternalLinkage, nullptr, 7604 if (CGM.getTriple().isOSBinFormatCOFF()) 7605 VTableGV->setDLLStorageClass(getStorage(CGM, VTableName)); 7608 llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2); 7609 ConstantInitBuilder builder(CGM); 7610 auto values = builder.beginStruct(ObjCTypes.EHTypeTy); 7612 llvm::ConstantExpr::getInBoundsGetElementPtr(VTableGV->getValueType(), 7613 VTableGV, VTableIdx)); 7614 values.add(GetClassName(ClassName)); 7615 values.add(GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition)); 7617 llvm::GlobalValue::LinkageTypes L = IsForDefinition 7618 ? llvm::GlobalValue::ExternalLinkage 7619 : llvm::GlobalValue::WeakAnyLinkage; 7621 values.finishAndSetAsInitializer(Entry); 7622 Entry->setAlignment(CGM.getPointerAlign().getQuantity()); 7624 Entry = values.finishAndCreateGlobal("OBJC_EHTYPE_$_
" + ClassName, 7625 CGM.getPointerAlign(), 7628 if (hasObjCExceptionAttribute(CGM.getContext(), ID)) 7629 CGM.setGVProperties(Entry, ID); 7631 assert(Entry->getLinkage() == L); 7633 if (!CGM.getTriple().isOSBinFormatCOFF()) 7634 if (ID->getVisibility() == HiddenVisibility) 7635 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility); 7637 if (IsForDefinition) 7638 if (CGM.getTriple().isOSBinFormatMachO()) 7639 Entry->setSection("__DATA,__objc_const
"); 7646 CodeGen::CGObjCRuntime * 7647 CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) { 7648 switch (CGM.getLangOpts().ObjCRuntime.getKind()) { 7649 case ObjCRuntime::FragileMacOSX: 7650 return new CGObjCMac(CGM); 7652 case ObjCRuntime::MacOSX: 7653 case ObjCRuntime::iOS: 7654 case ObjCRuntime::WatchOS: 7655 return new CGObjCNonFragileABIMac(CGM); 7657 case ObjCRuntime::GNUstep: 7658 case ObjCRuntime::GCC: 7659 case ObjCRuntime::ObjFW: 7660 llvm_unreachable("these runtimes are
not Mac runtimes
"); 7662 llvm_unreachable("bad runtime
"); const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
const llvm::DataLayout & getDataLayout() const
ReturnValueSlot - Contains the address where the return value of a function can be stored...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
Defines the clang::ASTContext interface.
QualType withConst() const
Retrieves a version of this type with const applied.
bool isClassMethod() const
const Capture & getCapture(const VarDecl *var) const
llvm::IntegerType * IntTy
int
External linkage, which indicates that the entity can be referred to from other translation units...
CharUnits BlockHeaderForcedGapOffset
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
Smart pointer class that efficiently represents Objective-C method names.
QualType getObjCIdType() const
Represents the Objective-CC id type.
Class implementation was compiled under ARC.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
bool isBlockPointerType() const
bool ReturnTypeUsesSRet(const CGFunctionInfo &FI)
Return true iff the given type uses 'sret' when used as a return type.
CodeGenTypes & getTypes()
ObjCInterfaceDecl * getClassInterface()
__SIZE_TYPE__ size_t
The unsigned integer type of the result of the sizeof operator.
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
llvm::LLVMContext & getLLVMContext()
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
The standard implementation of ConstantInitBuilder used in Clang.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
Stmt - This represents one statement.
const ObjCAtFinallyStmt * getFinallyStmt() const
Retrieve the @finally statement, if any.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Implements runtime-specific code generation functions.
bool isRecordType() const
const ASTRecordLayout & getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const
Get or compute information about the layout of the specified Objective-C implementation.
Decl - This represents one declaration (or definition), e.g.
CharUnits getPointerSize() const
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
all_protocol_iterator all_referenced_protocol_begin() const
void EmitAutoVarDecl(const VarDecl &D)
EmitAutoVarDecl - Emit an auto variable declaration.
Has a non-trivial constructor or destructor.
The base class of the type hierarchy.
Represents Objective-C's @throw statement.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
bool hasDestructors() const
Do any of the ivars of this class (not counting its base classes) require non-trivial destruction...
static bool hasObjCExceptionAttribute(ASTContext &Context, const ObjCInterfaceDecl *OID)
hasObjCExceptionAttribute - Return true if this class or any super class has the objc_exception attri...
static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT, bool pointee=false)
unsigned getCharWidth() const
param_const_iterator param_end() const
QualType getElementType() const
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::Instruction **callOrInvoke, SourceLocation Loc)
EmitCall - Generate a call of the given function, expecting the given result type, and using the given argument list which specifies both the LLVM arguments and the types they were derived from.
CanQualType getCanonicalParamType(QualType T) const
Return the canonical parameter type corresponding to the specific potentially non-canonical one...
Represents a variable declaration or definition.
Objects with "hidden" visibility are not seen by the dynamic linker.
const T * getAs() const
Member-template getAs<specific type>'.
llvm::GlobalVariable * finishAndCreateGlobal(As &&...args)
Given that this builder was created by beginning an array or struct directly on a ConstantInitBuilder...
ObjCMethodDecl - Represents an instance or class method declaration.
QualType getObjCClassType() const
Represents the Objective-C Class type.
llvm::Value * getPointer() const
Defines the Objective-C statement AST node classes.
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
protocol_range protocols() const
Represents a parameter to a function.
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have...
void add(RValue rvalue, QualType type)
A jump destination is an abstract label, branching to which may require a jump out through normal cle...
llvm::Value * EmitObjCThrowOperand(const Expr *expr)
Class implementation was compiled under ARC.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Represents a struct/union/class.
uint64_t getPointerWidth(unsigned AddrSpace) const
Return the width of pointers on this target, for the specified address space.
One of these records is kept for each identifier that is lexed.
Represents a class type in Objective C.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ParmVarDecl *const * param_const_iterator
field_range fields() const
Class has non-trivial destructors, but zero-initialization is okay.
bool isObjCIdType() const
Represents a member of a struct/union/class.
protocol_iterator protocol_begin() const
CharUnits getSizeAlign() const
llvm::CallInst * EmitRuntimeCall(llvm::Value *callee, const Twine &name="")
method_range methods() const
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for protocol's metadata.
ObjCMethodDecl * getSetterMethodDecl() const
std::string getNameAsString() const
Get the name of the class associated with this interface.
Class implementation was compiled under MRC and has MRC weak ivars.
prop_range properties() const
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
bool isObjCQualifiedClassType() const
Has the exception attribute.
static std::string getBlockLayoutInfoString(const SmallVectorImpl< CGObjCCommonMac::RUN_SKIP > &RunSkipBlockVars, bool HasCopyDisposeHelpers)
bool isUnarySelector() const
Objects with "default" visibility are seen by the dynamic linker and act like normal objects...
Represents Objective-C's @catch statement.
static bool isWeakLinkedClass(const ObjCInterfaceDecl *ID)
bool hasNonZeroConstructors() const
Do any of the ivars of this class (not counting its base classes) require construction other than zer...
bool isBitField() const
Determines whether this field is a bitfield.
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
ObjCContainerDecl - Represents a container for method declarations.
const Expr * getThrowExpr() const
CharUnits - This is an opaque type for sizes expressed in character units.
const BlockDecl * getBlockDecl() const
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
QualType getObjCClassRedefinitionType() const
Retrieve the type that Class has been defined to, which may be different from the built-in Class if C...
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
unsigned getBitWidthValue(const ASTContext &Ctx) const
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void addCompilerUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.compiler.used metadata.
void ForceCleanup(std::initializer_list< llvm::Value **> ValuesToReload={})
Force the emission of cleanups now, instead of waiting until this object is destroyed.
Represents an Objective-C protocol declaration.
llvm::Constant * CreateRuntimeVariable(llvm::Type *Ty, StringRef Name)
Create a new runtime global variable with the specified type and name.
CharUnits getPointerAlign() const
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
Represents an ObjC class declaration.
QualType getReturnType() const
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface...
Address NormalCleanupDest
i32s containing the indexes of the cleanup destinations.
all_protocol_iterator all_referenced_protocol_end() const
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
QualType getObjCProtoType() const
Retrieve the type of the Objective-C Protocol class.
This object can be modified without requiring retains or releases.
llvm::Constant * CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false)
Create a new runtime function with the specified type and name.
const ObjCAtCatchStmt * getCatchStmt(unsigned I) const
Retrieve a @catch statement.
unsigned getIndex() const
StringRef getString() const
static CharUnits One()
One - Construct a CharUnits quantity of one.
void addFrom(const CallArgList &other)
Add all the arguments from another CallArgList to this one.
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
ASTContext & getContext() const
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
CGBlockInfo - Information to generate a block literal.
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static llvm::StringMapEntry< llvm::GlobalVariable * > & GetConstantStringEntry(llvm::StringMap< llvm::GlobalVariable *> &Map, const StringLiteral *Literal, unsigned &StringLength)
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.
Pepresents a block literal declaration, which is like an unnamed FunctionDecl.
This represents one expression.
Defines the clang::LangOptions interface.
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
CharUnits getOffset() const
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
llvm::BasicBlock * getBlock() const
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
bool isObjCClassType() const
bool isObjCIdType() const
True if this is equivalent to the 'id' type, i.e.
Represents Objective-C's @synchronized statement.
ObjCInterfaceDecl * getSuperClass() const
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
llvm::LLVMContext & getLLVMContext()
bool needsCopyDisposeHelpers() const
bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI)
Return true iff the given type uses an argument slot when 'sret' is used as a return type...
llvm::IntegerType * Int32Ty
clang::ObjCRuntime ObjCRuntime
propimpl_range property_impls() const
bool isInstanceMethod() const
static llvm::Constant * getConstantGEP(llvm::LLVMContext &VMContext, llvm::GlobalVariable *C, unsigned idx0, unsigned idx1)
getConstantGEP() - Help routine to construct simple GEPs.
unsigned getNumArgs() const
const TargetInfo & getTarget() const
Selector getSelector() const
float __ovld __cnfn length(float p)
Return the length of vector p, i.e., sqrt(p.x2 + p.y 2 + ...)
const LangOptions & getLangOpts() const
ASTContext & getContext() const
(Obsolete) ARC-specific: this class has a .release_ivars method
CanQualType getCanonicalTypeUnqualified() const
The l-value was considered opaque, so the alignment was determined from a type.
RecordDecl * getDecl() const
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
There is no lifetime qualification on this type.
Address CreateBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
QualType getObjCIdRedefinitionType() const
Retrieve the type that id has been defined to, which may be different from the built-in id if id has ...
SelectorTable & Selectors
Assigning into this object requires the old value to be released and the new value to be retained...
bool ReturnTypeUsesFPRet(QualType ResultType)
Return true iff the given type uses 'fpret' when used as a return type.
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go...
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
void EmitARCRelease(llvm::Value *value, ARCPreciseLifetime_t precise)
Release the given object.
const Stmt * getCatchBody() const
ConstantAddress GetAddrOfConstantCFString(const StringLiteral *Literal)
Return a pointer to a constant CFString object for the given string.
llvm::StructType * StructureType
SmallVector< llvm::Value *, 8 > ObjCEHValueStack
ObjCEHValueStack - Stack of Objective-C exception values, used for rethrows.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const
Set visibility, dllimport/dllexport and dso_local.
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
const CGFunctionInfo & arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD)
Objective-C methods are C functions with some implicit parameters.
void EmitStmt(const Stmt *S, ArrayRef< const Attr *> Attrs=None)
EmitStmt - Emit the code for the statement.
static void PushProtocolProperties(llvm::SmallPtrSet< const IdentifierInfo *, 16 > &PropertySet, SmallVectorImpl< const ObjCPropertyDecl *> &Properties, const ObjCProtocolDecl *Proto, bool IsClassProperty)
static bool hasMRCWeakIvars(CodeGenModule &CGM, const ObjCImplementationDecl *ID)
For compatibility, we only want to set the "HasMRCWeakIvars" flag (and actually fill in a layout stri...
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
ObjCCategoryDecl - Represents a category declaration.
static bool hasWeakMember(QualType type)
bool isObjCObjectPointerType() const
Represents one property declaration in an Objective-C interface.
Class implementation was compiled under MRC and has MRC weak ivars.
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...
All available information about a concrete callee.
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)
The given basic block lies in the current EH scope, but may be a target of a potentially scope-crossi...
Assigning into this object requires a lifetime extension.
unsigned getPreferredTypeAlign(const Type *T) const
Return the "preferred" alignment of the specified type T for the current target, in bits...
bool ReturnTypeUsesFP2Ret(QualType ResultType)
Return true iff the given type uses 'fp2ret' when used as a return type.
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
ConstantAddress GetAddrOfConstantCString(const std::string &Str, const char *GlobalName=nullptr)
Returns a pointer to a character array containing the literal and a terminating '\0' character...
StringRef getName() const
Return the actual identifier string.
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type, returning the result.
void addUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.used metadata.
ObjCIvarDecl * getNextIvar()
bool isObjCGCWeak() const
true when Type is objc's weak.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
This class organizes the cross-function state that is used while generating LLVM code.
protocol_iterator protocol_end() const
StructBuilder beginStruct(llvm::StructType *ty=nullptr)
const ObjCInterfaceDecl * getClassInterface() const
static void addIfPresent(llvm::DenseSet< llvm::Value *> &S, Address V)
Dataflow Directional Tag Classes.
CharUnits getSize() const
getSize - Get the record size in characters.
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
ArrayRef< Capture > captures() const
Address CreateStructGEP(Address Addr, unsigned Index, CharUnits Offset, const llvm::Twine &Name="")
llvm::LoadInst * CreateAlignedLoad(llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::IntegerType * IntPtrTy
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
int printf(__constant const char *st,...)
const ObjCInterfaceDecl * getContainingInterface() const
Return the class interface that this ivar is logically contained in; this is either the interface whe...
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::Module & getModule() const
Apparently: is not a meta-class.
Address getNormalCleanupDestSlot()
Represents a pointer to an Objective C object.
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for class's metadata.
StructBuilder beginStruct(llvm::StructType *structTy=nullptr)
Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV)
Can create any sort of selector.
llvm::Type * getElementType() const
Return the type of the values stored in this address.
const llvm::APInt & getSize() const
This class organizes the cross-module state that is used while lowering AST types to LLVM types...
protocol_iterator protocol_begin() const
llvm::PointerType * Int8PtrTy
bool isObjCQualifiedIdType() const
param_const_iterator param_begin() const
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for class's metadata.
Represents Objective-C's @finally statement.
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
llvm::IntegerType * PtrDiffTy
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
Reading or writing from this object requires a barrier call.
Selector GetUnarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing an unary selector.
llvm::Type * ConvertType(QualType T)
A specialization of Address that requires the address to be an LLVM Constant.
ObjCIvarDecl - Represents an ObjC instance variable.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
A helper class of ConstantInitBuilder, used for building constant struct initializers.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
CharUnits BlockHeaderForcedGapSize
Has a non-trivial constructor or destructor.
Represents Objective-C's @try ... @catch ... @finally statement.
protocol_iterator protocol_end() const
unsigned getNumCatchStmts() const
Retrieve the number of @catch statements in this try-catch-finally block.
StringLiteral - This represents a string literal expression, e.g.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
StringRef getName() const
getName - Get the name of identifier for the class interface associated with this implementation as a...
static RValue get(llvm::Value *V)
Visibility getVisibility() const
Determines the visibility of this entity.
const internal::VariadicDynCastAllOfMatcher< Decl, BlockDecl > blockDecl
Matches block declarations.
const VarDecl * getCatchParamDecl() const
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
std::string ObjCConstantStringClass
LValue - This represents an lvalue references.
Information for lazily generating a cleanup.
ObjCMethodDecl * getGetterMethodDecl() const
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
AccessControl getAccessControl() const
ObjCProtocolList::iterator protocol_iterator
CallArgList - Type for representing both the value and type of arguments in a call.
const LangOptions & getLangOpts() const
void PopCleanupBlock(bool FallThroughIsBranchThrough=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration...
Represents the canonical version of C arrays with a specified constant size.
A helper class of ConstantInitBuilder, used for building constant array initializers.
Abstract information about a function or function prototype.
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
ArrayRef< ParmVarDecl * > parameters() const
ObjCCompatibleAliasDecl - Represents alias of a class.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PL, ArrayRef< Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
ObjCCategoryDecl * FindCategoryDeclaration(IdentifierInfo *CategoryId) const
FindCategoryDeclaration - Finds category declaration in the list of categories for this class and ret...
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
const llvm::Triple & getTriple() const