28 #include "llvm/ADT/DenseSet.h"
29 #include "llvm/ADT/SetVector.h"
30 #include "llvm/ADT/SmallPtrSet.h"
31 #include "llvm/ADT/SmallString.h"
32 #include "llvm/IR/CallSite.h"
33 #include "llvm/IR/DataLayout.h"
34 #include "llvm/IR/InlineAsm.h"
35 #include "llvm/IR/IntrinsicInst.h"
36 #include "llvm/IR/LLVMContext.h"
37 #include "llvm/IR/Module.h"
38 #include "llvm/Support/raw_ostream.h"
41 using namespace clang;
42 using namespace CodeGen;
49 class ObjCCommonTypesHelper {
51 llvm::LLVMContext &VMContext;
61 llvm::Constant *getMessageSendFn()
const {
64 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
66 CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
69 llvm::AttributeSet::get(CGM.getLLVMContext(),
70 llvm::AttributeSet::FunctionIndex,
71 llvm::Attribute::NonLazyBind));
79 llvm::Constant *getMessageSendStretFn()
const {
80 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
81 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy,
83 "objc_msgSend_stret");
92 llvm::Constant *getMessageSendFpretFn()
const {
93 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
94 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.DoubleTy,
96 "objc_msgSend_fpret");
105 llvm::Constant *getMessageSendFp2retFn()
const {
106 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
107 llvm::Type *longDoubleType = llvm::Type::getX86_FP80Ty(VMContext);
109 llvm::StructType::get(longDoubleType, longDoubleType,
nullptr);
111 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(resultType,
113 "objc_msgSend_fp2ret");
121 llvm::Constant *getMessageSendSuperFn()
const {
122 llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
123 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
125 "objc_msgSendSuper");
132 llvm::Constant *getMessageSendSuperFn2()
const {
133 llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
134 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
136 "objc_msgSendSuper2");
143 llvm::Constant *getMessageSendSuperStretFn()
const {
144 llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
145 return CGM.CreateRuntimeFunction(
146 llvm::FunctionType::get(CGM.VoidTy, params,
true),
147 "objc_msgSendSuper_stret");
154 llvm::Constant *getMessageSendSuperStretFn2()
const {
155 llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
156 return CGM.CreateRuntimeFunction(
157 llvm::FunctionType::get(CGM.VoidTy, params,
true),
158 "objc_msgSendSuper2_stret");
161 llvm::Constant *getMessageSendSuperFpretFn()
const {
163 return getMessageSendSuperFn();
166 llvm::Constant *getMessageSendSuperFpretFn2()
const {
168 return getMessageSendSuperFn2();
175 llvm::Type *ShortTy, *IntTy, *LongTy, *LongLongTy;
195 if (!ExternalProtocolPtrTy) {
201 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
204 return ExternalProtocolPtrTy;
213 llvm::StructType *SuperTy;
219 llvm::StructType *PropertyTy;
223 llvm::StructType *PropertyListTy;
228 llvm::StructType *MethodTy;
235 llvm::Constant *getGetPropertyFn() {
244 llvm::FunctionType *FTy =
247 return CGM.CreateRuntimeFunction(FTy,
"objc_getProperty");
250 llvm::Constant *getSetPropertyFn() {
263 llvm::FunctionType *FTy =
266 return CGM.CreateRuntimeFunction(FTy,
"objc_setProperty");
269 llvm::Constant *getOptimizedSetPropertyFn(
bool atomic,
bool copy) {
284 Params.push_back(IdType);
285 Params.push_back(SelType);
286 Params.push_back(IdType);
288 llvm::FunctionType *FTy =
293 name =
"objc_setProperty_atomic_copy";
294 else if (atomic && !copy)
295 name =
"objc_setProperty_atomic";
296 else if (!atomic && copy)
297 name =
"objc_setProperty_nonatomic_copy";
299 name =
"objc_setProperty_nonatomic";
301 return CGM.CreateRuntimeFunction(FTy, name);
304 llvm::Constant *getCopyStructFn() {
311 Params.push_back(Ctx.
LongTy);
312 Params.push_back(Ctx.
BoolTy);
313 Params.push_back(Ctx.
BoolTy);
314 llvm::FunctionType *FTy =
317 return CGM.CreateRuntimeFunction(FTy,
"objc_copyStruct");
324 llvm::Constant *getCppAtomicObjectFunction() {
332 llvm::FunctionType *FTy =
335 return CGM.CreateRuntimeFunction(FTy,
"objc_copyCppObjectAtomic");
338 llvm::Constant *getEnumerationMutationFn() {
344 llvm::FunctionType *FTy =
347 return CGM.CreateRuntimeFunction(FTy,
"objc_enumerationMutation");
350 llvm::Constant *getLookUpClassFn() {
357 llvm::FunctionType *FTy =
361 return CGM.CreateRuntimeFunction(FTy,
"objc_lookUpClass");
365 llvm::Constant *getGcReadWeakFn() {
367 llvm::Type *args[] = { ObjectPtrTy->getPointerTo() };
368 llvm::FunctionType *FTy =
369 llvm::FunctionType::get(ObjectPtrTy, args,
false);
370 return CGM.CreateRuntimeFunction(FTy,
"objc_read_weak");
374 llvm::Constant *getGcAssignWeakFn() {
376 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
377 llvm::FunctionType *FTy =
378 llvm::FunctionType::get(ObjectPtrTy, args,
false);
379 return CGM.CreateRuntimeFunction(FTy,
"objc_assign_weak");
383 llvm::Constant *getGcAssignGlobalFn() {
385 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
386 llvm::FunctionType *FTy =
387 llvm::FunctionType::get(ObjectPtrTy, args,
false);
388 return CGM.CreateRuntimeFunction(FTy,
"objc_assign_global");
392 llvm::Constant *getGcAssignThreadLocalFn() {
394 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
395 llvm::FunctionType *FTy =
396 llvm::FunctionType::get(ObjectPtrTy, args,
false);
397 return CGM.CreateRuntimeFunction(FTy,
"objc_assign_threadlocal");
401 llvm::Constant *getGcAssignIvarFn() {
403 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo(),
405 llvm::FunctionType *FTy =
406 llvm::FunctionType::get(ObjectPtrTy, args,
false);
407 return CGM.CreateRuntimeFunction(FTy,
"objc_assign_ivar");
411 llvm::Constant *GcMemmoveCollectableFn() {
413 llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, LongTy };
414 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, args,
false);
415 return CGM.CreateRuntimeFunction(FTy,
"objc_memmove_collectable");
419 llvm::Constant *getGcAssignStrongCastFn() {
421 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
422 llvm::FunctionType *FTy =
423 llvm::FunctionType::get(ObjectPtrTy, args,
false);
424 return CGM.CreateRuntimeFunction(FTy,
"objc_assign_strongCast");
428 llvm::Constant *getExceptionThrowFn() {
431 llvm::FunctionType *FTy =
432 llvm::FunctionType::get(CGM.VoidTy, args,
false);
433 return CGM.CreateRuntimeFunction(FTy,
"objc_exception_throw");
437 llvm::Constant *getExceptionRethrowFn() {
439 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy,
false);
440 return CGM.CreateRuntimeFunction(FTy,
"objc_exception_rethrow");
444 llvm::Constant *getSyncEnterFn() {
447 llvm::FunctionType *FTy =
448 llvm::FunctionType::get(CGM.IntTy, args,
false);
449 return CGM.CreateRuntimeFunction(FTy,
"objc_sync_enter");
453 llvm::Constant *getSyncExitFn() {
456 llvm::FunctionType *FTy =
457 llvm::FunctionType::get(CGM.IntTy, args,
false);
458 return CGM.CreateRuntimeFunction(FTy,
"objc_sync_exit");
461 llvm::Constant *getSendFn(
bool IsSuper)
const {
462 return IsSuper ? getMessageSendSuperFn() : getMessageSendFn();
465 llvm::Constant *getSendFn2(
bool IsSuper)
const {
466 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();
469 llvm::Constant *getSendStretFn(
bool IsSuper)
const {
470 return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();
473 llvm::Constant *getSendStretFn2(
bool IsSuper)
const {
474 return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();
477 llvm::Constant *getSendFpretFn(
bool IsSuper)
const {
478 return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();
481 llvm::Constant *getSendFpretFn2(
bool IsSuper)
const {
482 return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();
485 llvm::Constant *getSendFp2retFn(
bool IsSuper)
const {
486 return IsSuper ? getMessageSendSuperFn() : getMessageSendFp2retFn();
489 llvm::Constant *getSendFp2RetFn2(
bool IsSuper)
const {
490 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFp2retFn();
498 class ObjCTypesHelper :
public ObjCCommonTypesHelper {
501 llvm::StructType *SymtabTy;
505 llvm::StructType *ModuleTy;
508 llvm::StructType *ProtocolTy;
513 llvm::StructType *ProtocolExtensionTy;
519 llvm::StructType *MethodDescriptionTy;
522 llvm::StructType *MethodDescriptionListTy;
527 llvm::StructType *ProtocolListTy;
531 llvm::StructType *CategoryTy;
533 llvm::StructType *ClassTy;
537 llvm::StructType *ClassExtensionTy;
541 llvm::StructType *IvarTy;
555 llvm::Constant *getExceptionTryEnterFn() {
556 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
557 return CGM.CreateRuntimeFunction(
558 llvm::FunctionType::get(CGM.VoidTy, params,
false),
559 "objc_exception_try_enter");
563 llvm::Constant *getExceptionTryExitFn() {
564 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
565 return CGM.CreateRuntimeFunction(
566 llvm::FunctionType::get(CGM.VoidTy, params,
false),
567 "objc_exception_try_exit");
571 llvm::Constant *getExceptionExtractFn() {
572 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
573 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
575 "objc_exception_extract");
579 llvm::Constant *getExceptionMatchFn() {
580 llvm::Type *params[] = { ClassPtrTy, ObjectPtrTy };
581 return CGM.CreateRuntimeFunction(
582 llvm::FunctionType::get(CGM.Int32Ty, params,
false),
583 "objc_exception_match");
587 llvm::Constant *getSetJmpFn() {
589 llvm::Type *params[] = { CGM.Int32Ty->getPointerTo() };
591 CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.Int32Ty,
594 llvm::AttributeSet::get(CGM.getLLVMContext(),
595 llvm::AttributeSet::FunctionIndex,
596 llvm::Attribute::NonLazyBind));
605 class ObjCNonFragileABITypesHelper :
public ObjCCommonTypesHelper {
608 llvm::StructType *MethodListnfABITy;
614 llvm::StructType *ProtocolnfABITy;
620 llvm::StructType *ProtocolListnfABITy;
626 llvm::StructType *ClassnfABITy;
632 llvm::StructType *IvarnfABITy;
635 llvm::StructType *IvarListnfABITy;
641 llvm::StructType *ClassRonfABITy;
647 llvm::StructType *CategorynfABITy;
656 llvm::StructType *MessageRefTy;
670 llvm::StructType *SuperMessageRefTy;
675 llvm::Constant *getMessageSendFixupFn() {
677 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
678 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
680 "objc_msgSend_fixup");
683 llvm::Constant *getMessageSendFpretFixupFn() {
685 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
686 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
688 "objc_msgSend_fpret_fixup");
691 llvm::Constant *getMessageSendStretFixupFn() {
693 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
694 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
696 "objc_msgSend_stret_fixup");
699 llvm::Constant *getMessageSendSuper2FixupFn() {
702 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
703 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
705 "objc_msgSendSuper2_fixup");
708 llvm::Constant *getMessageSendSuper2StretFixupFn() {
711 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
712 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
714 "objc_msgSendSuper2_stret_fixup");
717 llvm::Constant *getObjCEndCatchFn() {
718 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy,
false),
723 llvm::Constant *getObjCBeginCatchFn() {
725 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(Int8PtrTy,
730 llvm::StructType *EHTypeTy;
742 SKIP_SCAN(
unsigned _skip = 0,
unsigned _scan = 0)
743 : skip(_skip), scan(_scan) {}
750 enum BLOCK_LAYOUT_OPCODE {
757 BLOCK_LAYOUT_OPERATOR = 0,
763 BLOCK_LAYOUT_NON_OBJECT_BYTES = 1,
768 BLOCK_LAYOUT_NON_OBJECT_WORDS = 2,
772 BLOCK_LAYOUT_STRONG = 3,
775 BLOCK_LAYOUT_BYREF = 4,
779 BLOCK_LAYOUT_WEAK = 5,
783 BLOCK_LAYOUT_UNRETAINED = 6
800 enum BLOCK_LAYOUT_OPCODE opcode;
803 RUN_SKIP(
enum BLOCK_LAYOUT_OPCODE Opcode = BLOCK_LAYOUT_OPERATOR,
806 : opcode(Opcode), block_var_bytepos(BytePos), block_var_size(Size) {}
809 bool operator<(
const RUN_SKIP &b)
const {
810 return block_var_bytepos < b.block_var_bytepos;
815 llvm::LLVMContext &VMContext;
824 llvm::SetVector<IdentifierInfo*> LazySymbols;
830 llvm::SetVector<IdentifierInfo*> DefinedSymbols;
833 llvm::StringMap<llvm::GlobalVariable*> ClassNames;
836 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
843 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
847 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
850 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
853 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
856 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
861 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
890 llvm::Constant *GetMethodVarName(
Selector Sel);
898 bool Extended =
false);
899 llvm::Constant *GetMethodVarType(
const FieldDecl *D);
907 const Decl *Container);
912 llvm::Constant *GetClassName(StringRef RuntimeName);
926 bool forStrongLayout,
932 return BuildIvarLayout(OI, beginOffset, endOffset,
true,
false);
939 return BuildIvarLayout(OI, beginOffset, endOffset,
false, hasMRCWeakIvars);
944 void UpdateRunSkipBlockVars(
bool IsByref,
949 void BuildRCBlockVarRecordLayout(
const RecordType *RT,
951 bool ByrefLayout=
false);
953 void BuildRCRecordLayout(
const llvm::StructLayout *RecLayout,
961 llvm::Constant *getBitmapBlockLayout(
bool ComputeByrefLayout);
966 const ObjCCommonTypesHelper &ObjCTypes);
970 llvm::Constant *EmitPropertyList(Twine
Name,
971 const Decl *Container,
973 const ObjCCommonTypesHelper &ObjCTypes,
974 bool IsClassProperty);
978 llvm::Constant *EmitProtocolMethodTypes(Twine
Name,
980 const ObjCCommonTypesHelper &ObjCTypes);
983 void PushProtocolProperties(
984 llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet,
986 const Decl *Container,
988 const ObjCCommonTypesHelper &ObjCTypes,
989 bool IsClassProperty);
1000 ObjCCommonTypesHelper &ObjCTypes);
1017 llvm::GlobalVariable *CreateMetadataVar(Twine
Name, llvm::Constant *Init,
1032 const ObjCCommonTypesHelper &ObjCTypes);
1036 void EmitImageInfo();
1042 bool isNonFragileABI()
const {
1043 return ObjCABI == 2;
1062 virtual llvm::Constant *GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD)=0;
1072 class CGObjCMac :
public CGObjCCommonMac {
1074 ObjCTypesHelper ObjCTypes;
1078 void EmitModuleInfo();
1082 llvm::Constant *EmitModuleSymbols();
1086 void FinishModule();
1094 bool isClassProperty);
1125 llvm::Constant *Protocols,
1130 llvm::Constant *GetMethodDescriptionConstant(
const ObjCMethodDecl *MD);
1134 llvm::Constant *EmitMethodList(Twine
Name, StringRef Section,
1148 llvm::Constant *EmitMethodDescList(Twine
Name, StringRef Section,
1174 llvm::Constant *EmitProtocolList(Twine
Name,
1186 llvm::Function *ModuleInitFunction()
override;
1215 llvm::Constant *GetEHType(
QualType T)
override;
1226 llvm::Constant *GetPropertyGetFunction()
override;
1227 llvm::Constant *GetPropertySetFunction()
override;
1228 llvm::Constant *GetOptimizedPropertySetFunction(
bool atomic,
1229 bool copy)
override;
1230 llvm::Constant *GetGetStructFunction()
override;
1231 llvm::Constant *GetSetStructFunction()
override;
1232 llvm::Constant *GetCppAtomicObjectGetFunction()
override;
1233 llvm::Constant *GetCppAtomicObjectSetFunction()
override;
1234 llvm::Constant *EnumerationMutationFunction()
override;
1242 bool ClearInsertionPoint=
true)
override;
1244 Address AddrWeakObj)
override;
1249 bool threadlocal =
false)
override;
1261 unsigned CVRQualifiers)
override;
1268 llvm::GlobalVariable *GetClassGlobal(StringRef
Name,
1269 bool Weak =
false)
override {
1270 llvm_unreachable(
"CGObjCMac::GetClassGlobal");
1274 class CGObjCNonFragileABIMac :
public CGObjCCommonMac {
1276 ObjCNonFragileABITypesHelper ObjCTypes;
1277 llvm::GlobalVariable* ObjCEmptyCacheVar;
1278 llvm::GlobalVariable* ObjCEmptyVtableVar;
1281 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences;
1284 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences;
1287 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences;
1294 std::vector<llvm::GlobalValue*> DefinedMetaClasses;
1298 bool isVTableDispatchedSelector(
Selector Sel);
1302 void FinishNonFragileABIModule();
1307 StringRef SymbolName, StringRef SectionName);
1309 llvm::GlobalVariable * BuildClassRoTInitializer(
unsigned flags,
1310 unsigned InstanceStart,
1311 unsigned InstanceSize,
1313 llvm::GlobalVariable * BuildClassMetaData(
const std::string &ClassName,
1314 llvm::Constant *IsAGV,
1315 llvm::Constant *SuperClassGV,
1316 llvm::Constant *ClassRoGV,
1322 llvm::Constant *GetMethodDescriptionConstant(
const ObjCMethodDecl *MD);
1326 llvm::Constant *EmitMethodList(Twine
Name, StringRef Section,
1337 unsigned long int offset);
1352 llvm::Constant *EmitProtocolList(Twine
Name,
1368 llvm::GlobalVariable *GetClassGlobal(StringRef
Name,
1369 bool Weak =
false)
override;
1395 llvm::GlobalVariable * ObjCIvarOffsetVariable(
1407 bool ForDefinition);
1409 StringRef getMetaclassSymbolPrefix()
const {
return "OBJC_METACLASS_$_"; }
1411 StringRef getClassSymbolPrefix()
const {
return "OBJC_CLASS_$_"; }
1414 uint32_t &InstanceStart,
1415 uint32_t &InstanceSize);
1420 return CGM.getContext().Selectors.getSelector(0, &II);
1425 return CGM.getContext().Selectors.getSelector(1, &II);
1430 bool ImplementationIsNonLazy(
const ObjCImplDecl *OD)
const;
1445 dyn_cast_or_null<ObjCMethodDecl>(CGF.
CurFuncDecl))
1446 if (MD->isInstanceMethod())
1455 llvm::Function *ModuleInitFunction()
override;
1477 {
return EmitSelector(CGF, Sel); }
1479 {
return EmitSelectorAddr(CGF, Sel); }
1485 {
return EmitSelector(CGF, Method->
getSelector()); }
1496 llvm::Constant *GetEHType(
QualType T)
override;
1498 llvm::Constant *GetPropertyGetFunction()
override {
1499 return ObjCTypes.getGetPropertyFn();
1501 llvm::Constant *GetPropertySetFunction()
override {
1502 return ObjCTypes.getSetPropertyFn();
1505 llvm::Constant *GetOptimizedPropertySetFunction(
bool atomic,
1506 bool copy)
override {
1507 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
1510 llvm::Constant *GetSetStructFunction()
override {
1511 return ObjCTypes.getCopyStructFn();
1514 llvm::Constant *GetGetStructFunction()
override {
1515 return ObjCTypes.getCopyStructFn();
1518 llvm::Constant *GetCppAtomicObjectSetFunction()
override {
1519 return ObjCTypes.getCppAtomicObjectFunction();
1522 llvm::Constant *GetCppAtomicObjectGetFunction()
override {
1523 return ObjCTypes.getCppAtomicObjectFunction();
1526 llvm::Constant *EnumerationMutationFunction()
override {
1527 return ObjCTypes.getEnumerationMutationFn();
1535 bool ClearInsertionPoint=
true)
override;
1537 Address AddrWeakObj)
override;
1542 bool threadlocal =
false)
override;
1553 unsigned CVRQualifiers)
override;
1561 struct NullReturnState {
1562 llvm::BasicBlock *NullBB;
1563 NullReturnState() : NullBB(nullptr) {}
1576 CGF.
Builder.CreateCondBr(isNull, NullBB, callBB);
1588 if (!NullBB)
return result;
1592 llvm::BasicBlock *contBB =
nullptr;
1595 llvm::BasicBlock *callBB = CGF.
Builder.GetInsertBlock();
1606 CallArgList::const_iterator
I = CallArgs.begin();
1610 if (ParamDecl->hasAttr<NSConsumedAttr>()) {
1613 "NullReturnState::complete - arg not on object");
1620 assert(CGF.
Builder.GetInsertBlock() == NullBB);
1639 llvm::PHINode *phi = CGF.
Builder.CreatePHI(null->getType(), 2);
1641 phi->addIncoming(null, NullBB);
1650 assert(result.
isAggregate() &&
"null init of non-aggregate result?");
1661 llvm::Type *scalarTy = callResult.first->getType();
1662 llvm::Constant *scalarZero = llvm::Constant::getNullValue(scalarTy);
1665 llvm::PHINode *real = CGF.
Builder.CreatePHI(scalarTy, 2);
1666 real->addIncoming(callResult.first, callBB);
1667 real->addIncoming(scalarZero, NullBB);
1668 llvm::PHINode *imag = CGF.
Builder.CreatePHI(scalarTy, 2);
1669 imag->addIncoming(callResult.second, callBB);
1670 imag->addIncoming(scalarZero, NullBB);
1681 llvm::GlobalVariable *C,
unsigned idx0,
1684 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),
1685 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)
1687 return llvm::ConstantExpr::getGetElementPtr(C->getValueType(), C, Idxs);
1694 if (OID->hasAttr<ObjCExceptionAttr>())
1713 return EmitClassRef(CGF, ID);
1718 return EmitSelector(CGF, Sel);
1721 return EmitSelectorAddr(CGF, Sel);
1728 llvm::Constant *CGObjCMac::GetEHType(
QualType T) {
1731 return CGM.GetAddrOfRTTIDescriptor(
1732 CGM.getContext().getObjCIdRedefinitionType(),
true);
1736 return CGM.GetAddrOfRTTIDescriptor(
1737 CGM.getContext().getObjCClassRedefinitionType(),
true);
1740 return CGM.GetAddrOfRTTIDescriptor(T,
true);
1742 llvm_unreachable(
"asking for catch type for ObjC type in fragile runtime");
1766 return (CGM.getLangOpts().NoConstantCFStrings == 0 ?
1767 CGM.GetAddrOfConstantCFString(SL) :
1768 CGM.GetAddrOfConstantString(SL));
1784 bool isCategoryImpl,
1786 bool IsClassMessage,
1802 if (IsClassMessage) {
1803 if (isCategoryImpl) {
1814 llvm::Constant *MetaClassPtr = EmitMetaClassRef(Class);
1821 }
else if (isCategoryImpl)
1830 llvm::Type *ClassTy =
1835 return EmitMessageSend(CGF, Return, ResultType,
1836 EmitSelector(CGF, Sel),
1837 ObjCSuper.
getPointer(), ObjCTypes.SuperPtrCTy,
1838 true, CallArgs, Method, Class, ObjCTypes);
1850 return EmitMessageSend(CGF, Return, ResultType,
1851 EmitSelector(CGF, Sel),
1853 false, CallArgs, Method, Class, ObjCTypes);
1858 if (ID->isWeakImported())
1876 const ObjCCommonTypesHelper &ObjCTypes) {
1880 ActualArgs.
add(RValue::get(Arg0), Arg0Ty);
1885 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
1888 assert(CGM.getContext().getCanonicalType(Method->
getReturnType()) ==
1889 CGM.getContext().getCanonicalType(ResultType) &&
1890 "Result type mismatch!");
1892 bool ReceiverCanBeNull =
true;
1897 ReceiverCanBeNull =
false;
1901 }
else if (ClassReceiver && Method && Method->
isClassMethod()) {
1906 }
else if (
auto CurMethod =
1907 dyn_cast_or_null<ObjCMethodDecl>(CGF.
CurCodeDecl)) {
1908 auto Self = CurMethod->getSelfDecl();
1909 if (Self->getType().isConstQualified()) {
1910 if (
auto LI = dyn_cast<llvm::LoadInst>(Arg0->stripPointerCasts())) {
1912 if (SelfAddr == LI->getPointerOperand()) {
1913 ReceiverCanBeNull =
false;
1919 NullReturnState nullReturn;
1921 llvm::Constant *Fn =
nullptr;
1922 if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
1923 if (ReceiverCanBeNull) nullReturn.init(CGF, Arg0);
1924 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
1925 : ObjCTypes.getSendStretFn(IsSuper);
1926 }
else if (CGM.ReturnTypeUsesFPRet(ResultType)) {
1927 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
1928 : ObjCTypes.getSendFpretFn(IsSuper);
1929 }
else if (CGM.ReturnTypeUsesFP2Ret(ResultType)) {
1930 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)
1931 : ObjCTypes.getSendFp2retFn(IsSuper);
1935 if (ReceiverCanBeNull && CGM.ReturnTypeUsesSRet(MSI.CallInfo))
1936 nullReturn.init(CGF, Arg0);
1937 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
1938 : ObjCTypes.getSendFn(IsSuper);
1942 bool RequiresNullCheck =
false;
1943 if (ReceiverCanBeNull && CGM.getLangOpts().ObjCAutoRefCount && Method) {
1944 for (
const auto *ParamDecl : Method->
parameters()) {
1945 if (ParamDecl->hasAttr<NSConsumedAttr>()) {
1946 if (!nullReturn.NullBB)
1947 nullReturn.init(CGF, Arg0);
1948 RequiresNullCheck =
true;
1954 llvm::Instruction *CallSite;
1955 Fn = llvm::ConstantExpr::getBitCast(Fn, MSI.MessengerType);
1956 RValue rvalue = CGF.
EmitCall(MSI.CallInfo, Fn, Return, ActualArgs,
1961 if (Method && Method->hasAttr<NoReturnAttr>() && !ReceiverCanBeNull) {
1962 llvm::CallSite(CallSite).setDoesNotReturn();
1965 return nullReturn.complete(CGF, rvalue, ResultType, CallArgs,
1966 RequiresNullCheck ? Method :
nullptr);
1970 bool pointee =
false) {
1975 return Qualifiers::Strong;
1978 return Qualifiers::Weak;
1982 if (pointee)
return Qualifiers::GCNone;
1983 switch (ownership) {
1984 case Qualifiers::OCL_Weak:
return Qualifiers::Weak;
1985 case Qualifiers::OCL_Strong:
return Qualifiers::Strong;
1986 case Qualifiers::OCL_ExplicitNone:
return Qualifiers::GCNone;
1987 case Qualifiers::OCL_Autoreleasing: llvm_unreachable(
"autoreleasing ivar?");
1988 case Qualifiers::OCL_None: llvm_unreachable(
"known nonzero");
1990 llvm_unreachable(
"bad objc ownership");
1995 return Qualifiers::Strong;
1998 if (Ctx.
getLangOpts().getGC() != LangOptions::NonGC) {
2003 return Qualifiers::GCNone;
2009 uint64_t SizeInWords;
2010 IvarInfo(
CharUnits offset, uint64_t sizeInWords)
2011 :
Offset(offset), SizeInWords(sizeInWords) {}
2014 bool operator<(
const IvarInfo &other)
const {
2015 return Offset < other.Offset;
2020 class IvarLayoutBuilder {
2031 bool ForStrongLayout;
2034 bool IsDisordered =
false;
2040 CharUnits instanceEnd,
bool forStrongLayout)
2041 : CGM(CGM), InstanceBegin(instanceBegin), InstanceEnd(instanceEnd),
2042 ForStrongLayout(forStrongLayout) {
2047 template <
class Iterator,
class GetOffsetFn>
2048 void visitAggregate(Iterator
begin, Iterator
end,
2050 const GetOffsetFn &getOffset);
2058 bool hasBitmapData()
const {
return !IvarsInfo.empty(); }
2060 llvm::Constant *buildBitmap(CGObjCCommonMac &CGObjC,
2064 const unsigned char *s = buffer.data();
2065 for (
unsigned i = 0, e = buffer.size(); i < e; i++)
2067 printf(
"0x0%x%s", s[i], s[i] != 0 ?
", " :
"");
2069 printf(
"0x%x%s", s[i], s[i] != 0 ?
", " :
"");
2075 llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(
CodeGenModule &CGM,
2078 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2079 if (CGM.
getLangOpts().getGC() == LangOptions::NonGC)
2082 IvarLayoutBuilder builder(CGM, CharUnits::Zero(), blockInfo.
BlockSize,
2085 builder.visitBlock(blockInfo);
2087 if (!builder.hasBitmapData())
2091 llvm::Constant *
C = builder.buildBitmap(*
this, buffer);
2092 if (CGM.
getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
2093 printf(
"\n block variable layout for block: ");
2094 builder.dump(buffer);
2100 void IvarLayoutBuilder::visitBlock(
const CGBlockInfo &blockInfo) {
2103 IvarsInfo.push_back(IvarInfo(CharUnits::Zero(), 1));
2113 for (
const auto &CI : blockDecl->
captures()) {
2114 const VarDecl *variable = CI.getVariable();
2126 if (fieldOffset < lastFieldOffset)
2127 IsDisordered =
true;
2128 lastFieldOffset = fieldOffset;
2132 IvarsInfo.push_back(IvarInfo(fieldOffset, 1));
2136 assert(!type->
isArrayType() &&
"array variable should not be caught");
2138 visitRecord(record, fieldOffset);
2144 if (GCAttr == Qualifiers::Strong) {
2147 IvarsInfo.push_back(IvarInfo(fieldOffset, 1));
2163 return Qualifiers::OCL_None;
2167 return ByrefLayout ? Qualifiers::OCL_ExplicitNone : Qualifiers::OCL_Strong;
2169 return Qualifiers::OCL_None;
2172 void CGObjCCommonMac::UpdateRunSkipBlockVars(
bool IsByref,
2178 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset,
2180 else if (LifeTime == Qualifiers::OCL_Strong)
2181 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset,
2183 else if (LifeTime == Qualifiers::OCL_Weak)
2184 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset,
2186 else if (LifeTime == Qualifiers::OCL_ExplicitNone)
2187 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset,
2190 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES,
2195 void CGObjCCommonMac::BuildRCRecordLayout(
const llvm::StructLayout *RecLayout,
2200 bool IsUnion = (RD && RD->
isUnion());
2201 CharUnits MaxUnionSize = CharUnits::Zero();
2203 const FieldDecl *LastFieldBitfieldOrUnnamed =
nullptr;
2204 CharUnits MaxFieldOffset = CharUnits::Zero();
2205 CharUnits LastBitfieldOrUnnamedOffset = CharUnits::Zero();
2207 if (RecFields.empty())
2211 for (
unsigned i = 0, e = RecFields.size(); i != e; ++i) {
2221 LastFieldBitfieldOrUnnamed = Field;
2222 LastBitfieldOrUnnamedOffset = FieldOffset;
2226 LastFieldBitfieldOrUnnamed =
nullptr;
2233 BytePos + FieldOffset, HasUnion);
2239 dyn_cast_or_null<ConstantArrayType>(Array);
2240 uint64_t ElCount = CArray->
getSize().getZExtValue();
2241 assert(CArray &&
"only array with known element size is supported");
2245 dyn_cast_or_null<ConstantArrayType>(Array);
2246 ElCount *= CArray->
getSize().getZExtValue();
2250 int OldIndex = RunSkipBlockVars.size() - 1;
2252 BuildRCBlockVarRecordLayout(RT, BytePos + FieldOffset,
2258 for (
int FirstIndex = RunSkipBlockVars.size() - 1 ;ElIx < ElCount; ElIx++) {
2260 for (
int i = OldIndex+1; i <= FirstIndex; ++i)
2261 RunSkipBlockVars.push_back(
2262 RUN_SKIP(RunSkipBlockVars[i].opcode,
2263 RunSkipBlockVars[i].block_var_bytepos + Size*ElIx,
2264 RunSkipBlockVars[i].block_var_size));
2272 if (UnionIvarSize > MaxUnionSize) {
2273 MaxUnionSize = UnionIvarSize;
2275 MaxFieldOffset = FieldOffset;
2278 UpdateRunSkipBlockVars(
false,
2279 getBlockCaptureLifetime(FQT, ByrefLayout),
2280 BytePos + FieldOffset,
2285 if (LastFieldBitfieldOrUnnamed) {
2286 if (LastFieldBitfieldOrUnnamed->
isBitField()) {
2288 uint64_t BitFieldSize
2290 unsigned UnsSize = (BitFieldSize / ByteSizeInBits) +
2291 ((BitFieldSize % ByteSizeInBits) != 0);
2292 CharUnits Size = CharUnits::fromQuantity(UnsSize);
2293 Size += LastBitfieldOrUnnamedOffset;
2294 UpdateRunSkipBlockVars(
false,
2295 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
2297 BytePos + LastBitfieldOrUnnamedOffset,
2300 assert(!LastFieldBitfieldOrUnnamed->
getIdentifier() &&
"Expected unnamed");
2304 UpdateRunSkipBlockVars(
false,
2305 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
2307 BytePos + LastBitfieldOrUnnamedOffset,
2313 UpdateRunSkipBlockVars(
false,
2314 getBlockCaptureLifetime(MaxField->
getType(), ByrefLayout),
2315 BytePos + MaxFieldOffset,
2319 void CGObjCCommonMac::BuildRCBlockVarRecordLayout(
const RecordType *RT,
2326 const llvm::StructLayout *RecLayout =
2327 CGM.
getDataLayout().getStructLayout(cast<llvm::StructType>(Ty));
2329 BuildRCRecordLayout(RecLayout, RD, Fields, BytePos, HasUnion, ByrefLayout);
2341 uint64_t CGObjCCommonMac::InlineLayoutInstruction(
2344 if (Layout.size() <= 3) {
2345 unsigned size = Layout.size();
2346 unsigned strong_word_count = 0, byref_word_count=0, weak_word_count=0;
2348 enum BLOCK_LAYOUT_OPCODE opcode ;
2352 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2353 if (opcode == BLOCK_LAYOUT_STRONG)
2354 strong_word_count = (inst & 0xF)+1;
2358 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2359 if (opcode == BLOCK_LAYOUT_BYREF)
2360 byref_word_count = (inst & 0xF)+1;
2364 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2365 if (opcode == BLOCK_LAYOUT_WEAK)
2366 weak_word_count = (inst & 0xF)+1;
2373 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2374 if (opcode == BLOCK_LAYOUT_STRONG) {
2375 strong_word_count = (inst & 0xF)+1;
2377 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2378 if (opcode == BLOCK_LAYOUT_BYREF)
2379 byref_word_count = (inst & 0xF)+1;
2380 else if (opcode == BLOCK_LAYOUT_WEAK)
2381 weak_word_count = (inst & 0xF)+1;
2385 else if (opcode == BLOCK_LAYOUT_BYREF) {
2386 byref_word_count = (inst & 0xF)+1;
2388 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2389 if (opcode == BLOCK_LAYOUT_WEAK)
2390 weak_word_count = (inst & 0xF)+1;
2400 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2401 if (opcode == BLOCK_LAYOUT_STRONG)
2402 strong_word_count = (inst & 0xF)+1;
2403 else if (opcode == BLOCK_LAYOUT_BYREF)
2404 byref_word_count = (inst & 0xF)+1;
2405 else if (opcode == BLOCK_LAYOUT_WEAK)
2406 weak_word_count = (inst & 0xF)+1;
2418 if (strong_word_count == 16 || byref_word_count == 16 || weak_word_count == 16)
2422 (strong_word_count != 0) + (byref_word_count != 0) + (weak_word_count != 0);
2424 if (size == count) {
2425 if (strong_word_count)
2426 Result = strong_word_count;
2428 if (byref_word_count)
2429 Result += byref_word_count;
2431 if (weak_word_count)
2432 Result += weak_word_count;
2438 llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(
bool ComputeByrefLayout) {
2439 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2440 if (RunSkipBlockVars.empty())
2444 unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2448 llvm::array_pod_sort(RunSkipBlockVars.begin(), RunSkipBlockVars.end());
2451 unsigned size = RunSkipBlockVars.size();
2452 for (
unsigned i = 0; i < size; i++) {
2453 enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode;
2454 CharUnits start_byte_pos = RunSkipBlockVars[i].block_var_bytepos;
2455 CharUnits end_byte_pos = start_byte_pos;
2458 if (opcode == RunSkipBlockVars[j].opcode) {
2459 end_byte_pos = RunSkipBlockVars[j++].block_var_bytepos;
2466 end_byte_pos - start_byte_pos + RunSkipBlockVars[j-1].block_var_size;
2469 RunSkipBlockVars[j].block_var_bytepos -
2470 RunSkipBlockVars[j-1].block_var_bytepos - RunSkipBlockVars[j-1].block_var_size;
2471 size_in_bytes += gap;
2473 CharUnits residue_in_bytes = CharUnits::Zero();
2474 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) {
2475 residue_in_bytes = size_in_bytes % WordSizeInBytes;
2476 size_in_bytes -= residue_in_bytes;
2477 opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS;
2480 unsigned size_in_words = size_in_bytes.
getQuantity() / WordSizeInBytes;
2481 while (size_in_words >= 16) {
2484 unsigned char inst = (opcode << 4) | 0xf;
2485 Layout.push_back(inst);
2486 size_in_words -= 16;
2488 if (size_in_words > 0) {
2491 unsigned char inst = (opcode << 4) | (size_in_words-1);
2492 Layout.push_back(inst);
2494 if (residue_in_bytes > CharUnits::Zero()) {
2495 unsigned char inst =
2496 (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) | (residue_in_bytes.
getQuantity()-1);
2497 Layout.push_back(inst);
2501 while (!Layout.empty()) {
2502 unsigned char inst = Layout.back();
2503 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2504 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES || opcode == BLOCK_LAYOUT_NON_OBJECT_WORDS)
2510 uint64_t Result = InlineLayoutInstruction(Layout);
2514 if (ComputeByrefLayout)
2515 printf(
"\n Inline BYREF variable layout: ");
2517 printf(
"\n Inline block variable layout: ");
2518 printf(
"0x0%" PRIx64
"", Result);
2519 if (
auto numStrong = (Result & 0xF00) >> 8)
2520 printf(
", BL_STRONG:%d", (
int) numStrong);
2521 if (
auto numByref = (Result & 0x0F0) >> 4)
2522 printf(
", BL_BYREF:%d", (
int) numByref);
2523 if (
auto numWeak = (Result & 0x00F) >> 0)
2524 printf(
", BL_WEAK:%d", (
int) numWeak);
2525 printf(
", BL_OPERATOR:0\n");
2527 return llvm::ConstantInt::get(CGM.
IntPtrTy, Result);
2530 unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0;
2531 Layout.push_back(inst);
2533 for (
unsigned i = 0, e = Layout.size(); i != e; i++)
2534 BitMap += Layout[i];
2537 if (ComputeByrefLayout)
2538 printf(
"\n Byref variable layout: ");
2540 printf(
"\n Block variable layout: ");
2541 for (
unsigned i = 0, e = BitMap.size(); i != e; i++) {
2542 unsigned char inst = BitMap[i];
2543 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2546 case BLOCK_LAYOUT_OPERATOR:
2550 case BLOCK_LAYOUT_NON_OBJECT_BYTES:
2551 printf(
"BL_NON_OBJECT_BYTES:");
2553 case BLOCK_LAYOUT_NON_OBJECT_WORDS:
2554 printf(
"BL_NON_OBJECT_WORD:");
2556 case BLOCK_LAYOUT_STRONG:
2559 case BLOCK_LAYOUT_BYREF:
2562 case BLOCK_LAYOUT_WEAK:
2565 case BLOCK_LAYOUT_UNRETAINED:
2566 printf(
"BL_UNRETAINED:");
2571 printf(
"%d", (inst & 0xf) + delta);
2579 llvm::GlobalVariable *Entry = CreateMetadataVar(
2581 llvm::ConstantDataArray::getString(VMContext, BitMap,
false),
2582 "__TEXT,__objc_classname,cstring_literals", CharUnits::One(),
true);
2586 llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(
CodeGenModule &CGM,
2588 assert(CGM.
getLangOpts().getGC() == LangOptions::NonGC);
2590 RunSkipBlockVars.clear();
2591 bool hasUnion =
false;
2595 unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2600 const llvm::StructLayout *layout =
2606 UpdateRunSkipBlockVars(
false, Qualifiers::OCL_None,
2610 for (
const auto &CI : blockDecl->
captures()) {
2611 const VarDecl *variable = CI.getVariable();
2620 CharUnits::fromQuantity(layout->getElementOffset(capture.
getIndex()));
2622 assert(!type->
isArrayType() &&
"array variable should not be caught");
2625 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion);
2630 fieldSize = CharUnits::fromQuantity(WordSizeInBytes);
2633 UpdateRunSkipBlockVars(CI.isByRef(), getBlockCaptureLifetime(type,
false),
2634 fieldOffset, fieldSize);
2636 return getBitmapBlockLayout(
false);
2641 assert(CGM.
getLangOpts().getGC() == LangOptions::NonGC);
2642 assert(!T->
isArrayType() &&
"__block array variable should not be caught");
2644 RunSkipBlockVars.clear();
2645 bool hasUnion =
false;
2647 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion,
true );
2648 llvm::Constant *Result = getBitmapBlockLayout(
true);
2649 if (isa<llvm::ConstantInt>(Result))
2650 Result = llvm::ConstantExpr::getIntToPtr(Result, CGM.
Int8PtrTy);
2653 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2663 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
2664 ObjCTypes.getExternalProtocolPtrTy());
2676 GetOrEmitProtocol(PD);
2679 llvm::Constant *CGObjCCommonMac::GetProtocolRef(
const ObjCProtocolDecl *PD) {
2681 return GetOrEmitProtocol(PD);
2683 return GetOrEmitProtocolRef(PD);
2686 llvm::Value *CGObjCCommonMac::EmitClassRefViaRuntime(
2689 ObjCCommonTypesHelper &ObjCTypes) {
2690 llvm::Constant *lookUpClassFn = ObjCTypes.getLookUpClassFn();
2700 llvm::CallInst *call = CGF.
Builder.CreateCall(lookUpClassFn, className);
2701 call->setDoesNotThrow();
2718 llvm::GlobalVariable *Entry = Protocols[PD->
getIdentifier()];
2721 if (Entry && Entry->hasInitializer())
2733 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
2734 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
2735 std::vector<llvm::Constant*> MethodTypesExt, OptMethodTypesExt;
2737 llvm::Constant *C = GetMethodDescriptionConstant(MD);
2739 return GetOrEmitProtocolRef(PD);
2741 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
2742 OptInstanceMethods.push_back(C);
2743 OptMethodTypesExt.push_back(GetMethodVarType(MD,
true));
2745 InstanceMethods.push_back(C);
2746 MethodTypesExt.push_back(GetMethodVarType(MD,
true));
2751 llvm::Constant *C = GetMethodDescriptionConstant(MD);
2753 return GetOrEmitProtocolRef(PD);
2755 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
2756 OptClassMethods.push_back(C);
2757 OptMethodTypesExt.push_back(GetMethodVarType(MD,
true));
2759 ClassMethods.push_back(C);
2760 MethodTypesExt.push_back(GetMethodVarType(MD,
true));
2764 MethodTypesExt.insert(MethodTypesExt.end(),
2765 OptMethodTypesExt.begin(), OptMethodTypesExt.end());
2767 llvm::Constant *Values[] = {
2768 EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods,
2771 EmitProtocolList(
"OBJC_PROTOCOL_REFS_" + PD->
getName(),
2773 EmitMethodDescList(
"OBJC_PROTOCOL_INSTANCE_METHODS_" + PD->
getName(),
2774 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
2776 EmitMethodDescList(
"OBJC_PROTOCOL_CLASS_METHODS_" + PD->
getName(),
2777 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2779 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
2784 assert(Entry->hasPrivateLinkage());
2785 Entry->setInitializer(Init);
2787 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolTy,
2788 false, llvm::GlobalValue::PrivateLinkage,
2789 Init,
"OBJC_PROTOCOL_" + PD->
getName());
2790 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
2792 Entry->setAlignment(4);
2801 llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD) {
2802 llvm::GlobalVariable *&Entry = Protocols[PD->
getIdentifier()];
2808 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolTy,
2809 false, llvm::GlobalValue::PrivateLinkage,
2810 nullptr,
"OBJC_PROTOCOL_" + PD->
getName());
2811 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
2813 Entry->setAlignment(4);
2835 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
2836 llvm::Constant *Values[] = {
2837 llvm::ConstantInt::get(ObjCTypes.IntTy, Size),
2838 EmitMethodDescList(
"OBJC_PROTOCOL_INSTANCE_METHODS_OPT_" + PD->
getName(),
2839 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
2840 OptInstanceMethods),
2841 EmitMethodDescList(
"OBJC_PROTOCOL_CLASS_METHODS_OPT_" + PD->
getName(),
2842 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2844 EmitPropertyList(
"OBJC_$_PROP_PROTO_LIST_" + PD->
getName(),
nullptr, PD,
2846 EmitProtocolMethodTypes(
"OBJC_PROTOCOL_METHOD_TYPES_" + PD->
getName(),
2847 MethodTypesExt, ObjCTypes),
2848 EmitPropertyList(
"OBJC_$_CLASS_PROP_PROTO_LIST_" + PD->
getName(),
nullptr,
2849 PD, ObjCTypes,
true)};
2852 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
2853 Values[3]->isNullValue() && Values[4]->isNullValue() &&
2854 Values[5]->isNullValue())
2855 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
2857 llvm::Constant *Init =
2858 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
2861 return CreateMetadataVar(
"\01l_OBJC_PROTOCOLEXT_" + PD->
getName(), Init,
2873 CGObjCMac::EmitProtocolList(Twine
Name,
2879 ProtocolRefs.push_back(GetProtocolRef(*begin));
2882 if (ProtocolRefs.empty())
2883 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
2886 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
2888 llvm::Constant *Values[3];
2890 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
2891 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy,
2892 ProtocolRefs.size() - 1);
2894 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
2895 ProtocolRefs.size()),
2898 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
2899 llvm::GlobalVariable *GV =
2900 CreateMetadataVar(Name, Init,
"__OBJC,__cat_cls_meth,regular,no_dead_strip",
2902 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
2905 void CGObjCCommonMac::
2906 PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*,16> &PropertySet,
2908 const Decl *Container,
2910 const ObjCCommonTypesHelper &ObjCTypes,
2911 bool IsClassProperty) {
2913 PushProtocolProperties(PropertySet, Properties, Container,
P, ObjCTypes,
2917 if (IsClassProperty != PD->isClassProperty())
2921 llvm::Constant *Prop[] = {
2923 GetPropertyTypeString(PD, Container)
2925 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, Prop));
2941 llvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name,
2942 const Decl *Container,
2944 const ObjCCommonTypesHelper &ObjCTypes,
2945 bool IsClassProperty) {
2946 if (IsClassProperty) {
2950 if ((Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 11)) ||
2951 (Triple.isiOS() && Triple.isOSVersionLT(9)))
2952 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
2956 llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
2959 llvm::Constant *Prop[] = {GetPropertyName(PD->
getIdentifier()),
2960 GetPropertyTypeString(PD, Container)};
2961 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, Prop));
2966 if (IsClassProperty != PD->isClassProperty())
2973 if (IsClassProperty != PD->isClassProperty())
2983 for (
const auto *
P : OID->all_referenced_protocols())
2984 PushProtocolProperties(PropertySet, Properties, Container,
P, ObjCTypes,
2988 for (
const auto *
P : CD->protocols())
2989 PushProtocolProperties(PropertySet, Properties, Container,
P, ObjCTypes,
2994 if (Properties.empty())
2995 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
2997 unsigned PropertySize =
2999 llvm::Constant *Values[3];
3000 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
3001 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
3002 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
3004 Values[2] = llvm::ConstantArray::get(AT, Properties);
3005 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
3007 llvm::GlobalVariable *GV =
3008 CreateMetadataVar(Name, Init,
3009 (ObjCABI == 2) ?
"__DATA, __objc_const" :
3010 "__OBJC,__property,regular,no_dead_strip",
3013 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy);
3017 CGObjCCommonMac::EmitProtocolMethodTypes(Twine Name,
3019 const ObjCCommonTypesHelper &ObjCTypes) {
3021 if (MethodTypes.empty())
3022 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy);
3024 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
3025 MethodTypes.size());
3026 llvm::Constant *Init = llvm::ConstantArray::get(AT, MethodTypes);
3028 llvm::GlobalVariable *GV = CreateMetadataVar(
3029 Name, Init, (ObjCABI == 2) ?
"__DATA, __objc_const" : StringRef(),
3031 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.Int8PtrPtrTy);
3041 CGObjCMac::GetMethodDescriptionConstant(
const ObjCMethodDecl *MD) {
3042 llvm::Constant *Desc[] = {
3043 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->
getSelector()),
3044 ObjCTypes.SelectorPtrTy),
3045 GetMethodVarType(MD)
3050 return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
3055 CGObjCMac::EmitMethodDescList(Twine Name, StringRef Section,
3058 if (Methods.empty())
3059 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
3061 llvm::Constant *Values[2];
3062 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
3063 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
3065 Values[1] = llvm::ConstantArray::get(AT, Methods);
3066 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
3068 llvm::GlobalVariable *GV =
3070 return llvm::ConstantExpr::getBitCast(GV,
3071 ObjCTypes.MethodDescriptionListPtrTy);
3087 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.CategoryTy);
3098 llvm::raw_svector_ostream(ExtName) << Interface->
getName() <<
'_'
3104 InstanceMethods.push_back(GetMethodConstant(I));
3108 ClassMethods.push_back(GetMethodConstant(I));
3110 llvm::Constant *Values[8];
3111 Values[0] = GetClassName(OCD->
getName());
3114 Values[2] = EmitMethodList(
"OBJC_CATEGORY_INSTANCE_METHODS_" + ExtName.str(),
3115 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
3117 Values[3] = EmitMethodList(
"OBJC_CATEGORY_CLASS_METHODS_" + ExtName.str(),
3118 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
3122 EmitProtocolList(
"OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
3125 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
3127 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
3131 Values[6] = EmitPropertyList(
"\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
3133 Values[7] = EmitPropertyList(
"\01l_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(),
3136 Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3137 Values[7] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3140 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
3143 llvm::GlobalVariable *GV =
3144 CreateMetadataVar(
"OBJC_CATEGORY_" + ExtName.str(), Init,
3145 "__OBJC,__category,regular,no_dead_strip",
3147 DefinedCategories.push_back(GV);
3148 DefinedCategoryNames.insert(ExtName.str());
3150 MethodDefinitions.clear();
3210 for (
auto field : recType->getDecl()->fields()) {
3225 assert(CGM.
getLangOpts().getGC() == LangOptions::NonGC);
3263 llvm::Constant *Protocols =
3264 EmitProtocolList(
"OBJC_CLASS_PROTOCOLS_" + ID->
getName(),
3271 bool hasMRCWeak =
false;
3288 InstanceMethods.push_back(GetMethodConstant(I));
3292 ClassMethods.push_back(GetMethodConstant(I));
3295 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
3299 if (llvm::Constant *C = GetMethodConstant(MD))
3300 InstanceMethods.push_back(C);
3302 if (llvm::Constant *C = GetMethodConstant(MD))
3303 InstanceMethods.push_back(C);
3307 llvm::Constant *Values[12];
3308 Values[ 0] = EmitMetaClass(ID, Protocols, ClassMethods);
3311 LazySymbols.insert(Super->getIdentifier());
3314 llvm::ConstantExpr::getBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
3315 ObjCTypes.ClassPtrTy);
3317 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
3321 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
3322 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
3323 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size.
getQuantity());
3324 Values[ 6] = EmitIvarList(ID,
false);
3325 Values[7] = EmitMethodList(
"OBJC_INSTANCE_METHODS_" + ID->
getName(),
3326 "__OBJC,__inst_meth,regular,no_dead_strip",
3329 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
3330 Values[ 9] = Protocols;
3331 Values[10] = BuildStrongIvarLayout(ID, CharUnits::Zero(), Size);
3332 Values[11] = EmitClassExtension(ID, Size, hasMRCWeak,
3334 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
3336 std::string
Name(
"OBJC_CLASS_");
3338 const char *Section =
"__OBJC,__class,regular,no_dead_strip";
3340 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3342 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3343 "Forward metaclass reference has incorrect type.");
3344 GV->setInitializer(Init);
3345 GV->setSection(Section);
3349 GV = CreateMetadataVar(Name, Init, Section, CGM.
getPointerAlign(),
true);
3350 DefinedClasses.push_back(GV);
3351 ImplementedClasses.push_back(Interface);
3353 MethodDefinitions.clear();
3357 llvm::Constant *Protocols,
3360 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ClassTy);
3365 llvm::Constant *Values[12];
3372 ObjCTypes.ClassPtrTy);
3378 llvm::ConstantExpr::getBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
3379 ObjCTypes.ClassPtrTy);
3381 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
3385 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
3386 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
3387 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
3388 Values[ 6] = EmitIvarList(ID,
true);
3391 "__OBJC,__cls_meth,regular,no_dead_strip", Methods);
3393 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
3394 Values[ 9] = Protocols;
3396 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
3398 Values[11] = EmitClassExtension(ID, CharUnits::Zero(),
false,
3400 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
3403 std::string
Name(
"OBJC_METACLASS_");
3407 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3409 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3410 "Forward metaclass reference has incorrect type.");
3411 GV->setInitializer(Init);
3413 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
3414 llvm::GlobalValue::PrivateLinkage,
3417 GV->setSection(
"__OBJC,__meta_class,regular,no_dead_strip");
3418 GV->setAlignment(4);
3435 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3437 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
3438 llvm::GlobalValue::PrivateLinkage,
nullptr,
3441 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3442 "Forward metaclass reference has incorrect type.");
3448 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3451 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
3452 llvm::GlobalValue::PrivateLinkage,
nullptr,
3455 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3456 "Forward class metadata reference has incorrect type.");
3474 bool isClassProperty) {
3476 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
3478 llvm::Constant *Values[3];
3479 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
3480 if (isClassProperty) {
3482 Values[1] = llvm::Constant::getNullValue(PtrTy);
3484 Values[1] = BuildWeakIvarLayout(ID, CharUnits::Zero(), InstanceSize,
3486 if (isClassProperty)
3487 Values[2] = EmitPropertyList(
"\01l_OBJC_$_CLASS_PROP_LIST_" + ID->
getName(),
3490 Values[2] = EmitPropertyList(
"\01l_OBJC_$_PROP_LIST_" + ID->
getName(),
3494 if ((!Values[1] || Values[1]->isNullValue()) && Values[2]->isNullValue())
3495 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
3497 llvm::Constant *Init =
3498 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
3499 return CreateMetadataVar(
"OBJC_CLASSEXT_" + ID->
getName(), Init,
3500 "__OBJC,__class_ext,regular,no_dead_strip",
3518 std::vector<llvm::Constant*> Ivars;
3526 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3533 if (!IVD->getDeclName())
3535 llvm::Constant *Ivar[] = {
3536 GetMethodVarName(IVD->getIdentifier()),
3537 GetMethodVarType(IVD),
3538 llvm::ConstantInt::get(ObjCTypes.IntTy,
3539 ComputeIvarBaseOffset(CGM, OID, IVD))
3541 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar));
3546 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3548 llvm::Constant *Values[2];
3549 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
3550 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
3552 Values[1] = llvm::ConstantArray::get(AT, Ivars);
3553 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
3555 llvm::GlobalVariable *GV;
3558 CreateMetadataVar(
"OBJC_CLASS_VARIABLES_" + ID->
getName(), Init,
3559 "__OBJC,__class_vars,regular,no_dead_strip",
3562 GV = CreateMetadataVar(
"OBJC_INSTANCE_VARIABLES_" + ID->
getName(), Init,
3563 "__OBJC,__instance_vars,regular,no_dead_strip",
3565 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy);
3585 llvm::Constant *CGObjCMac::GetMethodConstant(
const ObjCMethodDecl *MD) {
3586 llvm::Function *Fn = GetMethodDefinition(MD);
3590 llvm::Constant *Method[] = {
3591 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->
getSelector()),
3592 ObjCTypes.SelectorPtrTy),
3593 GetMethodVarType(MD),
3594 llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy)
3596 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
3599 llvm::Constant *CGObjCMac::EmitMethodList(Twine Name, StringRef Section,
3602 if (Methods.empty())
3603 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
3605 llvm::Constant *Values[3];
3606 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
3607 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
3608 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
3610 Values[2] = llvm::ConstantArray::get(AT, Methods);
3611 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
3613 llvm::GlobalVariable *GV =
3615 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListPtrTy);
3618 llvm::Function *CGObjCCommonMac::GenerateMethod(
const ObjCMethodDecl *OMD,
3621 GetNameForMethod(OMD, CD, Name);
3624 llvm::FunctionType *MethodTy =
3626 llvm::Function *Method =
3631 MethodDefinitions.insert(std::make_pair(OMD, Method));
3636 llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
3637 llvm::Constant *Init,
3641 llvm::Type *Ty = Init->getType();
3642 llvm::GlobalVariable *GV =
3643 new llvm::GlobalVariable(CGM.
getModule(), Ty,
false,
3644 llvm::GlobalValue::PrivateLinkage, Init,
Name);
3645 if (!Section.empty())
3646 GV->setSection(Section);
3653 llvm::Function *CGObjCMac::ModuleInitFunction() {
3659 llvm::Constant *CGObjCMac::GetPropertyGetFunction() {
3660 return ObjCTypes.getGetPropertyFn();
3663 llvm::Constant *CGObjCMac::GetPropertySetFunction() {
3664 return ObjCTypes.getSetPropertyFn();
3667 llvm::Constant *CGObjCMac::GetOptimizedPropertySetFunction(
bool atomic,
3669 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
3672 llvm::Constant *CGObjCMac::GetGetStructFunction() {
3673 return ObjCTypes.getCopyStructFn();
3676 llvm::Constant *CGObjCMac::GetSetStructFunction() {
3677 return ObjCTypes.getCopyStructFn();
3680 llvm::Constant *CGObjCMac::GetCppAtomicObjectGetFunction() {
3681 return ObjCTypes.getCppAtomicObjectFunction();
3684 llvm::Constant *CGObjCMac::GetCppAtomicObjectSetFunction() {
3685 return ObjCTypes.getCppAtomicObjectFunction();
3688 llvm::Constant *CGObjCMac::EnumerationMutationFunction() {
3689 return ObjCTypes.getEnumerationMutationFn();
3693 return EmitTryOrSynchronizedStmt(CGF, S);
3698 return EmitTryOrSynchronizedStmt(CGF, S);
3707 ObjCTypesHelper &ObjCTypes;
3708 PerformFragileFinally(
const Stmt *
S,
3712 ObjCTypesHelper *ObjCTypes)
3713 : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
3714 ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
3719 llvm::BasicBlock *FinallyCallExit =
3721 llvm::BasicBlock *FinallyNoCallExit =
3724 FinallyCallExit, FinallyNoCallExit);
3728 ExceptionData.getPointer());
3732 if (isa<ObjCAtTryStmt>(
S)) {
3734 cast<ObjCAtTryStmt>(
S).getFinallyStmt()) {
3736 if (flags.isForEHCleanup())
return;
3743 CGF.
EmitStmt(FinallyStmt->getFinallyBody());
3762 class FragileHazards {
3767 llvm::InlineAsm *ReadHazard;
3768 llvm::InlineAsm *WriteHazard;
3770 llvm::FunctionType *GetAsmFnType();
3772 void collectLocals();
3778 void emitWriteHazard();
3779 void emitHazardsInNewBlocks();
3791 if (Locals.empty())
return;
3796 BlocksBeforeTry.insert(&*I);
3798 llvm::FunctionType *AsmFnTy = GetAsmFnType();
3806 std::string Constraint;
3807 for (
unsigned I = 0,
E = Locals.size(); I !=
E; ++
I) {
3808 if (I) Constraint +=
',';
3812 ReadHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
3820 std::string Constraint;
3821 for (
unsigned I = 0,
E = Locals.size(); I !=
E; ++
I) {
3822 if (I) Constraint +=
',';
3823 Constraint +=
"=*m";
3826 WriteHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
3831 void FragileHazards::emitWriteHazard() {
3832 if (Locals.empty())
return;
3838 assert(!Locals.empty());
3839 llvm::CallInst *call = Builder.CreateCall(ReadHazard, Locals);
3840 call->setDoesNotThrow();
3846 void FragileHazards::emitHazardsInNewBlocks() {
3847 if (Locals.empty())
return;
3853 FI = CGF.
CurFn->begin(), FE = CGF.
CurFn->end(); FI != FE; ++FI) {
3854 llvm::BasicBlock &BB = *FI;
3855 if (BlocksBeforeTry.count(&BB))
continue;
3859 BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) {
3860 llvm::Instruction &I = *BI;
3864 if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(
I))
continue;
3865 if (isa<llvm::IntrinsicInst>(I))
3870 llvm::CallSite CS(&I);
3871 if (CS.doesNotThrow())
continue;
3878 Builder.SetInsertPoint(&BB, BI);
3879 emitReadHazard(Builder);
3892 void FragileHazards::collectLocals() {
3900 llvm::BasicBlock &Entry = CGF.
CurFn->getEntryBlock();
3902 I = Entry.begin(),
E = Entry.end(); I !=
E; ++
I)
3903 if (isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I))
3904 Locals.push_back(&*I);
3907 llvm::FunctionType *FragileHazards::GetAsmFnType() {
3909 for (
unsigned i = 0, e = Locals.size(); i != e; ++i)
3910 tys[i] = Locals[i]->getType();
3911 return llvm::FunctionType::get(CGF.
VoidTy, tys,
false);
4028 bool isTry = isa<ObjCAtTryStmt>(
S);
4045 Address SyncArgSlot = Address::invalid();
4048 CGF.
EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
4061 "exceptiondata.ptr");
4067 FragileHazards Hazards(CGF);
4083 Address PropagatingExnVar = Address::invalid();
4096 ExceptionData.getPointer());
4099 llvm::Constant *Zero = llvm::ConstantInt::get(CGF.
Builder.getInt32Ty(), 0);
4102 ObjCTypes.ExceptionDataTy, ExceptionData.getPointer(), GEPIndexes,
4105 ObjCTypes.getSetJmpFn(), SetJmpBuffer,
"setjmp_result");
4106 SetJmpResult->setCanReturnTwice();
4113 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
4114 CGF.
Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
4119 CGF.
EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
4120 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
4122 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.
Builder.saveAndClearIP();
4128 Hazards.emitWriteHazard();
4132 if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
4141 llvm::CallInst *Caught =
4143 ExceptionData.getPointer(),
"caught");
4153 llvm::BasicBlock *CatchBlock =
nullptr;
4154 llvm::BasicBlock *CatchHandler =
nullptr;
4160 "propagating_exception");
4166 ExceptionData.getPointer());
4168 llvm::CallInst *SetJmpResult =
4170 SetJmpBuffer,
"setjmp.result");
4171 SetJmpResult->setCanReturnTwice();
4174 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
4178 CGF.
Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
4188 bool AllMatched =
false;
4218 EmitInitOfCatchParam(CGF, Caught, CatchParam);
4224 CatchVarCleanups.ForceCleanup();
4230 assert(OPT &&
"Unexpected non-object pointer type in @catch");
4235 assert(IDecl &&
"Catch parameter must have Objective-C type!");
4241 llvm::CallInst *Match =
4243 matchArgs,
"match");
4248 CGF.
Builder.CreateCondBr(CGF.
Builder.CreateIsNotNull(Match,
"matched"),
4249 MatchedBlock, NextCatchBlock);
4265 EmitInitOfCatchParam(CGF, Tmp, CatchParam);
4270 CatchVarCleanups.ForceCleanup();
4281 if (Caught->use_empty())
4282 Caught->eraseFromParent();
4298 assert(PropagatingExnVar.
isValid());
4299 llvm::CallInst *NewCaught =
4301 ExceptionData.getPointer(),
"caught");
4311 Hazards.emitHazardsInNewBlocks();
4314 CGF.
Builder.restoreIP(TryFallthroughIP);
4318 CGF.
EmitBlock(FinallyEnd.getBlock(),
true);
4321 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
4326 if (PropagatingExnVar.
isValid()) {
4331 llvm::CallInst *Caught =
4333 ExceptionData.getPointer());
4334 PropagatingExn = Caught;
4339 CGF.
Builder.CreateUnreachable();
4342 CGF.
Builder.restoreIP(SavedIP);
4347 bool ClearInsertionPoint) {
4356 "Unexpected rethrow outside @catch block.");
4360 CGF.
EmitRuntimeCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
4361 ->setDoesNotReturn();
4362 CGF.
Builder.CreateUnreachable();
4365 if (ClearInsertionPoint)
4366 CGF.
Builder.ClearInsertionPoint();
4376 ObjCTypes.PtrObjectPtrTy);
4389 llvm::Type * SrcTy = src->
getType();
4390 if (!isa<llvm::PointerType>(SrcTy)) {
4391 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(SrcTy);
4392 assert(Size <= 8 && "does not support size > 8
");
4393 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
4394 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
4395 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4397 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4398 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4399 llvm::Value *args[] = { src, dst.getPointer() };
4400 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(),
4401 args, "weakassign
");
4407 void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
4408 llvm::Value *src, Address dst,
4410 llvm::Type * SrcTy = src->getType();
4411 if (!isa<llvm::PointerType>(SrcTy)) {
4412 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4413 assert(Size <= 8 && "does
not support size > 8
");
4414 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
4415 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
4416 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4418 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4419 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4420 llvm::Value *args[] = { src, dst.getPointer() };
4422 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(),
4423 args, "globalassign
");
4425 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(),
4426 args, "threadlocalassign
");
4432 void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
4433 llvm::Value *src, Address dst,
4434 llvm::Value *ivarOffset) {
4435 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is
NULL");
4436 llvm::Type * SrcTy = src->getType();
4437 if (!isa<llvm::PointerType>(SrcTy)) {
4438 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4439 assert(Size <= 8 && "does
not support size > 8
");
4440 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
4441 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
4442 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4444 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4445 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4446 llvm::Value *args[] = { src, dst.getPointer(), ivarOffset };
4447 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
4453 void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
4454 llvm::Value *src, Address dst) {
4455 llvm::Type * SrcTy = src->getType();
4456 if (!isa<llvm::PointerType>(SrcTy)) {
4457 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4458 assert(Size <= 8 && "does
not support size > 8
");
4459 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
4460 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
4461 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4463 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4464 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4465 llvm::Value *args[] = { src, dst.getPointer() };
4466 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(),
4467 args, "strongassign
");
4470 void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
4473 llvm::Value *size) {
4474 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
4475 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
4476 llvm::Value *args[] = { DestPtr.getPointer(), SrcPtr.getPointer(), size };
4477 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
4482 LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
4484 llvm::Value *BaseValue,
4485 const ObjCIvarDecl *Ivar,
4486 unsigned CVRQualifiers) {
4487 const ObjCInterfaceDecl *ID =
4488 ObjectTy->getAs<ObjCObjectType>()->getInterface();
4489 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
4490 EmitIvarOffset(CGF, ID, Ivar));
4493 llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
4494 const ObjCInterfaceDecl *Interface,
4495 const ObjCIvarDecl *Ivar) {
4496 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
4497 return llvm::ConstantInt::get(
4498 CGM.getTypes().ConvertType(CGM.getContext().LongTy),
4502 /* *** Private Interface *** */
4512 enum ImageInfoFlags {
4513 eImageInfo_FixAndContinue = (1 << 0), // This flag is no longer set by clang.
4514 eImageInfo_GarbageCollected = (1 << 1),
4515 eImageInfo_GCOnly = (1 << 2),
4516 eImageInfo_OptimizedByDyld = (1 << 3), // This flag is set by the dyld shared cache.
4518 // A flag indicating that the module has no instances of a @synthesize of a
4519 // superclass variable. <rdar://problem/6803242>
4520 eImageInfo_CorrectedSynthesize = (1 << 4), // This flag is no longer set by clang.
4521 eImageInfo_ImageIsSimulated = (1 << 5),
4522 eImageInfo_ClassProperties = (1 << 6)
4525 void CGObjCCommonMac::EmitImageInfo() {
4526 unsigned version = 0; // Version is unused?
4527 const char *Section = (ObjCABI == 1) ?
4528 "__OBJC, __image_info,regular
" :
4529 "__DATA, __objc_imageinfo, regular, no_dead_strip
";
4531 // Generate module-level named metadata to convey this information to the
4532 // linker and code-gen.
4533 llvm::Module &Mod = CGM.getModule();
4535 // Add the ObjC ABI version to the module flags.
4536 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Version
", ObjCABI);
4537 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Version
",
4539 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Section
",
4540 llvm::MDString::get(VMContext,Section));
4542 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
4543 // Non-GC overrides those files which specify GC.
4544 Mod.addModuleFlag(llvm::Module::Override,
4545 "Objective-C Garbage Collection
", (uint32_t)0);
4547 // Add the ObjC garbage collection value.
4548 Mod.addModuleFlag(llvm::Module::Error,
4549 "Objective-C Garbage Collection
",
4550 eImageInfo_GarbageCollected);
4552 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
4553 // Add the ObjC GC Only value.
4554 Mod.addModuleFlag(llvm::Module::Error, "Objective-C GC Only
",
4557 // Require that GC be specified and set to eImageInfo_GarbageCollected.
4558 llvm::Metadata *Ops[2] = {
4559 llvm::MDString::get(VMContext, "Objective-C Garbage Collection
"),
4560 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
4561 llvm::Type::getInt32Ty(VMContext), eImageInfo_GarbageCollected))};
4562 Mod.addModuleFlag(llvm::Module::Require, "Objective-C GC Only
",
4563 llvm::MDNode::get(VMContext, Ops));
4567 // Indicate whether we're compiling this to run on a simulator.
4568 const llvm::Triple &Triple = CGM.getTarget().getTriple();
4569 if ((Triple.isiOS() || Triple.isWatchOS()) &&
4570 (Triple.getArch() == llvm::Triple::x86 ||
4571 Triple.getArch() == llvm::Triple::x86_64))
4572 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Is Simulated
",
4573 eImageInfo_ImageIsSimulated);
4575 // Indicate whether we are generating class properties.
4576 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Class Properties
",
4577 eImageInfo_ClassProperties);
4580 // struct objc_module {
4581 // unsigned long version;
4582 // unsigned long size;
4583 // const char *name;
4587 // FIXME: Get from somewhere
4588 static const int ModuleVersion = 7;
4590 void CGObjCMac::EmitModuleInfo() {
4591 uint64_t Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ModuleTy);
4593 llvm::Constant *Values[] = {
4594 llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion),
4595 llvm::ConstantInt::get(ObjCTypes.LongTy, Size),
4596 // This used to be the filename, now it is unused. <rdr://4327263>
4597 GetClassName(StringRef("")),
4600 CreateMetadataVar("OBJC_MODULES
",
4601 llvm::ConstantStruct::get(ObjCTypes.ModuleTy, Values),
4602 "__OBJC,__module_info,regular,no_dead_strip
",
4603 CGM.getPointerAlign(), true);
4606 llvm::Constant *CGObjCMac::EmitModuleSymbols() {
4607 unsigned NumClasses = DefinedClasses.size();
4608 unsigned NumCategories = DefinedCategories.size();
4610 // Return null if no symbols were defined.
4611 if (!NumClasses && !NumCategories)
4612 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
4614 llvm::Constant *Values[5];
4615 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
4616 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
4617 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
4618 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
4620 // The runtime expects exactly the list of defined classes followed
4621 // by the list of defined categories, in a single array.
4622 SmallVector<llvm::Constant*, 8> Symbols(NumClasses + NumCategories);
4623 for (unsigned i=0; i<NumClasses; i++) {
4624 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
4626 if (ObjCImplementationDecl *IMP = ID->getImplementation())
4627 // We are implementing a weak imported interface. Give it external linkage
4628 if (ID->isWeakImported() && !IMP->isWeakImported())
4629 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
4631 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
4632 ObjCTypes.Int8PtrTy);
4634 for (unsigned i=0; i<NumCategories; i++)
4635 Symbols[NumClasses + i] =
4636 llvm::ConstantExpr::getBitCast(DefinedCategories[i],
4637 ObjCTypes.Int8PtrTy);
4640 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
4644 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
4646 llvm::GlobalVariable *GV = CreateMetadataVar(
4647 "OBJC_SYMBOLS
", Init, "__OBJC,__symbols,regular,no_dead_strip
",
4648 CGM.getPointerAlign(), true);
4649 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
4652 llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF,
4653 IdentifierInfo *II) {
4654 LazySymbols.insert(II);
4656 llvm::GlobalVariable *&Entry = ClassReferences[II];
4659 llvm::Constant *Casted =
4660 llvm::ConstantExpr::getBitCast(GetClassName(II->getName()),
4661 ObjCTypes.ClassPtrTy);
4662 Entry = CreateMetadataVar(
4663 "OBJC_CLASS_REFERENCES_
", Casted,
4664 "__OBJC,__cls_refs,literal_pointers,no_dead_strip
",
4665 CGM.getPointerAlign(), true);
4668 return CGF.Builder.CreateAlignedLoad(Entry, CGF.getPointerAlign());
4671 llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF,
4672 const ObjCInterfaceDecl *ID) {
4673 // If the class has the objc_runtime_visible attribute, we need to
4674 // use the Objective-C runtime to get the class.
4675 if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
4676 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
4678 return EmitClassRefFromId(CGF, ID->getIdentifier());
4681 llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
4682 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool
");
4683 return EmitClassRefFromId(CGF, II);
4686 llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel) {
4687 return CGF.Builder.CreateLoad(EmitSelectorAddr(CGF, Sel));
4690 Address CGObjCMac::EmitSelectorAddr(CodeGenFunction &CGF, Selector Sel) {
4691 CharUnits Align = CGF.getPointerAlign();
4693 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
4695 llvm::Constant *Casted =
4696 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
4697 ObjCTypes.SelectorPtrTy);
4698 Entry = CreateMetadataVar(
4699 "OBJC_SELECTOR_REFERENCES_
", Casted,
4700 "__OBJC,__message_refs,literal_pointers,no_dead_strip
", Align, true);
4701 Entry->setExternallyInitialized(true);
4704 return Address(Entry, Align);
4707 llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) {
4708 llvm::GlobalVariable *&Entry = ClassNames[RuntimeName];
4710 Entry = CreateMetadataVar(
4712 llvm::ConstantDataArray::getString(VMContext, RuntimeName),
4713 ((ObjCABI == 2) ? "__TEXT,__objc_classname,cstring_literals
"
4714 : "__TEXT,__cstring,cstring_literals
"),
4715 CharUnits::One(), true);
4716 return getConstantGEP(VMContext, Entry, 0, 0);
4719 llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
4720 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*>::iterator
4721 I = MethodDefinitions.find(MD);
4722 if (I != MethodDefinitions.end())
4730 llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
4731 const ObjCCommonTypesHelper &ObjCTypes) {
4732 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
4735 void IvarLayoutBuilder::visitRecord(const RecordType *RT,
4737 const RecordDecl *RD = RT->getDecl();
4739 // If this is a union, remember that we had one, because it might mess
4740 // up the ordering of layout entries.
4742 IsDisordered = true;
4744 const ASTRecordLayout *recLayout = nullptr;
4745 visitAggregate(RD->field_begin(), RD->field_end(), offset,
4746 [&](const FieldDecl *field) -> CharUnits {
4748 recLayout = &CGM.getContext().getASTRecordLayout(RD);
4749 auto offsetInBits = recLayout->getFieldOffset(field->getFieldIndex());
4750 return CGM.getContext().toCharUnitsFromBits(offsetInBits);
4754 template <class Iterator, class GetOffsetFn>
4755 void IvarLayoutBuilder::visitAggregate(Iterator begin, Iterator end,
4756 CharUnits aggregateOffset,
4757 const GetOffsetFn &getOffset) {
4758 for (; begin != end; ++begin) {
4759 auto field = *begin;
4761 // Skip over bitfields.
4762 if (field->isBitField()) {
4766 // Compute the offset of the field within the aggregate.
4767 CharUnits fieldOffset = aggregateOffset + getOffset(field);
4769 visitField(field, fieldOffset);
4774 void IvarLayoutBuilder::visitField(const FieldDecl *field,
4775 CharUnits fieldOffset) {
4776 QualType fieldType = field->getType();
4778 // Drill down into arrays.
4779 uint64_t numElts = 1;
4780 while (auto arrayType = CGM.getContext().getAsConstantArrayType(fieldType)) {
4781 numElts *= arrayType->getSize().getZExtValue();
4782 fieldType = arrayType->getElementType();
4785 assert(!fieldType->isArrayType() && "ivar of non-constant array type?
");
4787 // If we ended up with a zero-sized array, we've done what we can do within
4788 // the limits of this layout encoding.
4789 if (numElts == 0) return;
4791 // Recurse if the base element type is a record type.
4792 if (auto recType = fieldType->getAs<RecordType>()) {
4793 size_t oldEnd = IvarsInfo.size();
4795 visitRecord(recType, fieldOffset);
4797 // If we have an array, replicate the first entry's layout information.
4798 auto numEltEntries = IvarsInfo.size() - oldEnd;
4799 if (numElts != 1 && numEltEntries != 0) {
4800 CharUnits eltSize = CGM.getContext().getTypeSizeInChars(recType);
4801 for (uint64_t eltIndex = 1; eltIndex != numElts; ++eltIndex) {
4802 // Copy the last numEltEntries onto the end of the array, adjusting
4803 // each for the element size.
4804 for (size_t i = 0; i != numEltEntries; ++i) {
4805 auto firstEntry = IvarsInfo[oldEnd + i];
4806 IvarsInfo.push_back(IvarInfo(firstEntry.Offset + eltIndex * eltSize,
4807 firstEntry.SizeInWords));
4815 // Classify the element type.
4816 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), fieldType);
4818 // If it matches what we're looking for, add an entry.
4819 if ((ForStrongLayout && GCAttr == Qualifiers::Strong)
4820 || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
4821 assert(CGM.getContext().getTypeSizeInChars(fieldType)
4822 == CGM.getPointerSize());
4823 IvarsInfo.push_back(IvarInfo(fieldOffset, numElts));
4830 llvm::Constant *IvarLayoutBuilder::buildBitmap(CGObjCCommonMac &CGObjC,
4831 llvm::SmallVectorImpl<unsigned char> &buffer) {
4832 // The bitmap is a series of skip/scan instructions, aligned to word
4833 // boundaries. The skip is performed first.
4834 const unsigned char MaxNibble = 0xF;
4835 const unsigned char SkipMask = 0xF0, SkipShift = 4;
4836 const unsigned char ScanMask = 0x0F, ScanShift = 0;
4838 assert(!IvarsInfo.empty() && "generating bitmap
for no data
");
4840 // Sort the ivar info on byte position in case we encounterred a
4841 // union nested in the ivar list.
4843 // This isn't a stable sort, but our algorithm should handle it fine.
4844 llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end());
4846 assert(std::is_sorted(IvarsInfo.begin(), IvarsInfo.end()));
4848 assert(IvarsInfo.back().Offset < InstanceEnd);
4850 assert(buffer.empty());
4852 // Skip the next N words.
4853 auto skip = [&](unsigned numWords) {
4854 assert(numWords > 0);
4856 // Try to merge into the previous byte. Since scans happen second, we
4857 // can't do this if it includes a scan.
4858 if (!buffer.empty() && !(buffer.back() & ScanMask)) {
4859 unsigned lastSkip = buffer.back() >> SkipShift;
4860 if (lastSkip < MaxNibble) {
4861 unsigned claimed = std::min(MaxNibble - lastSkip, numWords);
4862 numWords -= claimed;
4863 lastSkip += claimed;
4864 buffer.back() = (lastSkip << SkipShift);
4868 while (numWords >= MaxNibble) {
4869 buffer.push_back(MaxNibble << SkipShift);
4870 numWords -= MaxNibble;
4873 buffer.push_back(numWords << SkipShift);
4877 // Scan the next N words.
4878 auto scan = [&](unsigned numWords) {
4879 assert(numWords > 0);
4881 // Try to merge into the previous byte. Since scans happen second, we can
4882 // do this even if it includes a skip.
4883 if (!buffer.empty()) {
4884 unsigned lastScan = (buffer.back() & ScanMask) >> ScanShift;
4885 if (lastScan < MaxNibble) {
4886 unsigned claimed = std::min(MaxNibble - lastScan, numWords);
4887 numWords -= claimed;
4888 lastScan += claimed;
4889 buffer.back() = (buffer.back() & SkipMask) | (lastScan << ScanShift);
4893 while (numWords >= MaxNibble) {
4894 buffer.push_back(MaxNibble << ScanShift);
4895 numWords -= MaxNibble;
4898 buffer.push_back(numWords << ScanShift);
4902 // One past the end of the last scan.
4903 unsigned endOfLastScanInWords = 0;
4904 const CharUnits WordSize = CGM.getPointerSize();
4906 // Consider all the scan requests.
4907 for (auto &request : IvarsInfo) {
4908 CharUnits beginOfScan = request.Offset - InstanceBegin;
4910 // Ignore scan requests that don't start at an even multiple of the
4911 // word size. We can't encode them.
4912 if ((beginOfScan % WordSize) != 0) continue;
4914 // Ignore scan requests that start before the instance start.
4915 // This assumes that scans never span that boundary. The boundary
4916 // isn't the true start of the ivars, because in the fragile-ARC case
4917 // it's rounded up to word alignment, but the test above should leave
4918 // us ignoring that possibility.
4919 if (beginOfScan.isNegative()) {
4920 assert(request.Offset + request.SizeInWords * WordSize <= InstanceBegin);
4924 unsigned beginOfScanInWords = beginOfScan / WordSize;
4925 unsigned endOfScanInWords = beginOfScanInWords + request.SizeInWords;
4927 // If the scan starts some number of words after the last one ended,
4929 if (beginOfScanInWords > endOfLastScanInWords) {
4930 skip(beginOfScanInWords - endOfLastScanInWords);
4932 // Otherwise, start scanning where the last left off.
4934 beginOfScanInWords = endOfLastScanInWords;
4936 // If that leaves us with nothing to scan, ignore this request.
4937 if (beginOfScanInWords >= endOfScanInWords) continue;
4940 // Scan to the end of the request.
4941 assert(beginOfScanInWords < endOfScanInWords);
4942 scan(endOfScanInWords - beginOfScanInWords);
4943 endOfLastScanInWords = endOfScanInWords;
4947 return llvm::ConstantPointerNull::get(CGM.Int8PtrTy);
4949 // For GC layouts, emit a skip to the end of the allocation so that we
4950 // have precise information about the entire thing. This isn't useful
4951 // or necessary for the ARC-style layout strings.
4952 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
4953 unsigned lastOffsetInWords =
4954 (InstanceEnd - InstanceBegin + WordSize - CharUnits::One()) / WordSize;
4955 if (lastOffsetInWords > endOfLastScanInWords) {
4956 skip(lastOffsetInWords - endOfLastScanInWords);
4960 // Null terminate the string.
4961 buffer.push_back(0);
4963 bool isNonFragileABI = CGObjC.isNonFragileABI();
4965 llvm::GlobalVariable *Entry = CGObjC.CreateMetadataVar(
4967 llvm::ConstantDataArray::get(CGM.getLLVMContext(), buffer),
4968 (isNonFragileABI ? "__TEXT,__objc_classname,cstring_literals
"
4969 : "__TEXT,__cstring,cstring_literals
"),
4970 CharUnits::One(), true);
4971 return getConstantGEP(CGM.getLLVMContext(), Entry, 0, 0);
4991 CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD,
4992 CharUnits beginOffset, CharUnits endOffset,
4993 bool ForStrongLayout, bool HasMRCWeakIvars) {
4994 // If this is MRC, and we're either building a strong layout or there
4995 // are no weak ivars, bail out early.
4996 llvm::Type *PtrTy = CGM.Int8PtrTy;
4997 if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
4998 !CGM.getLangOpts().ObjCAutoRefCount &&
4999 (ForStrongLayout || !HasMRCWeakIvars))
5000 return llvm::Constant::getNullValue(PtrTy);
5002 const ObjCInterfaceDecl *OI = OMD->getClassInterface();
5003 SmallVector<const ObjCIvarDecl*, 32> ivars;
5005 // GC layout strings include the complete object layout, possibly
5006 // inaccurately in the non-fragile ABI; the runtime knows how to fix this
5009 // ARC layout strings only include the class's ivars. In non-fragile
5010 // runtimes, that means starting at InstanceStart, rounded up to word
5011 // alignment. In fragile runtimes, there's no InstanceStart, so it means
5012 // starting at the offset of the first ivar, rounded up to word alignment.
5014 // MRC weak layout strings follow the ARC style.
5015 CharUnits baseOffset;
5016 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
5017 for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();
5018 IVD; IVD = IVD->getNextIvar())
5019 ivars.push_back(IVD);
5021 if (isNonFragileABI()) {
5022 baseOffset = beginOffset; // InstanceStart
5023 } else if (!ivars.empty()) {
5025 CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivars[0]));
5027 baseOffset = CharUnits::Zero();
5030 baseOffset = baseOffset.alignTo(CGM.getPointerAlign());
5033 CGM.getContext().DeepCollectObjCIvars(OI, true, ivars);
5035 baseOffset = CharUnits::Zero();
5039 return llvm::Constant::getNullValue(PtrTy);
5041 IvarLayoutBuilder builder(CGM, baseOffset, endOffset, ForStrongLayout);
5043 builder.visitAggregate(ivars.begin(), ivars.end(), CharUnits::Zero(),
5044 [&](const ObjCIvarDecl *ivar) -> CharUnits {
5045 return CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivar));
5048 if (!builder.hasBitmapData())
5049 return llvm::Constant::getNullValue(PtrTy);
5051 llvm::SmallVector<unsigned char, 4> buffer;
5052 llvm::Constant *C = builder.buildBitmap(*this, buffer);
5054 if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
5055 printf("\n%s ivar layout
for class '%s':
",
5056 ForStrongLayout ? "strong
" : "weak
",
5057 OMD->getClassInterface()->getName().str().c_str());
5058 builder.dump(buffer);
5063 llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
5064 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
5066 // FIXME: Avoid std::string in "Sel.
getAsString()
"
5068 Entry = CreateMetadataVar(
5069 "OBJC_METH_VAR_NAME_
",
5070 llvm::ConstantDataArray::getString(VMContext, Sel.getAsString()),
5071 ((ObjCABI == 2) ? "__TEXT,__objc_methname,cstring_literals
"
5072 : "__TEXT,__cstring,cstring_literals
"),
5073 CharUnits::One(), true);
5075 return getConstantGEP(VMContext, Entry, 0, 0);
5078 // FIXME: Merge into a single cstring creation function.
5079 llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
5080 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
5083 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
5084 std::string TypeStr;
5085 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
5087 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
5090 Entry = CreateMetadataVar(
5091 "OBJC_METH_VAR_TYPE_
",
5092 llvm::ConstantDataArray::getString(VMContext, TypeStr),
5093 ((ObjCABI == 2) ? "__TEXT,__objc_methtype,cstring_literals
"
5094 : "__TEXT,__cstring,cstring_literals
"),
5095 CharUnits::One(), true);
5097 return getConstantGEP(VMContext, Entry, 0, 0);
5100 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D,
5102 std::string TypeStr;
5103 if (CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr, Extended))
5106 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
5109 Entry = CreateMetadataVar(
5110 "OBJC_METH_VAR_TYPE_
",
5111 llvm::ConstantDataArray::getString(VMContext, TypeStr),
5112 ((ObjCABI == 2) ? "__TEXT,__objc_methtype,cstring_literals
"
5113 : "__TEXT,__cstring,cstring_literals
"),
5114 CharUnits::One(), true);
5116 return getConstantGEP(VMContext, Entry, 0, 0);
5119 // FIXME: Merge into a single cstring creation function.
5120 llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
5121 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
5124 Entry = CreateMetadataVar(
5125 "OBJC_PROP_NAME_ATTR_
",
5126 llvm::ConstantDataArray::getString(VMContext, Ident->getName()),
5127 "__TEXT,__cstring,cstring_literals
", CharUnits::One(), true);
5129 return getConstantGEP(VMContext, Entry, 0, 0);
5132 // FIXME: Merge into a single cstring creation function.
5133 // FIXME: This Decl should be more precise.
5135 CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
5136 const Decl *Container) {
5137 std::string TypeStr;
5138 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr);
5139 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
5142 void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D,
5143 const ObjCContainerDecl *CD,
5144 SmallVectorImpl<char> &Name) {
5145 llvm::raw_svector_ostream OS(Name);
5146 assert (CD && "Missing container
decl in GetNameForMethod
");
5147 OS << '\01' << (D->isInstanceMethod() ? '-' : '+')
5148 << '[' << CD->getName();
5149 if (const ObjCCategoryImplDecl *CID =
5150 dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
5151 OS << '(' << *CID << ')';
5152 OS << ' ' << D->getSelector().getAsString() << ']';
5155 void CGObjCMac::FinishModule() {
5158 // Emit the dummy bodies for any protocols which were referenced but
5160 for (llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*>::iterator
5161 I = Protocols.begin(), e = Protocols.end(); I != e; ++I) {
5162 if (I->second->hasInitializer())
5165 llvm::Constant *Values[5];
5166 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
5167 Values[1] = GetClassName(I->first->getName());
5168 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
5169 Values[3] = Values[4] =
5170 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
5171 I->second->setInitializer(llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
5173 CGM.addCompilerUsedGlobal(I->second);
5176 // Add assembler directives to add lazy undefined symbol references
5177 // for classes which are referenced but not defined. This is
5178 // important for correct linker interaction.
5180 // FIXME: It would be nice if we had an LLVM construct for this.
5181 if (!LazySymbols.empty() || !DefinedSymbols.empty()) {
5182 SmallString<256> Asm;
5183 Asm += CGM.getModule().getModuleInlineAsm();
5184 if (!Asm.empty() && Asm.back() != '\n')
5187 llvm::raw_svector_ostream OS(Asm);
5188 for (llvm::SetVector<IdentifierInfo*>::iterator I = DefinedSymbols.begin(),
5189 e = DefinedSymbols.end(); I != e; ++I)
5190 OS << "\t.objc_class_name_
" << (*I)->getName() << "=0\n
"
5191 << "\t.globl .objc_class_name_
" << (*I)->getName() << "\n
";
5192 for (llvm::SetVector<IdentifierInfo*>::iterator I = LazySymbols.begin(),
5193 e = LazySymbols.end(); I != e; ++I) {
5194 OS << "\t.lazy_reference .objc_class_name_
" << (*I)->getName() << "\n
";
5197 for (size_t i = 0, e = DefinedCategoryNames.size(); i < e; ++i) {
5198 OS << "\t.objc_category_name_
" << DefinedCategoryNames[i] << "=0\n
"
5199 << "\t.globl .objc_category_name_
" << DefinedCategoryNames[i] << "\n
";
5202 CGM.getModule().setModuleInlineAsm(OS.str());
5206 CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
5207 : CGObjCCommonMac(cgm), ObjCTypes(cgm), ObjCEmptyCacheVar(nullptr),
5208 ObjCEmptyVtableVar(nullptr) {
5214 ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
5215 : VMContext(cgm.getLLVMContext()), CGM(cgm), ExternalProtocolPtrTy(nullptr)
5217 CodeGen::CodeGenTypes &Types = CGM.getTypes();
5218 ASTContext &Ctx = CGM.getContext();
5220 ShortTy = Types.ConvertType(Ctx.ShortTy);
5221 IntTy = Types.ConvertType(Ctx.IntTy);
5222 LongTy = Types.ConvertType(Ctx.LongTy);
5223 LongLongTy = Types.ConvertType(Ctx.LongLongTy);
5224 Int8PtrTy = CGM.Int8PtrTy;
5225 Int8PtrPtrTy = CGM.Int8PtrPtrTy;
5227 // arm64 targets use "int" ivar offset variables. All others,
5228 // including OS X x86_64 and Windows x86_64, use "long" ivar offsets.
5229 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::aarch64)
5230 IvarOffsetVarTy = IntTy;
5232 IvarOffsetVarTy = LongTy;
5234 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
5235 PtrObjectPtrTy = llvm::PointerType::getUnqual(ObjectPtrTy);
5236 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
5238 // I'm not sure I like this. The implicit coordination is a bit
5239 // gross. We should solve this in a reasonable fashion because this
5240 // is a pretty common task (match some runtime data structure with
5241 // an LLVM data structure).
5243 // FIXME: This is leaked.
5244 // FIXME: Merge with rewriter code?
5246 // struct _objc_super {
5250 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
5251 Ctx.getTranslationUnitDecl(),
5252 SourceLocation(), SourceLocation(),
5253 &Ctx.Idents.get("_objc_super
"));
5254 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5255 nullptr, Ctx.getObjCIdType(), nullptr, nullptr,
5256 false, ICIS_NoInit));
5257 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5258 nullptr, Ctx.getObjCClassType(), nullptr,
5259 nullptr, false, ICIS_NoInit));
5260 RD->completeDefinition();
5262 SuperCTy = Ctx.getTagDeclType(RD);
5263 SuperPtrCTy = Ctx.getPointerType(SuperCTy);
5265 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
5266 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
5270 // char *attributes;
5272 PropertyTy = llvm::StructType::create("struct._prop_t
",
5273 Int8PtrTy, Int8PtrTy, nullptr);
5275 // struct _prop_list_t {
5276 // uint32_t entsize; // sizeof(struct _prop_t)
5277 // uint32_t count_of_properties;
5278 // struct _prop_t prop_list[count_of_properties];
5281 llvm::StructType::create("struct._prop_list_t
", IntTy, IntTy,
5282 llvm::ArrayType::get(PropertyTy, 0), nullptr);
5283 // struct _prop_list_t *
5284 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
5286 // struct _objc_method {
5288 // char *method_type;
5291 MethodTy = llvm::StructType::create("struct._objc_method
",
5292 SelectorPtrTy, Int8PtrTy, Int8PtrTy,
5295 // struct _objc_cache *
5296 CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache
");
5297 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
5300 ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
5301 : ObjCCommonTypesHelper(cgm) {
5302 // struct _objc_method_description {
5306 MethodDescriptionTy =
5307 llvm::StructType::create("struct._objc_method_description
",
5308 SelectorPtrTy, Int8PtrTy, nullptr);
5310 // struct _objc_method_description_list {
5312 // struct _objc_method_description[1];
5314 MethodDescriptionListTy = llvm::StructType::create(
5315 "struct._objc_method_description_list
", IntTy,
5316 llvm::ArrayType::get(MethodDescriptionTy, 0), nullptr);
5318 // struct _objc_method_description_list *
5319 MethodDescriptionListPtrTy =
5320 llvm::PointerType::getUnqual(MethodDescriptionListTy);
5322 // Protocol description structures
5324 // struct _objc_protocol_extension {
5325 // uint32_t size; // sizeof(struct _objc_protocol_extension)
5326 // struct _objc_method_description_list *optional_instance_methods;
5327 // struct _objc_method_description_list *optional_class_methods;
5328 // struct _objc_property_list *instance_properties;
5329 // const char ** extendedMethodTypes;
5330 // struct _objc_property_list *class_properties;
5332 ProtocolExtensionTy =
5333 llvm::StructType::create("struct._objc_protocol_extension
",
5334 IntTy, MethodDescriptionListPtrTy,
5335 MethodDescriptionListPtrTy, PropertyListPtrTy,
5336 Int8PtrPtrTy, PropertyListPtrTy, nullptr);
5338 // struct _objc_protocol_extension *
5339 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
5341 // Handle recursive construction of Protocol and ProtocolList types
5344 llvm::StructType::create(VMContext, "struct._objc_protocol
");
5347 llvm::StructType::create(VMContext, "struct._objc_protocol_list
");
5348 ProtocolListTy->setBody(llvm::PointerType::getUnqual(ProtocolListTy),
5350 llvm::ArrayType::get(ProtocolTy, 0),
5353 // struct _objc_protocol {
5354 // struct _objc_protocol_extension *isa;
5355 // char *protocol_name;
5356 // struct _objc_protocol **_objc_protocol_list;
5357 // struct _objc_method_description_list *instance_methods;
5358 // struct _objc_method_description_list *class_methods;
5360 ProtocolTy->setBody(ProtocolExtensionPtrTy, Int8PtrTy,
5361 llvm::PointerType::getUnqual(ProtocolListTy),
5362 MethodDescriptionListPtrTy,
5363 MethodDescriptionListPtrTy,
5366 // struct _objc_protocol_list *
5367 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
5369 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
5371 // Class description structures
5373 // struct _objc_ivar {
5378 IvarTy = llvm::StructType::create("struct._objc_ivar
",
5379 Int8PtrTy, Int8PtrTy, IntTy, nullptr);
5381 // struct _objc_ivar_list *
5383 llvm::StructType::create(VMContext, "struct._objc_ivar_list
");
5384 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
5386 // struct _objc_method_list *
5388 llvm::StructType::create(VMContext, "struct._objc_method_list
");
5389 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
5391 // struct _objc_class_extension *
5393 llvm::StructType::create("struct._objc_class_extension
",
5394 IntTy, Int8PtrTy, PropertyListPtrTy, nullptr);
5395 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
5397 ClassTy = llvm::StructType::create(VMContext, "struct._objc_class
");
5399 // struct _objc_class {
5401 // Class super_class;
5405 // long instance_size;
5406 // struct _objc_ivar_list *ivars;
5407 // struct _objc_method_list *methods;
5408 // struct _objc_cache *cache;
5409 // struct _objc_protocol_list *protocols;
5410 // char *ivar_layout;
5411 // struct _objc_class_ext *ext;
5413 ClassTy->setBody(llvm::PointerType::getUnqual(ClassTy),
5414 llvm::PointerType::getUnqual(ClassTy),
5424 ClassExtensionPtrTy,
5427 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
5429 // struct _objc_category {
5430 // char *category_name;
5431 // char *class_name;
5432 // struct _objc_method_list *instance_method;
5433 // struct _objc_method_list *class_method;
5434 // struct _objc_protocol_list *protocols;
5435 // uint32_t size; // sizeof(struct _objc_category)
5436 // struct _objc_property_list *instance_properties;// category's @property
5437 // struct _objc_property_list *class_properties;
5440 llvm::StructType::create("struct._objc_category
",
5441 Int8PtrTy, Int8PtrTy, MethodListPtrTy,
5442 MethodListPtrTy, ProtocolListPtrTy,
5443 IntTy, PropertyListPtrTy, PropertyListPtrTy,
5446 // Global metadata structures
5448 // struct _objc_symtab {
5449 // long sel_ref_cnt;
5451 // short cls_def_cnt;
5452 // short cat_def_cnt;
5453 // char *defs[cls_def_cnt + cat_def_cnt];
5456 llvm::StructType::create("struct._objc_symtab
",
5457 LongTy, SelectorPtrTy, ShortTy, ShortTy,
5458 llvm::ArrayType::get(Int8PtrTy, 0), nullptr);
5459 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
5461 // struct _objc_module {
5463 // long size; // sizeof(struct _objc_module)
5465 // struct _objc_symtab* symtab;
5468 llvm::StructType::create("struct._objc_module
",
5469 LongTy, LongTy, Int8PtrTy, SymtabPtrTy, nullptr);
5472 // FIXME: This is the size of the setjmp buffer and should be target
5473 // specific. 18 is what's used on 32-bit X86.
5474 uint64_t SetJmpBufferSize = 18;
5477 llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4);
5480 llvm::StructType::create("struct._objc_exception_data
",
5481 llvm::ArrayType::get(CGM.Int32Ty,SetJmpBufferSize),
5482 StackPtrTy, nullptr);
5485 ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm)
5486 : ObjCCommonTypesHelper(cgm) {
5487 // struct _method_list_t {
5488 // uint32_t entsize; // sizeof(struct _objc_method)
5489 // uint32_t method_count;
5490 // struct _objc_method method_list[method_count];
5493 llvm::StructType::create("struct.__method_list_t
", IntTy, IntTy,
5494 llvm::ArrayType::get(MethodTy, 0), nullptr);
5495 // struct method_list_t *
5496 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy);
5498 // struct _protocol_t {
5500 // const char * const protocol_name;
5501 // const struct _protocol_list_t * protocol_list; // super protocols
5502 // const struct method_list_t * const instance_methods;
5503 // const struct method_list_t * const class_methods;
5504 // const struct method_list_t *optionalInstanceMethods;
5505 // const struct method_list_t *optionalClassMethods;
5506 // const struct _prop_list_t * properties;
5507 // const uint32_t size; // sizeof(struct _protocol_t)
5508 // const uint32_t flags; // = 0
5509 // const char ** extendedMethodTypes;
5510 // const char *demangledName;
5511 // const struct _prop_list_t * class_properties;
5514 // Holder for struct _protocol_list_t *
5515 ProtocolListnfABITy =
5516 llvm::StructType::create(VMContext, "struct._objc_protocol_list
");
5519 llvm::StructType::create("struct._protocol_t
", ObjectPtrTy, Int8PtrTy,
5520 llvm::PointerType::getUnqual(ProtocolListnfABITy),
5521 MethodListnfABIPtrTy, MethodListnfABIPtrTy,
5522 MethodListnfABIPtrTy, MethodListnfABIPtrTy,
5523 PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy,
5524 Int8PtrTy, PropertyListPtrTy,
5527 // struct _protocol_t*
5528 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy);
5530 // struct _protocol_list_t {
5531 // long protocol_count; // Note, this is 32/64 bit
5532 // struct _protocol_t *[protocol_count];
5534 ProtocolListnfABITy->setBody(LongTy,
5535 llvm::ArrayType::get(ProtocolnfABIPtrTy, 0),
5538 // struct _objc_protocol_list*
5539 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy);
5542 // unsigned [long] int *offset; // pointer to ivar offset location
5545 // uint32_t alignment;
5548 IvarnfABITy = llvm::StructType::create(
5549 "struct._ivar_t
", llvm::PointerType::getUnqual(IvarOffsetVarTy),
5550 Int8PtrTy, Int8PtrTy, IntTy, IntTy, nullptr);
5552 // struct _ivar_list_t {
5553 // uint32 entsize; // sizeof(struct _ivar_t)
5555 // struct _iver_t list[count];
5558 llvm::StructType::create("struct._ivar_list_t
", IntTy, IntTy,
5559 llvm::ArrayType::get(IvarnfABITy, 0), nullptr);
5561 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy);
5563 // struct _class_ro_t {
5564 // uint32_t const flags;
5565 // uint32_t const instanceStart;
5566 // uint32_t const instanceSize;
5567 // uint32_t const reserved; // only when building for 64bit targets
5568 // const uint8_t * const ivarLayout;
5569 // const char *const name;
5570 // const struct _method_list_t * const baseMethods;
5571 // const struct _objc_protocol_list *const baseProtocols;
5572 // const struct _ivar_list_t *const ivars;
5573 // const uint8_t * const weakIvarLayout;
5574 // const struct _prop_list_t * const properties;
5577 // FIXME. Add 'reserved' field in 64bit abi mode!
5578 ClassRonfABITy = llvm::StructType::create("struct._class_ro_t
",
5579 IntTy, IntTy, IntTy, Int8PtrTy,
5580 Int8PtrTy, MethodListnfABIPtrTy,
5581 ProtocolListnfABIPtrTy,
5583 Int8PtrTy, PropertyListPtrTy,
5586 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
5587 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
5588 ImpnfABITy = llvm::FunctionType::get(ObjectPtrTy, params, false)
5591 // struct _class_t {
5592 // struct _class_t *isa;
5593 // struct _class_t * const superclass;
5596 // struct class_ro_t *ro;
5599 ClassnfABITy = llvm::StructType::create(VMContext, "struct._class_t
");
5600 ClassnfABITy->setBody(llvm::PointerType::getUnqual(ClassnfABITy),
5601 llvm::PointerType::getUnqual(ClassnfABITy),
5603 llvm::PointerType::getUnqual(ImpnfABITy),
5604 llvm::PointerType::getUnqual(ClassRonfABITy),
5607 // LLVM for struct _class_t *
5608 ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy);
5610 // struct _category_t {
5611 // const char * const name;
5612 // struct _class_t *const cls;
5613 // const struct _method_list_t * const instance_methods;
5614 // const struct _method_list_t * const class_methods;
5615 // const struct _protocol_list_t * const protocols;
5616 // const struct _prop_list_t * const properties;
5617 // const struct _prop_list_t * const class_properties;
5618 // const uint32_t size;
5620 CategorynfABITy = llvm::StructType::create("struct._category_t
",
5621 Int8PtrTy, ClassnfABIPtrTy,
5622 MethodListnfABIPtrTy,
5623 MethodListnfABIPtrTy,
5624 ProtocolListnfABIPtrTy,
5630 // New types for nonfragile abi messaging.
5631 CodeGen::CodeGenTypes &Types = CGM.getTypes();
5632 ASTContext &Ctx = CGM.getContext();
5634 // MessageRefTy - LLVM for:
5635 // struct _message_ref_t {
5640 // First the clang type for struct _message_ref_t
5641 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
5642 Ctx.getTranslationUnitDecl(),
5643 SourceLocation(), SourceLocation(),
5644 &Ctx.Idents.get("_message_ref_t
"));
5645 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5646 nullptr, Ctx.VoidPtrTy, nullptr, nullptr, false,
5648 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5649 nullptr, Ctx.getObjCSelType(), nullptr, nullptr,
5650 false, ICIS_NoInit));
5651 RD->completeDefinition();
5653 MessageRefCTy = Ctx.getTagDeclType(RD);
5654 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy);
5655 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy));
5657 // MessageRefPtrTy - LLVM for struct _message_ref_t*
5658 MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy);
5660 // SuperMessageRefTy - LLVM for:
5661 // struct _super_message_ref_t {
5662 // SUPER_IMP messenger;
5666 llvm::StructType::create("struct._super_message_ref_t
",
5667 ImpnfABITy, SelectorPtrTy, nullptr);
5669 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
5670 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy);
5673 // struct objc_typeinfo {
5674 // const void** vtable; // objc_ehtype_vtable + 2
5675 // const char* name; // c++ typeinfo string
5679 llvm::StructType::create("struct._objc_typeinfo
",
5680 llvm::PointerType::getUnqual(Int8PtrTy),
5681 Int8PtrTy, ClassnfABIPtrTy, nullptr);
5682 EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy);
5685 llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
5686 FinishNonFragileABIModule();
5691 void CGObjCNonFragileABIMac::AddModuleClassList(
5692 ArrayRef<llvm::GlobalValue *> Container, StringRef SymbolName,
5693 StringRef SectionName) {
5694 unsigned NumClasses = Container.size();
5699 SmallVector<llvm::Constant*, 8> Symbols(NumClasses);
5700 for (unsigned i=0; i<NumClasses; i++)
5701 Symbols[i] = llvm::ConstantExpr::getBitCast(Container[i],
5702 ObjCTypes.Int8PtrTy);
5703 llvm::Constant *Init =
5704 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
5708 llvm::GlobalVariable *GV =
5709 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
5710 llvm::GlobalValue::PrivateLinkage,
5713 GV->setAlignment(CGM.getDataLayout().getABITypeAlignment(Init->getType()));
5714 GV->setSection(SectionName);
5715 CGM.addCompilerUsedGlobal(GV);
5718 void CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
5719 // nonfragile abi has no module definition.
5721 // Build list of all implemented class addresses in array
5722 // L_OBJC_LABEL_CLASS_$.
5724 for (unsigned i=0, NumClasses=ImplementedClasses.size(); i<NumClasses; i++) {
5725 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
5727 if (ObjCImplementationDecl *IMP = ID->getImplementation())
5728 // We are implementing a weak imported interface. Give it external linkage
5729 if (ID->isWeakImported() && !IMP->isWeakImported()) {
5730 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
5731 DefinedMetaClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
5735 AddModuleClassList(DefinedClasses, "OBJC_LABEL_CLASS_$
",
5736 "__DATA, __objc_classlist, regular, no_dead_strip
");
5738 AddModuleClassList(DefinedNonLazyClasses, "OBJC_LABEL_NONLAZY_CLASS_$
",
5739 "__DATA, __objc_nlclslist, regular, no_dead_strip
");
5741 // Build list of all implemented category addresses in array
5742 // L_OBJC_LABEL_CATEGORY_$.
5743 AddModuleClassList(DefinedCategories, "OBJC_LABEL_CATEGORY_$
",
5744 "__DATA, __objc_catlist, regular, no_dead_strip
");
5745 AddModuleClassList(DefinedNonLazyCategories, "OBJC_LABEL_NONLAZY_CATEGORY_$
",
5746 "__DATA, __objc_nlcatlist, regular, no_dead_strip
");
5755 bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
5756 // At various points we've experimented with using vtable-based
5757 // dispatch for all methods.
5758 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
5759 case CodeGenOptions::Legacy:
5761 case CodeGenOptions::NonLegacy:
5763 case CodeGenOptions::Mixed:
5767 // If so, see whether this selector is in the white-list of things which must
5768 // use the new dispatch convention. We lazily build a dense set for this.
5769 if (VTableDispatchMethods.empty()) {
5770 VTableDispatchMethods.insert(GetNullarySelector("alloc
"));
5771 VTableDispatchMethods.insert(GetNullarySelector("class"));
5772 VTableDispatchMethods.insert(GetNullarySelector("self"));
5773 VTableDispatchMethods.insert(GetNullarySelector("isFlipped
"));
5774 VTableDispatchMethods.insert(GetNullarySelector("length"));
5775 VTableDispatchMethods.insert(GetNullarySelector("count
"));
5777 // These are vtable-based if GC is disabled.
5778 // Optimistically use vtable dispatch for hybrid compiles.
5779 if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) {
5780 VTableDispatchMethods.insert(GetNullarySelector("retain
"));
5781 VTableDispatchMethods.insert(GetNullarySelector("release
"));
5782 VTableDispatchMethods.insert(GetNullarySelector("autorelease
"));
5785 VTableDispatchMethods.insert(GetUnarySelector("allocWithZone
"));
5786 VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass
"));
5787 VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector
"));
5788 VTableDispatchMethods.insert(GetUnarySelector("objectForKey
"));
5789 VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex
"));
5790 VTableDispatchMethods.insert(GetUnarySelector("isEqualToString
"));
5791 VTableDispatchMethods.insert(GetUnarySelector("isEqual
"));
5793 // These are vtable-based if GC is enabled.
5794 // Optimistically use vtable dispatch for hybrid compiles.
5795 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
5796 VTableDispatchMethods.insert(GetNullarySelector("hash
"));
5797 VTableDispatchMethods.insert(GetUnarySelector("addObject
"));
5799 // "countByEnumeratingWithState:objects:count
"
5800 IdentifierInfo *KeyIdents[] = {
5801 &CGM.getContext().Idents.get("countByEnumeratingWithState
"),
5802 &CGM.getContext().Idents.get("objects
"),
5803 &CGM.getContext().Idents.get("count
")
5805 VTableDispatchMethods.insert(
5806 CGM.getContext().Selectors.getSelector(3, KeyIdents));
5810 return VTableDispatchMethods.count(Sel);
5828 llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
5830 unsigned InstanceStart,
5831 unsigned InstanceSize,
5832 const ObjCImplementationDecl *ID) {
5833 std::string ClassName = ID->getObjCRuntimeNameAsString();
5834 llvm::Constant *Values[10]; // 11 for 64bit targets!
5836 CharUnits beginInstance = CharUnits::fromQuantity(InstanceStart);
5837 CharUnits endInstance = CharUnits::fromQuantity(InstanceSize);
5839 bool hasMRCWeak = false;
5840 if (CGM.getLangOpts().ObjCAutoRefCount)
5841 flags |= NonFragileABI_Class_CompiledByARC;
5842 else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))
5843 flags |= NonFragileABI_Class_HasMRCWeakIvars;
5845 Values[ 0] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags);
5846 Values[ 1] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceStart);
5847 Values[ 2] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceSize);
5848 // FIXME. For 64bit targets add 0 here.
5849 Values[ 3] = (flags & NonFragileABI_Class_Meta)
5850 ? GetIvarLayoutName(nullptr, ObjCTypes)
5851 : BuildStrongIvarLayout(ID, beginInstance, endInstance);
5852 Values[ 4] = GetClassName(ID->getObjCRuntimeNameAsString());
5853 // const struct _method_list_t * const baseMethods;
5854 std::vector<llvm::Constant*> Methods;
5855 std::string MethodListName("\01l_OBJC_$_
");
5856 if (flags & NonFragileABI_Class_Meta) {
5857 MethodListName += "CLASS_METHODS_
";
5858 MethodListName += ID->getObjCRuntimeNameAsString();
5859 for (const auto *I : ID->class_methods())
5860 // Class methods should always be defined.
5861 Methods.push_back(GetMethodConstant(I));
5863 MethodListName += "INSTANCE_METHODS_
";
5864 MethodListName += ID->getObjCRuntimeNameAsString();
5865 for (const auto *I : ID->instance_methods())
5866 // Instance methods should always be defined.
5867 Methods.push_back(GetMethodConstant(I));
5869 for (const auto *PID : ID->property_impls()) {
5870 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){
5871 ObjCPropertyDecl *PD = PID->getPropertyDecl();
5873 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
5874 if (llvm::Constant *C = GetMethodConstant(MD))
5875 Methods.push_back(C);
5876 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
5877 if (llvm::Constant *C = GetMethodConstant(MD))
5878 Methods.push_back(C);
5882 Values[ 5] = EmitMethodList(MethodListName,
5883 "__DATA, __objc_const
", Methods);
5885 const ObjCInterfaceDecl *OID = ID->getClassInterface();
5886 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer
");
5887 Values[ 6] = EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_
"
5888 + OID->getObjCRuntimeNameAsString(),
5889 OID->all_referenced_protocol_begin(),
5890 OID->all_referenced_protocol_end());
5892 if (flags & NonFragileABI_Class_Meta) {
5893 Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
5894 Values[ 8] = GetIvarLayoutName(nullptr, ObjCTypes);
5895 Values[ 9] = EmitPropertyList(
5896 "\01l_OBJC_$_CLASS_PROP_LIST_
" + ID->getObjCRuntimeNameAsString(),
5897 ID, ID->getClassInterface(), ObjCTypes, true);
5899 Values[ 7] = EmitIvarList(ID);
5900 Values[ 8] = BuildWeakIvarLayout(ID, beginInstance, endInstance,
5902 Values[ 9] = EmitPropertyList(
5903 "\01l_OBJC_$_PROP_LIST_
" + ID->getObjCRuntimeNameAsString(),
5904 ID, ID->getClassInterface(), ObjCTypes, false);
5906 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy,
5908 llvm::GlobalVariable *CLASS_RO_GV =
5909 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassRonfABITy, false,
5910 llvm::GlobalValue::PrivateLinkage,
5912 (flags & NonFragileABI_Class_Meta) ?
5913 std::string("\01l_OBJC_METACLASS_RO_$_
")+ClassName :
5914 std::string("\01l_OBJC_CLASS_RO_$_
")+ClassName);
5915 CLASS_RO_GV->setAlignment(
5916 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassRonfABITy));
5917 CLASS_RO_GV->setSection("__DATA, __objc_const
");
5932 llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassMetaData(
5933 const std::string &ClassName, llvm::Constant *IsAGV, llvm::Constant *SuperClassGV,
5934 llvm::Constant *ClassRoGV, bool HiddenVisibility, bool Weak) {
5935 llvm::Constant *Values[] = {
5938 ObjCEmptyCacheVar, // &ObjCEmptyCacheVar
5939 ObjCEmptyVtableVar, // &ObjCEmptyVtableVar
5940 ClassRoGV // &CLASS_RO_GV
5943 Values[1] = llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy);
5945 Values[3] = llvm::Constant::getNullValue(
5946 llvm::PointerType::getUnqual(ObjCTypes.ImpnfABITy));
5947 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy,
5949 llvm::GlobalVariable *GV = GetClassGlobal(ClassName, Weak);
5950 GV->setInitializer(Init);
5951 GV->setSection("__DATA, __objc_data
");
5953 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassnfABITy));
5954 if (!CGM.getTriple().isOSBinFormatCOFF())
5955 if (HiddenVisibility)
5956 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
5961 CGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
5962 return OD->getClassMethod(GetNullarySelector("load
")) != nullptr;
5965 void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
5966 uint32_t &InstanceStart,
5967 uint32_t &InstanceSize) {
5968 const ASTRecordLayout &RL =
5969 CGM.getContext().getASTObjCImplementationLayout(OID);
5971 // InstanceSize is really instance end.
5972 InstanceSize = RL.getDataSize().getQuantity();
5974 // If there are no fields, the start is the same as the end.
5975 if (!RL.getFieldCount())
5976 InstanceStart = InstanceSize;
5978 InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth();
5981 static llvm::GlobalValue::DLLStorageClassTypes getStorage(CodeGenModule &CGM,
5983 IdentifierInfo &II = CGM.getContext().Idents.get(Name);
5984 TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl();
5985 DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl);
5987 const VarDecl *VD = nullptr;
5988 for (const auto &Result : DC->lookup(&II))
5989 if ((VD = dyn_cast<VarDecl>(Result)))
5993 return llvm::GlobalValue::DLLImportStorageClass;
5994 if (VD->hasAttr<DLLExportAttr>())
5995 return llvm::GlobalValue::DLLExportStorageClass;
5996 if (VD->hasAttr<DLLImportAttr>())
5997 return llvm::GlobalValue::DLLImportStorageClass;
5998 return llvm::GlobalValue::DefaultStorageClass;
6001 void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
6002 if (!ObjCEmptyCacheVar) {
6004 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CacheTy, false,
6005 llvm::GlobalValue::ExternalLinkage, nullptr,
6006 "_objc_empty_cache
");
6007 if (CGM.getTriple().isOSBinFormatCOFF())
6008 ObjCEmptyCacheVar->setDLLStorageClass(getStorage(CGM, "_objc_empty_cache
"));
6010 // Only OS X with deployment version <10.9 use the empty vtable symbol
6011 const llvm::Triple &Triple = CGM.getTarget().getTriple();
6012 if (Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 9))
6013 ObjCEmptyVtableVar =
6014 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ImpnfABITy, false,
6015 llvm::GlobalValue::ExternalLinkage, nullptr,
6016 "_objc_empty_vtable
");
6019 // FIXME: Is this correct (that meta class size is never computed)?
6020 uint32_t InstanceStart =
6021 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy);
6022 uint32_t InstanceSize = InstanceStart;
6023 uint32_t flags = NonFragileABI_Class_Meta;
6025 llvm::GlobalVariable *SuperClassGV, *IsAGV;
6027 StringRef ClassName = ID->getObjCRuntimeNameAsString();
6028 const auto *CI = ID->getClassInterface();
6029 assert(CI && "CGObjCNonFragileABIMac::GenerateClass -
class is 0");
6032 bool classIsHidden = (CGM.
getTriple().isOSBinFormatCOFF())
6033 ? !CI->hasAttr<DLLExportAttr>()
6046 if (!CI->getSuperClass()) {
6050 SuperClassGV = GetClassGlobal((getClassSymbolPrefix() + ClassName).str(),
6051 CI->isWeakImported());
6052 if (CGM.
getTriple().isOSBinFormatCOFF())
6053 if (CI->hasAttr<DLLImportAttr>())
6054 SuperClassGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
6056 IsAGV = GetClassGlobal((getMetaclassSymbolPrefix() + ClassName).str(),
6057 CI->isWeakImported());
6058 if (CGM.
getTriple().isOSBinFormatCOFF())
6059 if (CI->hasAttr<DLLImportAttr>())
6060 IsAGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
6069 StringRef SuperClassName = Super->getObjCRuntimeNameAsString();
6071 IsAGV = GetClassGlobal((getMetaclassSymbolPrefix() + RootClassName).str(),
6072 Root->isWeakImported());
6073 if (CGM.
getTriple().isOSBinFormatCOFF())
6074 if (Root->hasAttr<DLLImportAttr>())
6075 IsAGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
6079 GetClassGlobal((getMetaclassSymbolPrefix() + SuperClassName).str(),
6080 Super->isWeakImported());
6081 if (CGM.
getTriple().isOSBinFormatCOFF())
6082 if (Super->hasAttr<DLLImportAttr>())
6083 SuperClassGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
6086 llvm::GlobalVariable *CLASS_RO_GV =
6087 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
6089 llvm::GlobalVariable *MetaTClass =
6090 BuildClassMetaData((getMetaclassSymbolPrefix() + ClassName).str(), IsAGV,
6091 SuperClassGV, CLASS_RO_GV, classIsHidden,
6092 CI->isWeakImported());
6093 if (CGM.
getTriple().isOSBinFormatCOFF())
6094 if (CI->hasAttr<DLLExportAttr>())
6095 MetaTClass->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
6096 DefinedMetaClasses.push_back(MetaTClass);
6119 if (!CI->getSuperClass()) {
6121 SuperClassGV =
nullptr;
6124 const auto *Super = CI->getSuperClass();
6125 StringRef SuperClassName = Super->getObjCRuntimeNameAsString();
6128 GetClassGlobal((getClassSymbolPrefix() + SuperClassName).str(),
6129 Super->isWeakImported());
6130 if (CGM.
getTriple().isOSBinFormatCOFF())
6131 if (Super->hasAttr<DLLImportAttr>())
6132 SuperClassGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
6135 GetClassSizeInfo(ID, InstanceStart, InstanceSize);
6137 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
6139 llvm::GlobalVariable *ClassMD =
6140 BuildClassMetaData((getClassSymbolPrefix() + ClassName).str(), MetaTClass,
6141 SuperClassGV, CLASS_RO_GV, classIsHidden,
6142 CI->isWeakImported());
6143 if (CGM.
getTriple().isOSBinFormatCOFF())
6144 if (CI->hasAttr<DLLExportAttr>())
6145 ClassMD->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
6146 DefinedClasses.push_back(ClassMD);
6147 ImplementedClasses.push_back(CI);
6150 if (ImplementationIsNonLazy(ID))
6151 DefinedNonLazyClasses.push_back(ClassMD);
6155 GetInterfaceEHType(CI,
true);
6157 MethodDefinitions.clear();
6174 llvm::Constant *Init =
6175 llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD),
6176 ObjCTypes.getExternalProtocolPtrTy());
6178 std::string ProtocolName(
"\01l_OBJC_PROTOCOL_REFERENCE_$_");
6183 llvm::GlobalVariable *PTGV = CGM.
getModule().getGlobalVariable(ProtocolName);
6186 PTGV =
new llvm::GlobalVariable(
6188 Init->getType(),
false,
6189 llvm::GlobalValue::WeakAnyLinkage,
6192 PTGV->setSection(
"__DATA, __objc_protorefs, coalesced, no_dead_strip");
6213 const char *Prefix =
"\01l_OBJC_$_CATEGORY_";
6217 ExtCatName +=
"_$_";
6223 llvm::Constant *Values[8];
6226 llvm::GlobalVariable *ClassGV =
6227 GetClassGlobal(ExtClassName.str(), Interface->isWeakImported());
6229 Values[1] = ClassGV;
6230 std::vector<llvm::Constant*> Methods;
6233 MethodListName +=
"INSTANCE_METHODS_";
6235 MethodListName +=
"_$_";
6236 MethodListName += OCD->
getName();
6240 Methods.push_back(GetMethodConstant(I));
6242 Values[2] = EmitMethodList(MethodListName.str(),
6243 "__DATA, __objc_const",
6246 MethodListName = Prefix;
6247 MethodListName +=
"CLASS_METHODS_";
6249 MethodListName +=
"_$_";
6255 Methods.push_back(GetMethodConstant(I));
6257 Values[3] = EmitMethodList(MethodListName.str(),
6258 "__DATA, __objc_const",
6266 Values[4] = EmitProtocolList(
"\01l_OBJC_CATEGORY_PROTOCOLS_$_"
6268 + Category->getName(),
6269 Category->protocol_begin(),
6270 Category->protocol_end());
6271 Values[5] = EmitPropertyList(
"\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
6273 Values[6] = EmitPropertyList(
"\01l_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(),
6276 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
6277 Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
6278 Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
6281 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.CategorynfABITy);
6282 Values[7] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6284 llvm::Constant *Init =
6285 llvm::ConstantStruct::get(ObjCTypes.CategorynfABITy,
6287 llvm::GlobalVariable *GCATV
6288 =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.CategorynfABITy,
6290 llvm::GlobalValue::PrivateLinkage,
6293 GCATV->setAlignment(
6294 CGM.
getDataLayout().getABITypeAlignment(ObjCTypes.CategorynfABITy));
6295 GCATV->setSection(
"__DATA, __objc_const");
6297 DefinedCategories.push_back(GCATV);
6300 if (ImplementationIsNonLazy(OCD))
6301 DefinedNonLazyCategories.push_back(GCATV);
6303 MethodDefinitions.clear();
6309 llvm::Constant *CGObjCNonFragileABIMac::GetMethodConstant(
6311 llvm::Function *Fn = GetMethodDefinition(MD);
6315 llvm::Constant *Method[] = {
6316 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->
getSelector()),
6317 ObjCTypes.SelectorPtrTy),
6318 GetMethodVarType(MD),
6319 llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy)
6321 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
6332 CGObjCNonFragileABIMac::EmitMethodList(Twine Name, StringRef Section,
6335 if (Methods.empty())
6336 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
6338 llvm::Constant *Values[3];
6340 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.MethodTy);
6341 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6343 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
6344 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
6346 Values[2] = llvm::ConstantArray::get(AT, Methods);
6347 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
6349 llvm::GlobalVariable *GV =
6350 new llvm::GlobalVariable(CGM.
getModule(), Init->getType(),
false,
6351 llvm::GlobalValue::PrivateLinkage, Init,
Name);
6352 GV->setAlignment(CGM.
getDataLayout().getABITypeAlignment(Init->getType()));
6353 GV->setSection(Section);
6355 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListnfABIPtrTy);
6360 llvm::GlobalVariable *
6368 llvm::GlobalVariable *IvarOffsetGV = CGM.
getModule().getGlobalVariable(Name);
6369 if (!IvarOffsetGV) {
6371 new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.IvarOffsetVarTy,
6373 nullptr, Name.str());
6374 if (CGM.
getTriple().isOSBinFormatCOFF()) {
6375 bool IsPrivateOrPackage =
6379 if (ID->hasAttr<DLLExportAttr>() && !IsPrivateOrPackage)
6380 IvarOffsetGV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
6381 else if (ID->hasAttr<DLLImportAttr>())
6382 IvarOffsetGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
6385 return IvarOffsetGV;
6391 unsigned long int Offset) {
6392 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
6393 IvarOffsetGV->setInitializer(
6394 llvm::ConstantInt::get(ObjCTypes.IvarOffsetVarTy, Offset));
6395 IvarOffsetGV->setAlignment(
6396 CGM.
getDataLayout().getABITypeAlignment(ObjCTypes.IvarOffsetVarTy));
6398 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
6409 IvarOffsetGV->setSection(
"__DATA, __objc_ivar");
6410 return IvarOffsetGV;
6430 llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
6433 std::vector<llvm::Constant*> Ivars;
6436 assert(OID &&
"CGObjCNonFragileABIMac::EmitIvarList - null interface");
6443 if (!IVD->getDeclName())
6445 llvm::Constant *Ivar[5];
6447 ComputeIvarBaseOffset(CGM, ID, IVD));
6448 Ivar[1] = GetMethodVarName(IVD->getIdentifier());
6449 Ivar[2] = GetMethodVarType(IVD);
6450 llvm::Type *FieldTy =
6452 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(FieldTy);
6454 IVD->getType().getTypePtr()) >> 3;
6455 Align = llvm::Log2_32(Align);
6456 Ivar[3] = llvm::ConstantInt::get(ObjCTypes.IntTy, Align);
6462 Ivar[4] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6463 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarnfABITy, Ivar));
6467 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
6469 llvm::Constant *Values[3];
6470 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.IvarnfABITy);
6471 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6472 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
6473 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarnfABITy,
6475 Values[2] = llvm::ConstantArray::get(AT, Ivars);
6476 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
6477 const char *Prefix =
"\01l_OBJC_$_INSTANCE_VARIABLES_";
6478 llvm::GlobalVariable *GV =
6479 new llvm::GlobalVariable(CGM.
getModule(), Init->getType(),
false,
6480 llvm::GlobalValue::PrivateLinkage,
6485 GV->setSection(
"__DATA, __objc_const");
6488 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy);
6491 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(
6493 llvm::GlobalVariable *&Entry = Protocols[PD->
getIdentifier()];
6500 new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolnfABITy,
6528 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
6530 llvm::GlobalVariable *Entry = Protocols[PD->
getIdentifier()];
6533 if (Entry && Entry->hasInitializer())
6541 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
6542 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
6543 std::vector<llvm::Constant*> MethodTypesExt, OptMethodTypesExt;
6545 llvm::Constant *C = GetMethodDescriptionConstant(MD);
6547 return GetOrEmitProtocolRef(PD);
6550 OptInstanceMethods.push_back(C);
6551 OptMethodTypesExt.push_back(GetMethodVarType(MD,
true));
6553 InstanceMethods.push_back(C);
6554 MethodTypesExt.push_back(GetMethodVarType(MD,
true));
6559 llvm::Constant *C = GetMethodDescriptionConstant(MD);
6561 return GetOrEmitProtocolRef(PD);
6564 OptClassMethods.push_back(C);
6565 OptMethodTypesExt.push_back(GetMethodVarType(MD,
true));
6567 ClassMethods.push_back(C);
6568 MethodTypesExt.push_back(GetMethodVarType(MD,
true));
6572 MethodTypesExt.insert(MethodTypesExt.end(),
6573 OptMethodTypesExt.begin(), OptMethodTypesExt.end());
6575 llvm::Constant *Values[13];
6577 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy);
6583 Values[3] = EmitMethodList(
"\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_"
6585 "__DATA, __objc_const",
6587 Values[4] = EmitMethodList(
"\01l_OBJC_$_PROTOCOL_CLASS_METHODS_"
6589 "__DATA, __objc_const",
6591 Values[5] = EmitMethodList(
"\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_"
6593 "__DATA, __objc_const",
6594 OptInstanceMethods);
6595 Values[6] = EmitMethodList(
"\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_"
6597 "__DATA, __objc_const",
6599 Values[7] = EmitPropertyList(
6601 nullptr, PD, ObjCTypes,
false);
6603 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
6604 Values[8] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6605 Values[9] = llvm::Constant::getNullValue(ObjCTypes.IntTy);
6606 Values[10] = EmitProtocolMethodTypes(
"\01l_OBJC_$_PROTOCOL_METHOD_TYPES_"
6608 MethodTypesExt, ObjCTypes);
6610 Values[11] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
6612 Values[12] = EmitPropertyList(
6614 nullptr, PD, ObjCTypes,
true);
6616 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolnfABITy,
6621 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
6622 Entry->setInitializer(Init);
6625 new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolnfABITy,
6626 false, llvm::GlobalValue::WeakAnyLinkage, Init,
6628 Entry->setAlignment(
6629 CGM.
getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABITy));
6638 llvm::GlobalVariable *PTGV =
6639 new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolnfABIPtrTy,
6640 false, llvm::GlobalValue::WeakAnyLinkage, Entry,
6643 CGM.
getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy));
6644 PTGV->setSection(
"__DATA, __objc_protolist, coalesced, no_dead_strip");
6659 CGObjCNonFragileABIMac::EmitProtocolList(Twine Name,
6666 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
6670 Name.toVector(TmpName);
6671 llvm::GlobalVariable *GV =
6672 CGM.
getModule().getGlobalVariable(TmpName.str(),
true);
6674 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy);
6677 ProtocolRefs.push_back(GetProtocolRef(*begin));
6680 ProtocolRefs.push_back(llvm::Constant::getNullValue(
6681 ObjCTypes.ProtocolnfABIPtrTy));
6683 llvm::Constant *Values[2];
6685 llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
6687 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolnfABIPtrTy,
6688 ProtocolRefs.size()),
6691 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
6692 GV =
new llvm::GlobalVariable(CGM.
getModule(), Init->getType(),
false,
6693 llvm::GlobalValue::PrivateLinkage,
6695 GV->setSection(
"__DATA, __objc_const");
6699 return llvm::ConstantExpr::getBitCast(GV,
6700 ObjCTypes.ProtocolListnfABIPtrTy);
6711 CGObjCNonFragileABIMac::GetMethodDescriptionConstant(
const ObjCMethodDecl *MD) {
6712 llvm::Constant *Desc[3];
6714 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->
getSelector()),
6715 ObjCTypes.SelectorPtrTy);
6716 Desc[1] = GetMethodVarType(MD);
6721 Desc[2] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
6722 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Desc);
6731 LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
6736 unsigned CVRQualifiers) {
6738 llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
6739 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
6743 llvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset(
6747 llvm::Value *IvarOffsetValue = ObjCIvarOffsetVariable(Interface, Ivar);
6750 if (IsIvarOffsetKnownIdempotent(CGF, Ivar))
6751 cast<llvm::LoadInst>(IvarOffsetValue)
6752 ->setMetadata(CGM.
getModule().getMDKindID(
"invariant.load"),
6753 llvm::MDNode::get(VMContext, None));
6758 if (ObjCTypes.IvarOffsetVarTy == ObjCTypes.IntTy)
6759 IvarOffsetValue = CGF.
Builder.CreateIntCast(
6760 IvarOffsetValue, ObjCTypes.LongTy,
true,
"ivar.conv");
6761 return IvarOffsetValue;
6764 static void appendSelectorForMessageRefTable(std::string &buffer,
6771 for (
unsigned i = 0, e = selector.
getNumArgs(); i != e; ++i) {
6803 args.
add(RValue::get(arg0), arg0Type);
6807 args.
add(RValue::get(
nullptr), ObjCTypes.MessageRefCPtrTy);
6809 args.insert(args.end(), formalArgs.begin(), formalArgs.end());
6811 MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);
6813 NullReturnState nullReturn;
6822 llvm::Constant *fn =
nullptr;
6823 std::string messageRefName(
"\01l_");
6826 fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
6827 messageRefName +=
"objc_msgSendSuper2_stret_fixup";
6829 nullReturn.init(CGF, arg0);
6830 fn = ObjCTypes.getMessageSendStretFixupFn();
6831 messageRefName +=
"objc_msgSend_stret_fixup";
6834 fn = ObjCTypes.getMessageSendFpretFixupFn();
6835 messageRefName +=
"objc_msgSend_fpret_fixup";
6838 fn = ObjCTypes.getMessageSendSuper2FixupFn();
6839 messageRefName +=
"objc_msgSendSuper2_fixup";
6841 fn = ObjCTypes.getMessageSendFixupFn();
6842 messageRefName +=
"objc_msgSend_fixup";
6845 assert(fn &&
"CGObjCNonFragileABIMac::EmitMessageSend");
6846 messageRefName +=
'_';
6850 appendSelectorForMessageRefTable(messageRefName, selector);
6852 llvm::GlobalVariable *messageRef
6853 = CGM.
getModule().getGlobalVariable(messageRefName);
6856 llvm::Constant *values[] = { fn, GetMethodVarName(selector) };
6857 llvm::Constant *init = llvm::ConstantStruct::getAnon(values);
6858 messageRef =
new llvm::GlobalVariable(CGM.
getModule(),
6861 llvm::GlobalValue::WeakAnyLinkage,
6865 messageRef->setAlignment(16);
6866 messageRef->setSection(
"__DATA, __objc_msgrefs, coalesced");
6869 bool requiresnullCheck =
false;
6871 for (
const auto *ParamDecl : method->
parameters()) {
6872 if (ParamDecl->hasAttr<NSConsumedAttr>()) {
6873 if (!nullReturn.NullBB)
6874 nullReturn.init(CGF, arg0);
6875 requiresnullCheck =
true;
6894 RValue result = CGF.
EmitCall(MSI.CallInfo, callee, returnSlot, args);
6895 return nullReturn.complete(CGF, result, resultType, formalArgs,
6896 requiresnullCheck ? method :
nullptr);
6909 return isVTableDispatchedSelector(Sel)
6910 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
6912 false, CallArgs, Method)
6913 : EmitMessageSend(CGF, Return, ResultType,
6914 EmitSelector(CGF, Sel),
6916 false, CallArgs, Method, Class, ObjCTypes);
6919 llvm::GlobalVariable *
6920 CGObjCNonFragileABIMac::GetClassGlobal(StringRef Name,
bool Weak) {
6921 llvm::GlobalValue::LinkageTypes L =
6922 Weak ? llvm::GlobalValue::ExternalWeakLinkage
6925 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name);
6928 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassnfABITy,
6929 false, L,
nullptr,
Name);
6931 assert(GV->getLinkage() == L);
6940 llvm::GlobalVariable *&Entry = ClassReferences[II];
6944 std::string ClassName = (getClassSymbolPrefix() +
Name).str();
6945 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName, Weak);
6946 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassnfABIPtrTy,
6947 false, llvm::GlobalValue::PrivateLinkage,
6948 ClassGV,
"OBJC_CLASSLIST_REFERENCES_$_");
6950 Entry->setSection(
"__DATA, __objc_classrefs, regular, no_dead_strip");
6960 if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
6961 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
6963 return EmitClassRefFromId(CGF, ID->
getIdentifier(), ID->isWeakImported(),
ID);
6966 llvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(
6969 return EmitClassRefFromId(CGF, II,
false,
nullptr);
6976 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->
getIdentifier()];
6981 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName.str(),
6982 ID->isWeakImported());
6983 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassnfABIPtrTy,
6984 false, llvm::GlobalValue::PrivateLinkage,
6985 ClassGV,
"OBJC_CLASSLIST_SUP_REFS_$_");
6987 Entry->setSection(
"__DATA, __objc_superrefs, regular, no_dead_strip");
7000 llvm::GlobalVariable * &Entry = MetaClassReferences[ID->
getIdentifier()];
7004 llvm::GlobalVariable *MetaClassGV =
7005 GetClassGlobal(MetaClassName.str(), Weak);
7007 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassnfABIPtrTy,
7008 false, llvm::GlobalValue::PrivateLinkage,
7009 MetaClassGV,
"OBJC_CLASSLIST_SUP_REFS_$_");
7012 Entry->setSection(
"__DATA, __objc_superrefs, regular, no_dead_strip");
7023 if (ID->isWeakImported()) {
7026 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName.str(),
true);
7028 assert(ClassGV->hasExternalWeakLinkage());
7031 return EmitClassRef(CGF, ID);
7043 bool isCategoryImpl,
7045 bool IsClassMessage,
7064 Target = EmitMetaClassRef(CGF, Class, Class->isWeakImported());
7066 Target = EmitSuperClassRef(CGF, Class);
7070 llvm::Type *ClassTy =
7076 return (isVTableDispatchedSelector(Sel))
7077 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
7078 ObjCSuper.
getPointer(), ObjCTypes.SuperPtrCTy,
7079 true, CallArgs, Method)
7080 : EmitMessageSend(CGF, Return, ResultType,
7081 EmitSelector(CGF, Sel),
7082 ObjCSuper.
getPointer(), ObjCTypes.SuperPtrCTy,
7083 true, CallArgs, Method, Class, ObjCTypes);
7088 Address Addr = EmitSelectorAddr(CGF, Sel);
7091 LI->setMetadata(CGM.
getModule().getMDKindID(
"invariant.load"),
7092 llvm::MDNode::get(VMContext, None));
7098 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
7102 llvm::Constant *Casted =
7103 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
7104 ObjCTypes.SelectorPtrTy);
7105 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.SelectorPtrTy,
7106 false, llvm::GlobalValue::PrivateLinkage,
7107 Casted,
"OBJC_SELECTOR_REFERENCES_");
7108 Entry->setExternallyInitialized(
true);
7109 Entry->setSection(
"__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
7124 llvm::Type * SrcTy = src->getType();
7125 if (!isa<llvm::PointerType>(SrcTy)) {
7126 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(SrcTy);
7127 assert(Size <= 8 && "does not support size > 8
");
7128 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7129 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7130 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7132 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7133 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
7134 llvm::Value *args[] = { src, dst.getPointer(), ivarOffset };
7135 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
7141 void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
7142 CodeGen::CodeGenFunction &CGF,
7143 llvm::Value *src, Address dst) {
7144 llvm::Type * SrcTy = src->getType();
7145 if (!isa<llvm::PointerType>(SrcTy)) {
7146 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7147 assert(Size <= 8 && "does
not support size > 8
");
7148 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7149 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7150 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7152 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7153 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
7154 llvm::Value *args[] = { src, dst.getPointer() };
7155 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(),
7156 args, "weakassign
");
7159 void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
7160 CodeGen::CodeGenFunction &CGF,
7163 llvm::Value *Size) {
7164 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
7165 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
7166 llvm::Value *args[] = { DestPtr.getPointer(), SrcPtr.getPointer(), Size };
7167 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
7173 llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(
7174 CodeGen::CodeGenFunction &CGF,
7175 Address AddrWeakObj) {
7176 llvm::Type *DestTy = AddrWeakObj.getElementType();
7177 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy);
7178 llvm::Value *read_weak =
7179 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(),
7180 AddrWeakObj.getPointer(), "weakread
");
7181 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
7188 void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
7189 llvm::Value *src, Address dst) {
7190 llvm::Type * SrcTy = src->getType();
7191 if (!isa<llvm::PointerType>(SrcTy)) {
7192 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7193 assert(Size <= 8 && "does
not support size > 8
");
7194 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7195 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7196 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7198 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7199 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
7200 llvm::Value *args[] = { src, dst.getPointer() };
7201 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(),
7202 args, "weakassign
");
7208 void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
7209 llvm::Value *src, Address dst,
7211 llvm::Type * SrcTy = src->getType();
7212 if (!isa<llvm::PointerType>(SrcTy)) {
7213 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7214 assert(Size <= 8 && "does
not support size > 8
");
7215 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7216 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7217 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7219 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7220 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
7221 llvm::Value *args[] = { src, dst.getPointer() };
7223 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(),
7224 args, "globalassign
");
7226 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(),
7227 args, "threadlocalassign
");
7231 CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
7232 const ObjCAtSynchronizedStmt &S) {
7233 EmitAtSynchronizedStmt(CGF, S,
7234 cast<llvm::Function>(ObjCTypes.getSyncEnterFn()),
7235 cast<llvm::Function>(ObjCTypes.getSyncExitFn()));
7239 CGObjCNonFragileABIMac::GetEHType(QualType T) {
7240 // There's a particular fixed type info for 'id'.
7241 if (T->isObjCIdType() || T->isObjCQualifiedIdType()) {
7242 auto *IDEHType = CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id
");
7245 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
7246 llvm::GlobalValue::ExternalLinkage, nullptr,
7248 if (CGM.getTriple().isOSBinFormatCOFF())
7249 IDEHType->setDLLStorageClass(getStorage(CGM, "OBJC_EHTYPE_id
"));
7254 // All other types should be Objective-C interface pointer types.
7255 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
7256 assert(PT && "Invalid
@catch type.
");
7258 const ObjCInterfaceType *IT = PT->getInterfaceType();
7259 assert(IT && "Invalid
@catch type.
");
7261 return GetInterfaceEHType(IT->getDecl(), false);
7264 void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
7265 const ObjCAtTryStmt &S) {
7266 EmitTryCatchStmt(CGF, S,
7267 cast<llvm::Function>(ObjCTypes.getObjCBeginCatchFn()),
7268 cast<llvm::Function>(ObjCTypes.getObjCEndCatchFn()),
7269 cast<llvm::Function>(ObjCTypes.getExceptionRethrowFn()));
7273 void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
7274 const ObjCAtThrowStmt &S,
7275 bool ClearInsertionPoint) {
7276 if (const Expr *ThrowExpr = S.getThrowExpr()) {
7277 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
7278 Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
7279 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception)
7280 .setDoesNotReturn();
7282 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionRethrowFn())
7283 .setDoesNotReturn();
7286 CGF.Builder.CreateUnreachable();
7287 if (ClearInsertionPoint)
7288 CGF.Builder.ClearInsertionPoint();
7292 CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
7293 bool ForDefinition) {
7294 llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
7295 StringRef ClassName = ID->getObjCRuntimeNameAsString();
7297 // If we don't need a definition, return the entry if found or check
7298 // if we use an external reference.
7299 if (!ForDefinition) {
7303 // If this type (or a super class) has the __objc_exception__
7304 // attribute, emit an external reference.
7305 if (hasObjCExceptionAttribute(CGM.getContext(), ID)) {
7306 std::string EHTypeName = ("OBJC_EHTYPE_$_
" + ClassName).str();
7307 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy,
7308 false, llvm::GlobalValue::ExternalLinkage,
7309 nullptr, EHTypeName);
7310 if (CGM.getTriple().isOSBinFormatCOFF()) {
7311 if (ID->hasAttr<DLLExportAttr>())
7312 Entry->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
7313 else if (ID->hasAttr<DLLImportAttr>())
7314 Entry->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
7320 // Otherwise we need to either make a new entry or fill in the initializer.
7321 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition
");
7323 std::string VTableName = "objc_ehtype_vtable
";
7324 auto *VTableGV = CGM.getModule().getGlobalVariable(VTableName);
7327 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy, false,
7328 llvm::GlobalValue::ExternalLinkage, nullptr,
7330 if (CGM.getTriple().isOSBinFormatCOFF())
7331 VTableGV->setDLLStorageClass(getStorage(CGM, VTableName));
7334 llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2);
7335 llvm::Constant *Values[] = {
7336 llvm::ConstantExpr::getGetElementPtr(VTableGV->getValueType(), VTableGV,
7338 GetClassName(ID->getObjCRuntimeNameAsString()),
7339 GetClassGlobal((getClassSymbolPrefix() + ClassName).str()),
7341 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values);
7343 llvm::GlobalValue::LinkageTypes L = ForDefinition
7344 ? llvm::GlobalValue::ExternalLinkage
7345 : llvm::GlobalValue::WeakAnyLinkage;
7347 Entry->setInitializer(Init);
7350 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false, L,
7351 Init, ("OBJC_EHTYPE_$_
" + ClassName).str());
7352 if (CGM.getTriple().isOSBinFormatCOFF())
7353 if (hasObjCExceptionAttribute(CGM.getContext(), ID))
7354 if (ID->hasAttr<DLLExportAttr>())
7355 Entry->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
7357 assert(Entry->getLinkage() == L);
7359 if (!CGM.getTriple().isOSBinFormatCOFF())
7360 if (ID->getVisibility() == HiddenVisibility)
7361 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
7363 const auto &DL = CGM.getDataLayout();
7364 Entry->setAlignment(DL.getABITypeAlignment(ObjCTypes.EHTypeTy));
7367 Entry->setSection("__DATA,__objc_const
");
7374 CodeGen::CGObjCRuntime *
7375 CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
7376 switch (CGM.getLangOpts().ObjCRuntime.getKind()) {
7377 case ObjCRuntime::FragileMacOSX:
7378 return new CGObjCMac(CGM);
7380 case ObjCRuntime::MacOSX:
7381 case ObjCRuntime::iOS:
7382 case ObjCRuntime::WatchOS:
7383 return new CGObjCNonFragileABIMac(CGM);
7385 case ObjCRuntime::GNUstep:
7386 case ObjCRuntime::GCC:
7387 case ObjCRuntime::ObjFW:
7388 llvm_unreachable("these runtimes are
not Mac runtimes
");
7390 llvm_unreachable("bad runtime
");
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for class's metadata.
param_const_iterator param_begin() const
ReturnValueSlot - Contains the address where the return value of a function can be stored...
Defines the clang::ASTContext interface.
static Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
External linkage, which indicates that the entity can be referred to from other translation units...
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names the class interface associated with this implementation...
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
protocol_range protocols() const
CharUnits BlockHeaderForcedGapOffset
Smart pointer class that efficiently represents Objective-C method names.
Class implementation was compiled under ARC.
PointerType - C99 6.7.5.1 - Pointer Declarators.
const ObjCAtFinallyStmt * getFinallyStmt() const
Retrieve the @finally statement, if any.
A (possibly-)qualified type.
ArrayRef< Capture > captures() const
ImplementationControl getImplementationControl() const
CodeGenTypes & getTypes()
bool isBitField() const
Determines whether this field is a bitfield.
static Selector GetUnarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing an unary selector.
llvm::Module & getModule() const
protocol_iterator protocol_end() const
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
CharUnits getOffset() const
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
CreateTempAlloca - This creates a alloca and inserts it into the entry block.
Implements runtime-specific code generation functions.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
bool isRecordType() const
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
llvm::CallingConv::ID getRuntimeCC() const
void EmitAutoVarDecl(const VarDecl &D)
EmitAutoVarDecl - Emit an auto variable declaration.
std::string getAsString() const
const llvm::DataLayout & getDataLayout() const
Has a non-trivial constructor or destructor.
bool isObjCQualifiedClassType() const
Represents Objective-C's @throw statement.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
static bool hasObjCExceptionAttribute(ASTContext &Context, const ObjCInterfaceDecl *OID)
hasObjCExceptionAttribute - Return true if this class or any super class has the objc_exception attri...
bool isBlockPointerType() const
ObjCProtocolList::iterator protocol_iterator
static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT, bool pointee=false)
const llvm::APInt & getSize() const
const ASTRecordLayout & getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const
Get or compute information about the layout of the specified Objective-C implementation.
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
Objects with "hidden" visibility are not seen by the dynamic linker.
llvm::Type * getElementType() const
Return the type of the values stored in this address.
QualType getObjCClassType() const
Represents the Objective-C Class type.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
ObjCMethodDecl - Represents an instance or class method declaration.
Visibility getVisibility() const
Determines the visibility of this entity.
Defines the Objective-C statement AST node classes.
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
ParmVarDecl - Represents a parameter to a function.
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names the category interface associated with this implementat...
A jump destination is an abstract label, branching to which may require a jump out through normal cle...
QualType withConst() const
Retrieves a version of this type with const applied.
llvm::Value * EmitObjCThrowOperand(const Expr *expr)
Class implementation was compiled under ARC.
RecordDecl - Represents a struct/union/class.
One of these records is kept for each identifier that is lexed.
const ObjCInterfaceDecl * getContainingInterface() const
Return the class interface that this ivar is logically contained in; this is either the interface whe...
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
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 ...
static void addIfPresent(llvm::DenseSet< llvm::Value * > &S, llvm::Value *V)
protocol_iterator protocol_begin() const
Class has non-trivial destructors, but zero-initialization is okay.
std::string getNameAsString() const
Get the name of the class associated with this interface.
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
llvm::CallInst * EmitRuntimeCall(llvm::Value *callee, const Twine &name="")
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
Class implementation was compiled under MRC and has MRC weak ivars.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
RValue EmitCall(const CGFunctionInfo &FnInfo, llvm::Value *Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, CGCalleeInfo CalleeInfo=CGCalleeInfo(), llvm::Instruction **callOrInvoke=nullptr)
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.
Has the exception attribute.
const VarDecl * getCatchParamDecl() const
Objects with "default" visibility are seen by the dynamic linker and act like normal objects...
Represents Objective-C's @catch statement.
const Capture & getCapture(const VarDecl *var) const
static bool isWeakLinkedClass(const ObjCInterfaceDecl *ID)
ObjCContainerDecl - Represents a container for method declarations.
const LangOptions & getLangOpts() const
CharUnits - This is an opaque type for sizes expressed in character units.
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
protocol_iterator protocol_end() const
field_range fields() const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
RecordDecl * getDecl() const
CharUnits getPointerSize() const
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface...
std::string getNameAsString() const
getNameAsString - Get a human-readable name for the declaration, even if it is one of the special kin...
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
const Stmt * getCatchBody() const
void EmitStmt(const Stmt *S)
EmitStmt - Emit the code for the statement.
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
void addCompilerUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.compiler.used metadata.
Represents an Objective-C protocol declaration.
const ObjCAtCatchStmt * getCatchStmt(unsigned I) const
Retrieve a @catch statement.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
Represents an ObjC class declaration.
propimpl_range property_impls() const
detail::InMemoryDirectory::const_iterator I
unsigned getPreferredTypeAlign(const Type *T) const
Return the "preferred" alignment of the specified type T for the current target, in bits...
const ParmVarDecl *const * param_const_iterator
CanQualType getCanonicalTypeUnqualified() const
void addFrom(const CallArgList &other)
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
CGBlockInfo - Information to generate a block literal.
const TargetInfo & getTarget() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
bool isUnarySelector() const
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
bool hasDestructors() const
Do any of the ivars of this class (not counting its base classes) require non-trivial destruction...
llvm::Value * getPointer() const
BlockDecl - This represents a block literal declaration, which is like an unnamed FunctionDecl...
Expr - This represents one expression.
unsigned getIndex() const
Defines the clang::LangOptions interface.
StringRef getName() const
Return the actual identifier string.
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for class's metadata.
unsigned getNumArgs() const
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
bool isObjCClassType() const
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for protocol's metadata.
bool isObjCGCWeak() const
true when Type is objc's weak.
llvm::AllocaInst * NormalCleanupDest
i32s containing the indexes of the cleanup destinations.
ASTContext & getContext() const
llvm::BasicBlock * getBlock() const
Represents Objective-C's @synchronized statement.
protocol_iterator protocol_begin() const
void add(RValue rvalue, QualType type, bool needscopy=false)
bool isObjCIdType() const
llvm::LLVMContext & getLLVMContext()
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI)
Return true iff the given type uses an argument slot when 'sret' is used as a return type...
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
QualType getObjCIdType() const
Represents the Objective-CC id type.
static llvm::Constant * getConstantGEP(llvm::LLVMContext &VMContext, llvm::GlobalVariable *C, unsigned idx0, unsigned idx1)
getConstantGEP() - Help routine to construct simple GEPs.
CharUnits getSizeAlign() const
The result type of a method or function.
float __ovld __cnfn length(float p)
Return the length of vector p, i.e., sqrt(p.x2 + p.y 2 + ...)
(Obsolete) ARC-specific: this class has a .release_ivars method
param_const_iterator param_end() const
The l-value was considered opaque, so the alignment was determined from a type.
bool isClassMethod() const
ArrayRef< ParmVarDecl * > parameters() const
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
Address CreateBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
bool ReturnTypeUsesFPRet(QualType ResultType)
Return true iff the given type uses 'fpret' when used as a return type.
ASTContext & getContext() const
CharUnits getPointerAlign() const
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 TemplateArgument * iterator
CharUnits getSize() const
getSize - Get the record size in characters.
unsigned getBitWidthValue(const ASTContext &Ctx) const
StringRef getName() const
getName - Get the name of identifier for the class interface associated with this implementation as a...
llvm::StructType * StructureType
SmallVector< llvm::Value *, 8 > ObjCEHValueStack
ObjCEHValueStack - Stack of Objective-C exception values, used for rethrows.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
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.
const CGFunctionInfo & arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD)
Objective-C methods are C functions with some implicit parameters.
CanQualType getCanonicalParamType(QualType T) const
Return the canonical parameter type corresponding to the specific potentially non-canonical one...
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...
all_protocol_iterator all_referenced_protocol_end() const
ObjCCategoryDecl - Represents a category declaration.
const ObjCInterfaceDecl * getClassInterface() const
static bool hasWeakMember(QualType type)
const LangOptions & getLangOpts() const
Represents one property declaration in an Objective-C interface.
Class implementation was compiled under MRC and has MRC weak ivars.
QualType getReturnType() const
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...
virtual void Emit(CodeGenFunction &CGF, Flags flags)=0
Emit the cleanup.
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...
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type, returning the result.
ObjCIvarDecl * getNextIvar()
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...
instmeth_range instance_methods() const
This class organizes the cross-function state that is used while generating LLVM code.
ObjCCategoryDecl * FindCategoryDeclaration(IdentifierInfo *CategoryId) const
FindCategoryDeclaration - Finds category declaration in the list of categories for this class and ret...
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
prop_range properties() const
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
std::string getNameAsString() const
Get the name of the class associated with this interface.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
Address CreateStructGEP(Address Addr, unsigned Index, CharUnits Offset, const llvm::Twine &Name="")
unsigned getCharWidth() const
llvm::LoadInst * CreateAlignedLoad(llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::IntegerType * IntPtrTy
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getObjCProtoType() const
Retrieve the type of the Objective-C Protocol class.
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
int printf(__constant const char *st,...)
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Selector getSelector() const
detail::InMemoryDirectory::const_iterator E
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Apparently: is not a meta-class.
const llvm::Triple & getTriple() const
Address getNormalCleanupDestSlot()
Represents a pointer to an Objective C object.
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
ObjCMethodDecl * getGetterMethodDecl() const
bool hasNonZeroConstructors() const
Do any of the ivars of this class (not counting its base classes) require construction other than zer...
llvm::PointerType * getType() const
Return the type of the pointer value.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
const T * getAs() const
Member-template getAs<specific type>'.
ObjCMethodDecl * getSetterMethodDecl() const
This class organizes the cross-module state that is used while lowering AST types to LLVM types...
bool isObjCQualifiedIdType() const
llvm::PointerType * Int8PtrTy
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.
unsigned getNumCatchStmts() const
Retrieve the number of @catch statements in this try-catch-finally block.
uint64_t getPointerWidth(unsigned AddrSpace) const
Return the width of pointers on this target, for the specified address space.
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
bool isObjCGCStrong() const
true when Type is objc's strong.
AccessControl getAccessControl() const
classmeth_range class_methods() const
BoundNodesTreeBuilder *const Builder
StringRef getName() const
getName - Get the name of identifier for the class interface associated with this implementation as a...
bool isObjCObjectPointerType() const
llvm::Type * ConvertType(QualType T)
all_protocol_iterator all_referenced_protocol_begin() const
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.
const BlockDecl * getBlockDecl() const
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
CharUnits BlockHeaderForcedGapSize
Has a non-trivial constructor or destructor.
Represents Objective-C's @try ... @catch ... @finally statement.
const Expr * getThrowExpr() const
StringLiteral - This represents a string literal expression, e.g.
ObjCInterfaceDecl * getSuperClass() const
static RValue get(llvm::Value *V)
QualType getElementType() const
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
LValue - This represents an lvalue references.
Information for lazily generating a cleanup.
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
bool isObjCIdType() const
True if this is equivalent to the 'id' type, i.e.
CallArgList - Type for representing both the value and type of arguments in a call.
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.
CGCalleeInfo - Class to encapsulate the information about a callee to be used during the generation o...
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
ObjCCompatibleAliasDecl - Represents alias of a class.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.