29 #include "llvm/ADT/CachedHashString.h"
30 #include "llvm/ADT/DenseSet.h"
31 #include "llvm/ADT/SetVector.h"
32 #include "llvm/ADT/SmallPtrSet.h"
33 #include "llvm/ADT/SmallString.h"
34 #include "llvm/IR/CallSite.h"
35 #include "llvm/IR/DataLayout.h"
36 #include "llvm/IR/InlineAsm.h"
37 #include "llvm/IR/IntrinsicInst.h"
38 #include "llvm/IR/LLVMContext.h"
39 #include "llvm/IR/Module.h"
40 #include "llvm/Support/raw_ostream.h"
43 using namespace clang;
44 using namespace CodeGen;
51 class ObjCCommonTypesHelper {
53 llvm::LLVMContext &VMContext;
63 llvm::Constant *getMessageSendFn()
const {
66 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
67 return CGM.CreateRuntimeFunction(
68 llvm::FunctionType::get(ObjectPtrTy, params,
true),
"objc_msgSend",
69 llvm::AttributeList::get(CGM.getLLVMContext(),
70 llvm::AttributeList::FunctionIndex,
71 llvm::Attribute::NonLazyBind));
79 llvm::Constant *getMessageSendStretFn()
const {
80 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
81 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy,
83 "objc_msgSend_stret");
92 llvm::Constant *getMessageSendFpretFn()
const {
93 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
94 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.DoubleTy,
96 "objc_msgSend_fpret");
105 llvm::Constant *getMessageSendFp2retFn()
const {
106 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
107 llvm::Type *longDoubleType = llvm::Type::getX86_FP80Ty(VMContext);
109 llvm::StructType::get(longDoubleType, longDoubleType);
111 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(resultType,
113 "objc_msgSend_fp2ret");
121 llvm::Constant *getMessageSendSuperFn()
const {
122 llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
123 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
125 "objc_msgSendSuper");
132 llvm::Constant *getMessageSendSuperFn2()
const {
133 llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
134 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
136 "objc_msgSendSuper2");
143 llvm::Constant *getMessageSendSuperStretFn()
const {
144 llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
145 return CGM.CreateRuntimeFunction(
146 llvm::FunctionType::get(CGM.VoidTy, params,
true),
147 "objc_msgSendSuper_stret");
154 llvm::Constant *getMessageSendSuperStretFn2()
const {
155 llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
156 return CGM.CreateRuntimeFunction(
157 llvm::FunctionType::get(CGM.VoidTy, params,
true),
158 "objc_msgSendSuper2_stret");
161 llvm::Constant *getMessageSendSuperFpretFn()
const {
163 return getMessageSendSuperFn();
166 llvm::Constant *getMessageSendSuperFpretFn2()
const {
168 return getMessageSendSuperFn2();
175 llvm::IntegerType *ShortTy, *IntTy, *LongTy;
176 llvm::PointerType *Int8PtrTy, *Int8PtrPtrTy;
180 llvm::PointerType *ObjectPtrTy;
183 llvm::PointerType *PtrObjectPtrTy;
186 llvm::PointerType *SelectorPtrTy;
195 if (!ExternalProtocolPtrTy) {
201 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
204 return ExternalProtocolPtrTy;
213 llvm::StructType *SuperTy;
215 llvm::PointerType *SuperPtrTy;
219 llvm::StructType *PropertyTy;
223 llvm::StructType *PropertyListTy;
225 llvm::PointerType *PropertyListPtrTy;
228 llvm::StructType *MethodTy;
233 llvm::PointerType *CachePtrTy;
235 llvm::Constant *getGetPropertyFn() {
244 llvm::FunctionType *FTy =
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() {
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;
503 llvm::PointerType *SymtabPtrTy;
505 llvm::StructType *ModuleTy;
508 llvm::StructType *ProtocolTy;
510 llvm::PointerType *ProtocolPtrTy;
513 llvm::StructType *ProtocolExtensionTy;
516 llvm::PointerType *ProtocolExtensionPtrTy;
519 llvm::StructType *MethodDescriptionTy;
522 llvm::StructType *MethodDescriptionListTy;
525 llvm::PointerType *MethodDescriptionListPtrTy;
527 llvm::StructType *ProtocolListTy;
529 llvm::PointerType *ProtocolListPtrTy;
531 llvm::StructType *CategoryTy;
533 llvm::StructType *ClassTy;
535 llvm::PointerType *ClassPtrTy;
537 llvm::StructType *ClassExtensionTy;
539 llvm::PointerType *ClassExtensionPtrTy;
541 llvm::StructType *IvarTy;
543 llvm::StructType *IvarListTy;
545 llvm::PointerType *IvarListPtrTy;
547 llvm::StructType *MethodListTy;
549 llvm::PointerType *MethodListPtrTy;
552 llvm::StructType *ExceptionDataTy;
555 llvm::Constant *getExceptionTryEnterFn() {
556 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
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() };
590 return CGM.CreateRuntimeFunction(
591 llvm::FunctionType::get(CGM.Int32Ty, params,
false),
"_setjmp",
592 llvm::AttributeList::get(CGM.getLLVMContext(),
593 llvm::AttributeList::FunctionIndex,
594 llvm::Attribute::NonLazyBind));
603 class ObjCNonFragileABITypesHelper :
public ObjCCommonTypesHelper {
606 llvm::StructType *MethodListnfABITy;
609 llvm::PointerType *MethodListnfABIPtrTy;
612 llvm::StructType *ProtocolnfABITy;
615 llvm::PointerType *ProtocolnfABIPtrTy;
618 llvm::StructType *ProtocolListnfABITy;
621 llvm::PointerType *ProtocolListnfABIPtrTy;
624 llvm::StructType *ClassnfABITy;
627 llvm::PointerType *ClassnfABIPtrTy;
630 llvm::StructType *IvarnfABITy;
633 llvm::StructType *IvarListnfABITy;
636 llvm::PointerType *IvarListnfABIPtrTy;
639 llvm::StructType *ClassRonfABITy;
642 llvm::PointerType *ImpnfABITy;
645 llvm::StructType *CategorynfABITy;
654 llvm::StructType *MessageRefTy;
668 llvm::StructType *SuperMessageRefTy;
671 llvm::PointerType *SuperMessageRefPtrTy;
673 llvm::Constant *getMessageSendFixupFn() {
675 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
676 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
678 "objc_msgSend_fixup");
681 llvm::Constant *getMessageSendFpretFixupFn() {
683 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
684 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
686 "objc_msgSend_fpret_fixup");
689 llvm::Constant *getMessageSendStretFixupFn() {
691 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
692 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
694 "objc_msgSend_stret_fixup");
697 llvm::Constant *getMessageSendSuper2FixupFn() {
700 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
701 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
703 "objc_msgSendSuper2_fixup");
706 llvm::Constant *getMessageSendSuper2StretFixupFn() {
709 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
710 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
712 "objc_msgSendSuper2_stret_fixup");
715 llvm::Constant *getObjCEndCatchFn() {
716 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy,
false),
721 llvm::Constant *getObjCBeginCatchFn() {
723 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(Int8PtrTy,
728 llvm::StructType *EHTypeTy;
747 SKIP_SCAN(
unsigned _skip = 0,
unsigned _scan = 0)
748 : skip(_skip), scan(_scan) {}
755 enum BLOCK_LAYOUT_OPCODE {
762 BLOCK_LAYOUT_OPERATOR = 0,
768 BLOCK_LAYOUT_NON_OBJECT_BYTES = 1,
773 BLOCK_LAYOUT_NON_OBJECT_WORDS = 2,
777 BLOCK_LAYOUT_STRONG = 3,
780 BLOCK_LAYOUT_BYREF = 4,
784 BLOCK_LAYOUT_WEAK = 5,
788 BLOCK_LAYOUT_UNRETAINED = 6
805 enum BLOCK_LAYOUT_OPCODE opcode;
808 RUN_SKIP(
enum BLOCK_LAYOUT_OPCODE Opcode = BLOCK_LAYOUT_OPERATOR,
811 : opcode(Opcode), block_var_bytepos(BytePos), block_var_size(Size) {}
814 bool operator<(
const RUN_SKIP &b)
const {
815 return block_var_bytepos < b.block_var_bytepos;
820 llvm::LLVMContext &VMContext;
829 llvm::SetVector<IdentifierInfo*> LazySymbols;
835 llvm::SetVector<IdentifierInfo*> DefinedSymbols;
838 llvm::StringMap<llvm::GlobalVariable*> ClassNames;
841 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
848 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
852 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
855 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
858 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
861 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
866 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
889 llvm::WeakTrackingVH ConstantStringClassRef;
892 llvm::StructType *NSConstantStringType =
nullptr;
894 llvm::StringMap<llvm::GlobalVariable *> NSConstantStringMap;
904 llvm::Constant *GetMethodVarName(
Selector Sel);
912 bool Extended =
false);
913 llvm::Constant *GetMethodVarType(
const FieldDecl *D);
921 const Decl *Container);
926 llvm::Constant *GetClassName(StringRef RuntimeName);
940 bool forStrongLayout,
946 return BuildIvarLayout(OI, beginOffset, endOffset,
true,
false);
953 return BuildIvarLayout(OI, beginOffset, endOffset,
false, hasMRCWeakIvars);
958 void UpdateRunSkipBlockVars(
bool IsByref,
963 void BuildRCBlockVarRecordLayout(
const RecordType *RT,
965 bool ByrefLayout=
false);
967 void BuildRCRecordLayout(
const llvm::StructLayout *RecLayout,
975 llvm::Constant *getBitmapBlockLayout(
bool ComputeByrefLayout);
980 const ObjCCommonTypesHelper &ObjCTypes);
984 llvm::Constant *EmitPropertyList(Twine
Name,
985 const Decl *Container,
987 const ObjCCommonTypesHelper &ObjCTypes,
988 bool IsClassProperty);
992 llvm::Constant *EmitProtocolMethodTypes(Twine
Name,
994 const ObjCCommonTypesHelper &ObjCTypes);
1005 ObjCCommonTypesHelper &ObjCTypes);
1007 std::string GetSectionName(StringRef Section, StringRef MachOAttributes);
1024 llvm::GlobalVariable *CreateMetadataVar(Twine
Name,
1028 llvm::GlobalVariable *CreateMetadataVar(Twine
Name,
1029 llvm::Constant *Init,
1033 llvm::GlobalVariable *CreateCStringLiteral(StringRef
Name,
1035 bool ForceNonFragileABI =
false,
1036 bool NullTerminate =
true);
1049 const ObjCCommonTypesHelper &ObjCTypes);
1053 void EmitImageInfo();
1059 bool isNonFragileABI()
const {
1060 return ObjCABI == 2;
1080 virtual llvm::Constant *GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD)=0;
1082 virtual llvm::Constant *getNSConstantStringClassRef() = 0;
1096 CategoryInstanceMethods,
1097 CategoryClassMethods,
1100 ProtocolInstanceMethods,
1101 ProtocolClassMethods,
1102 OptionalProtocolInstanceMethods,
1103 OptionalProtocolClassMethods,
1108 class ProtocolMethodLists {
1111 RequiredInstanceMethods,
1112 RequiredClassMethods,
1113 OptionalInstanceMethods,
1114 OptionalClassMethods
1117 NumProtocolMethodLists = 4
1122 case RequiredInstanceMethods:
1123 return MethodListType::ProtocolInstanceMethods;
1124 case RequiredClassMethods:
1125 return MethodListType::ProtocolClassMethods;
1126 case OptionalInstanceMethods:
1127 return MethodListType::OptionalProtocolInstanceMethods;
1128 case OptionalClassMethods:
1129 return MethodListType::OptionalProtocolClassMethods;
1131 llvm_unreachable(
"bad kind");
1137 ProtocolMethodLists result;
1139 for (
auto MD : PD->methods()) {
1140 size_t index = (2 *
size_t(MD->isOptional()))
1141 + (
size_t(MD->isClassMethod()));
1142 result.Methods[index].push_back(MD);
1148 template <
class Self>
1159 for (
auto &list : Methods) {
1160 for (
auto MD : list) {
1161 result.push_back(self->GetMethodVarType(MD,
true));
1168 template <
class Self>
1172 getMethodListKind(kind), Methods[
kind]);
1178 class CGObjCMac :
public CGObjCCommonMac {
1180 friend ProtocolMethodLists;
1182 ObjCTypesHelper ObjCTypes;
1186 void EmitModuleInfo();
1190 llvm::Constant *EmitModuleSymbols();
1194 void FinishModule();
1233 llvm::Constant *Protocols,
1264 const ProtocolMethodLists &methodLists);
1268 llvm::Constant *EmitProtocolList(Twine
Name,
1280 llvm::Constant *getNSConstantStringClassRef()
override;
1282 llvm::Function *ModuleInitFunction()
override;
1311 llvm::Constant *GetEHType(
QualType T)
override;
1322 llvm::Constant *GetPropertyGetFunction()
override;
1323 llvm::Constant *GetPropertySetFunction()
override;
1324 llvm::Constant *GetOptimizedPropertySetFunction(
bool atomic,
1325 bool copy)
override;
1326 llvm::Constant *GetGetStructFunction()
override;
1327 llvm::Constant *GetSetStructFunction()
override;
1328 llvm::Constant *GetCppAtomicObjectGetFunction()
override;
1329 llvm::Constant *GetCppAtomicObjectSetFunction()
override;
1330 llvm::Constant *EnumerationMutationFunction()
override;
1338 bool ClearInsertionPoint=
true)
override;
1340 Address AddrWeakObj)
override;
1345 bool threadlocal =
false)
override;
1357 unsigned CVRQualifiers)
override;
1363 class CGObjCNonFragileABIMac :
public CGObjCCommonMac {
1365 friend ProtocolMethodLists;
1366 ObjCNonFragileABITypesHelper ObjCTypes;
1367 llvm::GlobalVariable* ObjCEmptyCacheVar;
1368 llvm::Constant* ObjCEmptyVtableVar;
1371 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences;
1374 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences;
1377 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences;
1384 std::vector<llvm::GlobalValue*> DefinedMetaClasses;
1388 bool isVTableDispatchedSelector(
Selector Sel);
1392 void FinishNonFragileABIModule();
1397 StringRef SymbolName, StringRef SectionName);
1399 llvm::GlobalVariable * BuildClassRoTInitializer(
unsigned flags,
1400 unsigned InstanceStart,
1401 unsigned InstanceSize,
1405 llvm::Constant *IsAGV,
1406 llvm::Constant *SuperClassGV,
1407 llvm::Constant *ClassRoGV,
1428 unsigned long int offset);
1443 llvm::Constant *EmitProtocolList(Twine
Name,
1459 llvm::Constant *GetClassGlobal(StringRef
Name,
1461 bool Weak =
false,
bool DLLImport =
false);
1490 llvm::GlobalVariable * ObjCIvarOffsetVariable(
1504 StringRef getMetaclassSymbolPrefix()
const {
return "OBJC_METACLASS_$_"; }
1506 StringRef getClassSymbolPrefix()
const {
return "OBJC_CLASS_$_"; }
1509 uint32_t &InstanceStart,
1510 uint32_t &InstanceSize);
1515 return CGM.getContext().Selectors.getSelector(0, &II);
1520 return CGM.getContext().Selectors.getSelector(1, &II);
1525 bool ImplementationIsNonLazy(
const ObjCImplDecl *OD)
const;
1540 dyn_cast_or_null<ObjCMethodDecl>(CGF.
CurFuncDecl))
1541 if (MD->isInstanceMethod())
1550 llvm::Constant *getNSConstantStringClassRef()
override;
1552 llvm::Function *ModuleInitFunction()
override;
1574 {
return EmitSelector(CGF, Sel); }
1576 {
return EmitSelectorAddr(CGF, Sel); }
1582 {
return EmitSelector(CGF, Method->
getSelector()); }
1593 llvm::Constant *GetEHType(
QualType T)
override;
1595 llvm::Constant *GetPropertyGetFunction()
override {
1596 return ObjCTypes.getGetPropertyFn();
1598 llvm::Constant *GetPropertySetFunction()
override {
1599 return ObjCTypes.getSetPropertyFn();
1602 llvm::Constant *GetOptimizedPropertySetFunction(
bool atomic,
1603 bool copy)
override {
1604 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
1607 llvm::Constant *GetSetStructFunction()
override {
1608 return ObjCTypes.getCopyStructFn();
1611 llvm::Constant *GetGetStructFunction()
override {
1612 return ObjCTypes.getCopyStructFn();
1615 llvm::Constant *GetCppAtomicObjectSetFunction()
override {
1616 return ObjCTypes.getCppAtomicObjectFunction();
1619 llvm::Constant *GetCppAtomicObjectGetFunction()
override {
1620 return ObjCTypes.getCppAtomicObjectFunction();
1623 llvm::Constant *EnumerationMutationFunction()
override {
1624 return ObjCTypes.getEnumerationMutationFn();
1632 bool ClearInsertionPoint=
true)
override;
1634 Address AddrWeakObj)
override;
1639 bool threadlocal =
false)
override;
1650 unsigned CVRQualifiers)
override;
1658 struct NullReturnState {
1659 llvm::BasicBlock *NullBB;
1660 NullReturnState() : NullBB(nullptr) {}
1673 CGF.
Builder.CreateCondBr(isNull, NullBB, callBB);
1688 if (!NullBB)
return result;
1692 llvm::BasicBlock *contBB =
nullptr;
1695 llvm::BasicBlock *callBB = CGF.
Builder.GetInsertBlock();
1706 CallArgList::const_iterator
I = CallArgs.begin();
1710 if (ParamDecl->
hasAttr<NSConsumedAttr>()) {
1713 "NullReturnState::complete - arg not on object");
1720 assert(CGF.
Builder.GetInsertBlock() == NullBB);
1739 llvm::PHINode *phi = CGF.
Builder.CreatePHI(null->getType(), 2);
1741 phi->addIncoming(null, NullBB);
1750 assert(result.
isAggregate() &&
"null init of non-aggregate result?");
1762 llvm::Type *scalarTy = callResult.first->getType();
1763 llvm::Constant *scalarZero = llvm::Constant::getNullValue(scalarTy);
1766 llvm::PHINode *real = CGF.
Builder.CreatePHI(scalarTy, 2);
1767 real->addIncoming(callResult.first, callBB);
1768 real->addIncoming(scalarZero, NullBB);
1769 llvm::PHINode *imag = CGF.
Builder.CreatePHI(scalarTy, 2);
1770 imag->addIncoming(callResult.second, callBB);
1771 imag->addIncoming(scalarZero, NullBB);
1782 llvm::GlobalVariable *C,
unsigned idx0,
1785 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),
1786 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)
1788 return llvm::ConstantExpr::getGetElementPtr(C->getValueType(), C, Idxs);
1795 if (OID->
hasAttr<ObjCExceptionAttr>())
1814 return EmitClassRef(CGF, ID);
1819 return EmitSelector(CGF, Sel);
1822 return EmitSelectorAddr(CGF, Sel);
1829 llvm::Constant *CGObjCMac::GetEHType(
QualType T) {
1832 return CGM.GetAddrOfRTTIDescriptor(
1833 CGM.getContext().getObjCIdRedefinitionType(),
true);
1837 return CGM.GetAddrOfRTTIDescriptor(
1838 CGM.getContext().getObjCClassRedefinitionType(),
true);
1841 return CGM.GetAddrOfRTTIDescriptor(T,
true);
1843 llvm_unreachable(
"asking for catch type for ObjC type in fragile runtime");
1866 CGObjCCommonMac::GenerateConstantString(
const StringLiteral *SL) {
1867 return (!CGM.getLangOpts().NoConstantCFStrings
1868 ? CGM.GetAddrOfConstantCFString(SL)
1869 : GenerateConstantNSString(SL));
1872 static llvm::StringMapEntry<llvm::GlobalVariable *> &
1875 StringRef String = Literal->
getString();
1876 StringLength = String.size();
1877 return *Map.insert(std::make_pair(String,
nullptr)).first;
1880 llvm::Constant *CGObjCMac::getNSConstantStringClassRef() {
1882 return cast<llvm::Constant>(V);
1884 auto &StringClass = CGM.getLangOpts().ObjCConstantStringClass;
1886 StringClass.empty() ?
"_NSConstantStringClassReference"
1887 :
"_" + StringClass +
"ClassReference";
1889 llvm::Type *PTy = llvm::ArrayType::get(CGM.IntTy, 0);
1890 auto GV = CGM.CreateRuntimeVariable(PTy, str);
1891 auto V = llvm::ConstantExpr::getBitCast(GV, CGM.IntTy->getPointerTo());
1892 ConstantStringClassRef = V;
1896 llvm::Constant *CGObjCNonFragileABIMac::getNSConstantStringClassRef() {
1898 return cast<llvm::Constant>(V);
1900 auto &StringClass = CGM.getLangOpts().ObjCConstantStringClass;
1902 StringClass.empty() ?
"OBJC_CLASS_$_NSConstantString"
1903 :
"OBJC_CLASS_$_" + StringClass;
1907 auto V = llvm::ConstantExpr::getBitCast(GV, CGM.IntTy->getPointerTo());
1909 ConstantStringClassRef = V;
1914 CGObjCCommonMac::GenerateConstantNSString(
const StringLiteral *Literal) {
1915 unsigned StringLength = 0;
1916 llvm::StringMapEntry<llvm::GlobalVariable *> &Entry =
1919 if (
auto *
C = Entry.second)
1923 llvm::Constant *
Class = getNSConstantStringClassRef();
1926 if (!NSConstantStringType) {
1927 NSConstantStringType =
1929 CGM.Int32Ty->getPointerTo(),
1932 },
"struct.__builtin_NSString");
1936 auto Fields =
Builder.beginStruct(NSConstantStringType);
1943 llvm::ConstantDataArray::getString(VMContext, Entry.first());
1945 llvm::GlobalValue::LinkageTypes
Linkage = llvm::GlobalValue::PrivateLinkage;
1946 bool isConstant = !CGM.getLangOpts().WritableStrings;
1948 auto *GV =
new llvm::GlobalVariable(CGM.getModule(), C->getType(), isConstant,
1950 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1953 GV->setAlignment(1);
1954 Fields.addBitCast(GV, CGM.Int8PtrTy);
1957 Fields.addInt(CGM.IntTy, StringLength);
1960 CharUnits Alignment = CGM.getPointerAlign();
1961 GV = Fields.finishAndCreateGlobal(
"_unnamed_nsstring_", Alignment,
1963 llvm::GlobalVariable::PrivateLinkage);
1964 const char *NSStringSection =
"__OBJC,__cstring_object,regular,no_dead_strip";
1965 const char *NSStringNonFragileABISection =
1966 "__DATA,__objc_stringobj,regular,no_dead_strip";
1968 GV->setSection(CGM.getLangOpts().ObjCRuntime.isNonFragile()
1969 ? NSStringNonFragileABISection
1989 bool isCategoryImpl,
1991 bool IsClassMessage,
2007 if (IsClassMessage) {
2008 if (isCategoryImpl) {
2019 llvm::Constant *MetaClassPtr = EmitMetaClassRef(Class);
2026 }
else if (isCategoryImpl)
2035 llvm::Type *ClassTy =
2040 return EmitMessageSend(CGF, Return, ResultType,
2041 EmitSelector(CGF, Sel),
2042 ObjCSuper.
getPointer(), ObjCTypes.SuperPtrCTy,
2043 true, CallArgs, Method, Class, ObjCTypes);
2055 return EmitMessageSend(CGF, Return, ResultType,
2056 EmitSelector(CGF, Sel),
2058 false, CallArgs, Method, Class, ObjCTypes);
2081 const ObjCCommonTypesHelper &ObjCTypes) {
2085 ActualArgs.
add(RValue::get(Arg0), Arg0Ty);
2090 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2093 assert(CGM.getContext().getCanonicalType(Method->
getReturnType()) ==
2094 CGM.getContext().getCanonicalType(ResultType) &&
2095 "Result type mismatch!");
2097 bool ReceiverCanBeNull =
true;
2102 ReceiverCanBeNull =
false;
2106 }
else if (ClassReceiver && Method && Method->
isClassMethod()) {
2111 }
else if (
auto CurMethod =
2112 dyn_cast_or_null<ObjCMethodDecl>(CGF.
CurCodeDecl)) {
2113 auto Self = CurMethod->getSelfDecl();
2114 if (Self->getType().isConstQualified()) {
2115 if (
auto LI = dyn_cast<llvm::LoadInst>(Arg0->stripPointerCasts())) {
2117 if (SelfAddr == LI->getPointerOperand()) {
2118 ReceiverCanBeNull =
false;
2124 bool RequiresNullCheck =
false;
2126 llvm::Constant *Fn =
nullptr;
2127 if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
2128 if (ReceiverCanBeNull) RequiresNullCheck =
true;
2129 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
2130 : ObjCTypes.getSendStretFn(IsSuper);
2131 }
else if (CGM.ReturnTypeUsesFPRet(ResultType)) {
2132 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
2133 : ObjCTypes.getSendFpretFn(IsSuper);
2134 }
else if (CGM.ReturnTypeUsesFP2Ret(ResultType)) {
2135 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)
2136 : ObjCTypes.getSendFp2retFn(IsSuper);
2140 if (ReceiverCanBeNull && CGM.ReturnTypeUsesSRet(MSI.CallInfo))
2141 RequiresNullCheck =
true;
2142 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
2143 : ObjCTypes.getSendFn(IsSuper);
2149 RequiresNullCheck =
false;
2152 if (!RequiresNullCheck && CGM.getLangOpts().ObjCAutoRefCount && Method) {
2153 for (
const auto *ParamDecl : Method->
parameters()) {
2154 if (ParamDecl->
hasAttr<NSConsumedAttr>()) {
2155 RequiresNullCheck =
true;
2161 NullReturnState nullReturn;
2162 if (RequiresNullCheck) {
2163 nullReturn.init(CGF, Arg0);
2166 llvm::Instruction *CallSite;
2167 Fn = llvm::ConstantExpr::getBitCast(Fn, MSI.MessengerType);
2168 CGCallee Callee = CGCallee::forDirect(Fn);
2169 RValue rvalue = CGF.
EmitCall(MSI.CallInfo, Callee, Return, ActualArgs,
2174 if (Method && Method->
hasAttr<NoReturnAttr>() && !ReceiverCanBeNull) {
2175 llvm::CallSite(CallSite).setDoesNotReturn();
2178 return nullReturn.complete(CGF, Return, rvalue, ResultType, CallArgs,
2179 RequiresNullCheck ? Method :
nullptr);
2183 bool pointee =
false) {
2188 return Qualifiers::Strong;
2191 return Qualifiers::Weak;
2195 if (pointee)
return Qualifiers::GCNone;
2196 switch (ownership) {
2197 case Qualifiers::OCL_Weak:
return Qualifiers::Weak;
2198 case Qualifiers::OCL_Strong:
return Qualifiers::Strong;
2199 case Qualifiers::OCL_ExplicitNone:
return Qualifiers::GCNone;
2200 case Qualifiers::OCL_Autoreleasing: llvm_unreachable(
"autoreleasing ivar?");
2201 case Qualifiers::OCL_None: llvm_unreachable(
"known nonzero");
2203 llvm_unreachable(
"bad objc ownership");
2208 return Qualifiers::Strong;
2211 if (Ctx.
getLangOpts().getGC() != LangOptions::NonGC) {
2216 return Qualifiers::GCNone;
2222 uint64_t SizeInWords;
2223 IvarInfo(
CharUnits offset, uint64_t sizeInWords)
2224 :
Offset(offset), SizeInWords(sizeInWords) {}
2227 bool operator<(
const IvarInfo &other)
const {
2228 return Offset < other.Offset;
2233 class IvarLayoutBuilder {
2244 bool ForStrongLayout;
2247 bool IsDisordered =
false;
2253 CharUnits instanceEnd,
bool forStrongLayout)
2254 : CGM(CGM), InstanceBegin(instanceBegin), InstanceEnd(instanceEnd),
2255 ForStrongLayout(forStrongLayout) {
2260 template <
class Iterator,
class GetOffsetFn>
2261 void visitAggregate(Iterator begin, Iterator end,
2263 const GetOffsetFn &getOffset);
2271 bool hasBitmapData()
const {
return !IvarsInfo.empty(); }
2273 llvm::Constant *buildBitmap(CGObjCCommonMac &CGObjC,
2277 const unsigned char *s = buffer.data();
2278 for (
unsigned i = 0, e = buffer.size(); i < e; i++)
2280 printf(
"0x0%x%s", s[i], s[i] != 0 ?
", " :
"");
2282 printf(
"0x%x%s", s[i], s[i] != 0 ?
", " :
"");
2288 llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(
CodeGenModule &CGM,
2291 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2292 if (CGM.
getLangOpts().getGC() == LangOptions::NonGC)
2295 IvarLayoutBuilder builder(CGM, CharUnits::Zero(), blockInfo.
BlockSize,
2298 builder.visitBlock(blockInfo);
2300 if (!builder.hasBitmapData())
2304 llvm::Constant *C = builder.buildBitmap(*
this, buffer);
2305 if (CGM.
getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
2306 printf(
"\n block variable layout for block: ");
2307 builder.dump(buffer);
2313 void IvarLayoutBuilder::visitBlock(
const CGBlockInfo &blockInfo) {
2316 IvarsInfo.push_back(IvarInfo(CharUnits::Zero(), 1));
2326 for (
const auto &CI : blockDecl->
captures()) {
2327 const VarDecl *variable = CI.getVariable();
2339 if (fieldOffset < lastFieldOffset)
2340 IsDisordered =
true;
2341 lastFieldOffset = fieldOffset;
2345 IvarsInfo.push_back(IvarInfo(fieldOffset, 1));
2349 assert(!type->
isArrayType() &&
"array variable should not be caught");
2351 visitRecord(record, fieldOffset);
2357 if (GCAttr == Qualifiers::Strong) {
2360 IvarsInfo.push_back(IvarInfo(fieldOffset, 1));
2376 return Qualifiers::OCL_None;
2380 return ByrefLayout ? Qualifiers::OCL_ExplicitNone : Qualifiers::OCL_Strong;
2382 return Qualifiers::OCL_None;
2385 void CGObjCCommonMac::UpdateRunSkipBlockVars(
bool IsByref,
2391 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset,
2393 else if (LifeTime == Qualifiers::OCL_Strong)
2394 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset,
2396 else if (LifeTime == Qualifiers::OCL_Weak)
2397 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset,
2399 else if (LifeTime == Qualifiers::OCL_ExplicitNone)
2400 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset,
2403 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES,
2408 void CGObjCCommonMac::BuildRCRecordLayout(
const llvm::StructLayout *RecLayout,
2413 bool IsUnion = (RD && RD->
isUnion());
2414 CharUnits MaxUnionSize = CharUnits::Zero();
2416 const FieldDecl *LastFieldBitfieldOrUnnamed =
nullptr;
2417 CharUnits MaxFieldOffset = CharUnits::Zero();
2418 CharUnits LastBitfieldOrUnnamedOffset = CharUnits::Zero();
2420 if (RecFields.empty())
2424 for (
unsigned i = 0, e = RecFields.size(); i != e; ++i) {
2434 LastFieldBitfieldOrUnnamed = Field;
2435 LastBitfieldOrUnnamedOffset = FieldOffset;
2439 LastFieldBitfieldOrUnnamed =
nullptr;
2446 BytePos + FieldOffset, HasUnion);
2452 dyn_cast_or_null<ConstantArrayType>(Array);
2453 uint64_t ElCount = CArray->
getSize().getZExtValue();
2454 assert(CArray &&
"only array with known element size is supported");
2458 dyn_cast_or_null<ConstantArrayType>(Array);
2459 ElCount *= CArray->
getSize().getZExtValue();
2463 int OldIndex = RunSkipBlockVars.size() - 1;
2465 BuildRCBlockVarRecordLayout(RT, BytePos + FieldOffset,
2471 for (
int FirstIndex = RunSkipBlockVars.size() - 1 ;ElIx < ElCount; ElIx++) {
2473 for (
int i = OldIndex+1; i <= FirstIndex; ++i)
2474 RunSkipBlockVars.push_back(
2475 RUN_SKIP(RunSkipBlockVars[i].opcode,
2476 RunSkipBlockVars[i].block_var_bytepos + Size*ElIx,
2477 RunSkipBlockVars[i].block_var_size));
2485 if (UnionIvarSize > MaxUnionSize) {
2486 MaxUnionSize = UnionIvarSize;
2488 MaxFieldOffset = FieldOffset;
2491 UpdateRunSkipBlockVars(
false,
2492 getBlockCaptureLifetime(FQT, ByrefLayout),
2493 BytePos + FieldOffset,
2498 if (LastFieldBitfieldOrUnnamed) {
2499 if (LastFieldBitfieldOrUnnamed->
isBitField()) {
2501 uint64_t BitFieldSize
2503 unsigned UnsSize = (BitFieldSize / ByteSizeInBits) +
2504 ((BitFieldSize % ByteSizeInBits) != 0);
2505 CharUnits Size = CharUnits::fromQuantity(UnsSize);
2506 Size += LastBitfieldOrUnnamedOffset;
2507 UpdateRunSkipBlockVars(
false,
2508 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
2510 BytePos + LastBitfieldOrUnnamedOffset,
2513 assert(!LastFieldBitfieldOrUnnamed->
getIdentifier() &&
"Expected unnamed");
2517 UpdateRunSkipBlockVars(
false,
2518 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
2520 BytePos + LastBitfieldOrUnnamedOffset,
2526 UpdateRunSkipBlockVars(
false,
2527 getBlockCaptureLifetime(MaxField->
getType(), ByrefLayout),
2528 BytePos + MaxFieldOffset,
2532 void CGObjCCommonMac::BuildRCBlockVarRecordLayout(
const RecordType *RT,
2539 const llvm::StructLayout *RecLayout =
2540 CGM.
getDataLayout().getStructLayout(cast<llvm::StructType>(Ty));
2542 BuildRCRecordLayout(RecLayout, RD, Fields, BytePos, HasUnion, ByrefLayout);
2554 uint64_t CGObjCCommonMac::InlineLayoutInstruction(
2557 if (Layout.size() <= 3) {
2558 unsigned size = Layout.size();
2559 unsigned strong_word_count = 0, byref_word_count=0, weak_word_count=0;
2561 enum BLOCK_LAYOUT_OPCODE opcode ;
2565 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2566 if (opcode == BLOCK_LAYOUT_STRONG)
2567 strong_word_count = (inst & 0xF)+1;
2571 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2572 if (opcode == BLOCK_LAYOUT_BYREF)
2573 byref_word_count = (inst & 0xF)+1;
2577 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2578 if (opcode == BLOCK_LAYOUT_WEAK)
2579 weak_word_count = (inst & 0xF)+1;
2586 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2587 if (opcode == BLOCK_LAYOUT_STRONG) {
2588 strong_word_count = (inst & 0xF)+1;
2590 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2591 if (opcode == BLOCK_LAYOUT_BYREF)
2592 byref_word_count = (inst & 0xF)+1;
2593 else if (opcode == BLOCK_LAYOUT_WEAK)
2594 weak_word_count = (inst & 0xF)+1;
2598 else if (opcode == BLOCK_LAYOUT_BYREF) {
2599 byref_word_count = (inst & 0xF)+1;
2601 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2602 if (opcode == BLOCK_LAYOUT_WEAK)
2603 weak_word_count = (inst & 0xF)+1;
2613 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2614 if (opcode == BLOCK_LAYOUT_STRONG)
2615 strong_word_count = (inst & 0xF)+1;
2616 else if (opcode == BLOCK_LAYOUT_BYREF)
2617 byref_word_count = (inst & 0xF)+1;
2618 else if (opcode == BLOCK_LAYOUT_WEAK)
2619 weak_word_count = (inst & 0xF)+1;
2631 if (strong_word_count == 16 || byref_word_count == 16 || weak_word_count == 16)
2635 (strong_word_count != 0) + (byref_word_count != 0) + (weak_word_count != 0);
2637 if (size == count) {
2638 if (strong_word_count)
2639 Result = strong_word_count;
2641 if (byref_word_count)
2642 Result += byref_word_count;
2644 if (weak_word_count)
2645 Result += weak_word_count;
2651 llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(
bool ComputeByrefLayout) {
2652 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2653 if (RunSkipBlockVars.empty())
2657 unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2661 llvm::array_pod_sort(RunSkipBlockVars.begin(), RunSkipBlockVars.end());
2664 unsigned size = RunSkipBlockVars.size();
2665 for (
unsigned i = 0; i < size; i++) {
2666 enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode;
2667 CharUnits start_byte_pos = RunSkipBlockVars[i].block_var_bytepos;
2668 CharUnits end_byte_pos = start_byte_pos;
2671 if (opcode == RunSkipBlockVars[j].opcode) {
2672 end_byte_pos = RunSkipBlockVars[j++].block_var_bytepos;
2679 end_byte_pos - start_byte_pos + RunSkipBlockVars[j-1].block_var_size;
2682 RunSkipBlockVars[j].block_var_bytepos -
2683 RunSkipBlockVars[j-1].block_var_bytepos - RunSkipBlockVars[j-1].block_var_size;
2684 size_in_bytes += gap;
2686 CharUnits residue_in_bytes = CharUnits::Zero();
2687 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) {
2688 residue_in_bytes = size_in_bytes % WordSizeInBytes;
2689 size_in_bytes -= residue_in_bytes;
2690 opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS;
2693 unsigned size_in_words = size_in_bytes.
getQuantity() / WordSizeInBytes;
2694 while (size_in_words >= 16) {
2697 unsigned char inst = (opcode << 4) | 0xf;
2698 Layout.push_back(inst);
2699 size_in_words -= 16;
2701 if (size_in_words > 0) {
2704 unsigned char inst = (opcode << 4) | (size_in_words-1);
2705 Layout.push_back(inst);
2707 if (residue_in_bytes > CharUnits::Zero()) {
2708 unsigned char inst =
2709 (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) | (residue_in_bytes.
getQuantity()-1);
2710 Layout.push_back(inst);
2714 while (!Layout.empty()) {
2715 unsigned char inst = Layout.back();
2716 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2717 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES || opcode == BLOCK_LAYOUT_NON_OBJECT_WORDS)
2723 uint64_t Result = InlineLayoutInstruction(Layout);
2727 if (ComputeByrefLayout)
2728 printf(
"\n Inline BYREF variable layout: ");
2730 printf(
"\n Inline block variable layout: ");
2731 printf(
"0x0%" PRIx64
"", Result);
2732 if (
auto numStrong = (Result & 0xF00) >> 8)
2733 printf(
", BL_STRONG:%d", (
int) numStrong);
2734 if (
auto numByref = (Result & 0x0F0) >> 4)
2735 printf(
", BL_BYREF:%d", (
int) numByref);
2736 if (
auto numWeak = (Result & 0x00F) >> 0)
2737 printf(
", BL_WEAK:%d", (
int) numWeak);
2738 printf(
", BL_OPERATOR:0\n");
2740 return llvm::ConstantInt::get(CGM.
IntPtrTy, Result);
2743 unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0;
2744 Layout.push_back(inst);
2746 for (
unsigned i = 0, e = Layout.size(); i != e; i++)
2747 BitMap += Layout[i];
2750 if (ComputeByrefLayout)
2751 printf(
"\n Byref variable layout: ");
2753 printf(
"\n Block variable layout: ");
2754 for (
unsigned i = 0, e = BitMap.size(); i != e; i++) {
2755 unsigned char inst = BitMap[i];
2756 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2759 case BLOCK_LAYOUT_OPERATOR:
2763 case BLOCK_LAYOUT_NON_OBJECT_BYTES:
2764 printf(
"BL_NON_OBJECT_BYTES:");
2766 case BLOCK_LAYOUT_NON_OBJECT_WORDS:
2767 printf(
"BL_NON_OBJECT_WORD:");
2769 case BLOCK_LAYOUT_STRONG:
2772 case BLOCK_LAYOUT_BYREF:
2775 case BLOCK_LAYOUT_WEAK:
2778 case BLOCK_LAYOUT_UNRETAINED:
2779 printf(
"BL_UNRETAINED:");
2784 printf(
"%d", (inst & 0xf) + delta);
2792 auto *Entry = CreateCStringLiteral(BitMap, ObjCLabelType::ClassName,
2798 llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(
CodeGenModule &CGM,
2800 assert(CGM.
getLangOpts().getGC() == LangOptions::NonGC);
2802 RunSkipBlockVars.clear();
2803 bool hasUnion =
false;
2807 unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2812 const llvm::StructLayout *layout =
2818 UpdateRunSkipBlockVars(
false, Qualifiers::OCL_None,
2822 for (
const auto &CI : blockDecl->
captures()) {
2823 const VarDecl *variable = CI.getVariable();
2832 CharUnits::fromQuantity(layout->getElementOffset(capture.
getIndex()));
2834 assert(!type->
isArrayType() &&
"array variable should not be caught");
2837 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion);
2842 fieldSize = CharUnits::fromQuantity(WordSizeInBytes);
2845 UpdateRunSkipBlockVars(CI.isByRef(), getBlockCaptureLifetime(type,
false),
2846 fieldOffset, fieldSize);
2848 return getBitmapBlockLayout(
false);
2853 assert(CGM.
getLangOpts().getGC() == LangOptions::NonGC);
2854 assert(!T->
isArrayType() &&
"__block array variable should not be caught");
2856 RunSkipBlockVars.clear();
2857 bool hasUnion =
false;
2859 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion,
true );
2860 llvm::Constant *Result = getBitmapBlockLayout(
true);
2861 if (isa<llvm::ConstantInt>(Result))
2862 Result = llvm::ConstantExpr::getIntToPtr(Result, CGM.
Int8PtrTy);
2865 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2875 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
2876 ObjCTypes.getExternalProtocolPtrTy());
2888 GetOrEmitProtocol(PD);
2891 llvm::Constant *CGObjCCommonMac::GetProtocolRef(
const ObjCProtocolDecl *PD) {
2893 return GetOrEmitProtocol(PD);
2895 return GetOrEmitProtocolRef(PD);
2898 llvm::Value *CGObjCCommonMac::EmitClassRefViaRuntime(
2901 ObjCCommonTypesHelper &ObjCTypes) {
2902 llvm::Constant *lookUpClassFn = ObjCTypes.getLookUpClassFn();
2912 llvm::CallInst *call = CGF.
Builder.CreateCall(lookUpClassFn, className);
2913 call->setDoesNotThrow();
2930 llvm::GlobalVariable *Entry = Protocols[PD->
getIdentifier()];
2933 if (Entry && Entry->hasInitializer())
2945 auto methodLists = ProtocolMethodLists::get(PD);
2948 auto values = builder.beginStruct(ObjCTypes.ProtocolTy);
2949 values.add(EmitProtocolExtension(PD, methodLists));
2951 values.add(EmitProtocolList(
"OBJC_PROTOCOL_REFS_" + PD->
getName(),
2953 values.add(methodLists.emitMethodList(
this, PD,
2954 ProtocolMethodLists::RequiredInstanceMethods));
2955 values.add(methodLists.emitMethodList(
this, PD,
2956 ProtocolMethodLists::RequiredClassMethods));
2960 assert(Entry->hasPrivateLinkage());
2961 values.finishAndSetAsInitializer(Entry);
2963 Entry = values.finishAndCreateGlobal(
"OBJC_PROTOCOL_" + PD->
getName(),
2966 llvm::GlobalValue::PrivateLinkage);
2967 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
2976 llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD) {
2977 llvm::GlobalVariable *&Entry = Protocols[PD->
getIdentifier()];
2983 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolTy,
2984 false, llvm::GlobalValue::PrivateLinkage,
2985 nullptr,
"OBJC_PROTOCOL_" + PD->
getName());
2986 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
2988 Entry->setAlignment(4);
3006 const ProtocolMethodLists &methodLists) {
3007 auto optInstanceMethods =
3008 methodLists.emitMethodList(
this, PD,
3009 ProtocolMethodLists::OptionalInstanceMethods);
3010 auto optClassMethods =
3011 methodLists.emitMethodList(
this, PD,
3012 ProtocolMethodLists::OptionalClassMethods);
3014 auto extendedMethodTypes =
3015 EmitProtocolMethodTypes(
"OBJC_PROTOCOL_METHOD_TYPES_" + PD->
getName(),
3016 methodLists.emitExtendedTypesArray(
this),
3019 auto instanceProperties =
3020 EmitPropertyList(
"OBJC_$_PROP_PROTO_LIST_" + PD->
getName(),
nullptr, PD,
3022 auto classProperties =
3023 EmitPropertyList(
"OBJC_$_CLASS_PROP_PROTO_LIST_" + PD->
getName(),
nullptr,
3024 PD, ObjCTypes,
true);
3027 if (optInstanceMethods->isNullValue() &&
3028 optClassMethods->isNullValue() &&
3029 extendedMethodTypes->isNullValue() &&
3030 instanceProperties->isNullValue() &&
3031 classProperties->isNullValue()) {
3032 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
3036 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
3039 auto values = builder.beginStruct(ObjCTypes.ProtocolExtensionTy);
3040 values.addInt(ObjCTypes.IntTy, size);
3041 values.add(optInstanceMethods);
3042 values.add(optClassMethods);
3043 values.add(instanceProperties);
3044 values.add(extendedMethodTypes);
3045 values.add(classProperties);
3048 return CreateMetadataVar(
"\01l_OBJC_PROTOCOLEXT_" + PD->
getName(), values,
3060 CGObjCMac::EmitProtocolList(Twine name,
3065 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
3068 auto values = builder.beginStruct();
3071 values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
3074 auto countSlot = values.addPlaceholder();
3076 auto refsArray = values.beginArray(ObjCTypes.ProtocolPtrTy);
3077 for (; begin != end; ++begin) {
3078 refsArray.add(GetProtocolRef(*begin));
3080 auto count = refsArray.size();
3083 refsArray.addNullPointer(ObjCTypes.ProtocolPtrTy);
3085 refsArray.finishAndAddTo(values);
3086 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
3089 if (CGM.
getTriple().isOSBinFormatMachO())
3090 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3092 llvm::GlobalVariable *GV =
3093 CreateMetadataVar(name, values, section, CGM.
getPointerAlign(),
false);
3094 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
3101 bool IsClassProperty) {
3106 if (IsClassProperty != PD->isClassProperty())
3110 Properties.push_back(PD);
3126 llvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine
Name,
3127 const Decl *Container,
3129 const ObjCCommonTypesHelper &ObjCTypes,
3130 bool IsClassProperty) {
3131 if (IsClassProperty) {
3135 if ((Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 11)) ||
3136 (Triple.isiOS() && Triple.isOSVersionLT(9)))
3137 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3141 llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
3146 if (IsClassProperty != PD->isClassProperty())
3149 Properties.push_back(PD);
3153 if (IsClassProperty != PD->isClassProperty())
3159 Properties.push_back(PD);
3163 for (
const auto *
P : OID->all_referenced_protocols())
3167 for (
const auto *
P : CD->protocols())
3172 if (Properties.empty())
3173 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3175 unsigned propertySize =
3179 auto values = builder.beginStruct();
3180 values.addInt(ObjCTypes.IntTy, propertySize);
3181 values.addInt(ObjCTypes.IntTy, Properties.size());
3182 auto propertiesArray = values.beginArray(ObjCTypes.PropertyTy);
3183 for (
auto PD : Properties) {
3184 auto property = propertiesArray.beginStruct(ObjCTypes.PropertyTy);
3186 property.add(GetPropertyTypeString(PD, Container));
3187 property.finishAndAddTo(propertiesArray);
3189 propertiesArray.finishAndAddTo(values);
3192 if (CGM.
getTriple().isOSBinFormatMachO())
3193 Section = (ObjCABI == 2) ?
"__DATA, __objc_const"
3194 :
"__OBJC,__property,regular,no_dead_strip";
3196 llvm::GlobalVariable *GV =
3197 CreateMetadataVar(Name, values, Section, CGM.
getPointerAlign(),
true);
3198 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy);
3202 CGObjCCommonMac::EmitProtocolMethodTypes(Twine Name,
3204 const ObjCCommonTypesHelper &ObjCTypes) {
3206 if (MethodTypes.empty())
3207 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy);
3209 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
3210 MethodTypes.size());
3211 llvm::Constant *Init = llvm::ConstantArray::get(AT, MethodTypes);
3214 if (CGM.
getTriple().isOSBinFormatMachO() && ObjCABI == 2)
3215 Section =
"__DATA, __objc_const";
3217 llvm::GlobalVariable *GV =
3219 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.Int8PtrPtrTy);
3235 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.CategoryTy);
3246 llvm::raw_svector_ostream(ExtName) << Interface->
getName() <<
'_'
3250 auto Values =
Builder.beginStruct(ObjCTypes.CategoryTy);
3258 for (
const auto *MD : OCD->
methods()) {
3259 Methods[
unsigned(MD->isClassMethod())].push_back(MD);
3262 Values.add(GetClassName(OCD->
getName()));
3266 Values.add(emitMethodList(ExtName, MethodListType::CategoryInstanceMethods,
3267 Methods[InstanceMethods]));
3268 Values.add(emitMethodList(ExtName, MethodListType::CategoryClassMethods,
3269 Methods[ClassMethods]));
3272 EmitProtocolList(
"OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
3275 Values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
3277 Values.addInt(ObjCTypes.IntTy, Size);
3281 Values.add(EmitPropertyList(
"\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
3283 Values.add(EmitPropertyList(
"\01l_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(),
3286 Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
3287 Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
3290 llvm::GlobalVariable *GV =
3291 CreateMetadataVar(
"OBJC_CATEGORY_" + ExtName.str(), Values,
3292 "__OBJC,__category,regular,no_dead_strip",
3294 DefinedCategories.push_back(GV);
3295 DefinedCategoryNames.insert(llvm::CachedHashString(ExtName));
3297 MethodDefinitions.clear();
3357 for (
auto field : recType->getDecl()->fields()) {
3372 assert(CGM.
getLangOpts().getGC() == LangOptions::NonGC);
3410 llvm::Constant *Protocols =
3411 EmitProtocolList(
"OBJC_CLASS_PROTOCOLS_" + ID->
getName(),
3418 bool hasMRCWeak =
false;
3438 for (
const auto *MD : ID->
methods()) {
3439 Methods[
unsigned(MD->isClassMethod())].push_back(MD);
3443 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
3447 if (GetMethodDefinition(MD))
3448 Methods[InstanceMethods].push_back(MD);
3450 if (GetMethodDefinition(MD))
3451 Methods[InstanceMethods].push_back(MD);
3456 auto values = builder.beginStruct(ObjCTypes.ClassTy);
3457 values.add(EmitMetaClass(ID, Protocols, Methods[ClassMethods]));
3460 LazySymbols.insert(Super->getIdentifier());
3462 values.addBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
3463 ObjCTypes.ClassPtrTy);
3465 values.addNullPointer(ObjCTypes.ClassPtrTy);
3469 values.addInt(ObjCTypes.LongTy, 0);
3470 values.addInt(ObjCTypes.LongTy, Flags);
3471 values.addInt(ObjCTypes.LongTy, Size.
getQuantity());
3472 values.add(EmitIvarList(ID,
false));
3473 values.add(emitMethodList(ID->
getName(), MethodListType::InstanceMethods,
3474 Methods[InstanceMethods]));
3476 values.addNullPointer(ObjCTypes.CachePtrTy);
3477 values.add(Protocols);
3478 values.add(BuildStrongIvarLayout(ID, CharUnits::Zero(), Size));
3479 values.add(EmitClassExtension(ID, Size, hasMRCWeak,
3482 std::string
Name(
"OBJC_CLASS_");
3484 const char *Section =
"__OBJC,__class,regular,no_dead_strip";
3486 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3488 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3489 "Forward metaclass reference has incorrect type.");
3490 values.finishAndSetAsInitializer(GV);
3491 GV->setSection(Section);
3495 GV = CreateMetadataVar(Name, values, Section, CGM.
getPointerAlign(),
true);
3496 DefinedClasses.push_back(GV);
3497 ImplementedClasses.push_back(Interface);
3499 MethodDefinitions.clear();
3503 llvm::Constant *Protocols,
3506 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ClassTy);
3512 auto values = builder.beginStruct(ObjCTypes.ClassTy);
3518 ObjCTypes.ClassPtrTy);
3523 values.addBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
3524 ObjCTypes.ClassPtrTy);
3526 values.addNullPointer(ObjCTypes.ClassPtrTy);
3530 values.addInt(ObjCTypes.LongTy, 0);
3531 values.addInt(ObjCTypes.LongTy, Flags);
3532 values.addInt(ObjCTypes.LongTy, Size);
3533 values.add(EmitIvarList(ID,
true));
3534 values.add(emitMethodList(ID->
getName(), MethodListType::ClassMethods,
3537 values.addNullPointer(ObjCTypes.CachePtrTy);
3538 values.add(Protocols);
3540 values.addNullPointer(ObjCTypes.Int8PtrTy);
3542 values.add(EmitClassExtension(ID, CharUnits::Zero(),
false,
3545 std::string
Name(
"OBJC_METACLASS_");
3549 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3551 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3552 "Forward metaclass reference has incorrect type.");
3553 values.finishAndSetAsInitializer(GV);
3557 llvm::GlobalValue::PrivateLinkage);
3559 GV->setSection(
"__OBJC,__meta_class,regular,no_dead_strip");
3576 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3578 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
3579 llvm::GlobalValue::PrivateLinkage,
nullptr,
3582 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3583 "Forward metaclass reference has incorrect type.");
3589 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3592 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
3593 llvm::GlobalValue::PrivateLinkage,
nullptr,
3596 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3597 "Forward class metadata reference has incorrect type.");
3617 llvm::Constant *layout;
3619 layout = llvm::ConstantPointerNull::get(CGM.
Int8PtrTy);
3621 layout = BuildWeakIvarLayout(ID, CharUnits::Zero(), InstanceSize,
3626 llvm::Constant *propertyList =
3627 EmitPropertyList((isMetaclass ? Twine(
"\01l_OBJC_$_CLASS_PROP_LIST_")
3628 : Twine(
"\01l_OBJC_$_PROP_LIST_"))
3633 if (layout->isNullValue() && propertyList->isNullValue()) {
3634 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
3638 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
3641 auto values = builder.beginStruct(ObjCTypes.ClassExtensionTy);
3642 values.addInt(ObjCTypes.IntTy, size);
3644 values.add(propertyList);
3646 return CreateMetadataVar(
"OBJC_CLASSEXT_" + ID->
getName(), values,
3647 "__OBJC,__class_ext,regular,no_dead_strip",
3671 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3676 auto ivarList = builder.beginStruct();
3677 auto countSlot = ivarList.addPlaceholder();
3678 auto ivars = ivarList.beginArray(ObjCTypes.IvarTy);
3683 if (!IVD->getDeclName())
3686 auto ivar = ivars.beginStruct(ObjCTypes.IvarTy);
3687 ivar.add(GetMethodVarName(IVD->getIdentifier()));
3688 ivar.add(GetMethodVarType(IVD));
3689 ivar.addInt(ObjCTypes.IntTy, ComputeIvarBaseOffset(CGM, OID, IVD));
3690 ivar.finishAndAddTo(ivars);
3694 auto count = ivars.size();
3698 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3701 ivars.finishAndAddTo(ivarList);
3702 ivarList.fillPlaceholderWithInt(countSlot, ObjCTypes.IntTy, count);
3704 llvm::GlobalVariable *GV;
3707 CreateMetadataVar(
"OBJC_CLASS_VARIABLES_" + ID->
getName(), ivarList,
3708 "__OBJC,__class_vars,regular,no_dead_strip",
3711 GV = CreateMetadataVar(
"OBJC_INSTANCE_VARIABLES_" + ID->
getName(), ivarList,
3712 "__OBJC,__instance_vars,regular,no_dead_strip",
3714 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy);
3725 auto description = builder.
beginStruct(ObjCTypes.MethodDescriptionTy);
3726 description.addBitCast(GetMethodVarName(MD->
getSelector()),
3727 ObjCTypes.SelectorPtrTy);
3728 description.add(GetMethodVarType(MD));
3729 description.finishAndAddTo(builder);
3741 llvm::Function *fn = GetMethodDefinition(MD);
3742 assert(fn &&
"no definition registered for method");
3744 auto method = builder.
beginStruct(ObjCTypes.MethodTy);
3745 method.addBitCast(GetMethodVarName(MD->
getSelector()),
3746 ObjCTypes.SelectorPtrTy);
3747 method.add(GetMethodVarType(MD));
3748 method.addBitCast(fn, ObjCTypes.Int8PtrTy);
3749 method.finishAndAddTo(builder);
3765 llvm::Constant *CGObjCMac::emitMethodList(Twine name,
MethodListType MLT,
3769 bool forProtocol =
false;
3771 case MethodListType::CategoryInstanceMethods:
3772 prefix =
"OBJC_CATEGORY_INSTANCE_METHODS_";
3773 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
3774 forProtocol =
false;
3776 case MethodListType::CategoryClassMethods:
3777 prefix =
"OBJC_CATEGORY_CLASS_METHODS_";
3778 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3779 forProtocol =
false;
3781 case MethodListType::InstanceMethods:
3782 prefix =
"OBJC_INSTANCE_METHODS_";
3783 section =
"__OBJC,__inst_meth,regular,no_dead_strip";
3784 forProtocol =
false;
3786 case MethodListType::ClassMethods:
3787 prefix =
"OBJC_CLASS_METHODS_";
3788 section =
"__OBJC,__cls_meth,regular,no_dead_strip";
3789 forProtocol =
false;
3791 case MethodListType::ProtocolInstanceMethods:
3792 prefix =
"OBJC_PROTOCOL_INSTANCE_METHODS_";
3793 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
3796 case MethodListType::ProtocolClassMethods:
3797 prefix =
"OBJC_PROTOCOL_CLASS_METHODS_";
3798 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3801 case MethodListType::OptionalProtocolInstanceMethods:
3802 prefix =
"OBJC_PROTOCOL_INSTANCE_METHODS_OPT_";
3803 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
3806 case MethodListType::OptionalProtocolClassMethods:
3807 prefix =
"OBJC_PROTOCOL_CLASS_METHODS_OPT_";
3808 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3814 if (methods.empty())
3815 return llvm::Constant::getNullValue(forProtocol
3816 ? ObjCTypes.MethodDescriptionListPtrTy
3817 : ObjCTypes.MethodListPtrTy);
3824 values.addInt(ObjCTypes.IntTy, methods.size());
3825 auto methodArray = values.beginArray(ObjCTypes.MethodDescriptionTy);
3826 for (
auto MD : methods) {
3827 emitMethodDescriptionConstant(methodArray, MD);
3829 methodArray.finishAndAddTo(values);
3831 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
3833 return llvm::ConstantExpr::getBitCast(GV,
3834 ObjCTypes.MethodDescriptionListPtrTy);
3840 values.addNullPointer(ObjCTypes.Int8PtrTy);
3841 values.addInt(ObjCTypes.IntTy, methods.size());
3842 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
3843 for (
auto MD : methods) {
3844 emitMethodConstant(methodArray, MD);
3846 methodArray.finishAndAddTo(values);
3848 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
3850 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListPtrTy);
3853 llvm::Function *CGObjCCommonMac::GenerateMethod(
const ObjCMethodDecl *OMD,
3856 GetNameForMethod(OMD, CD, Name);
3859 llvm::FunctionType *MethodTy =
3861 llvm::Function *Method =
3866 MethodDefinitions.insert(std::make_pair(OMD, Method));
3871 llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
3876 llvm::GlobalVariable *GV =
3878 llvm::GlobalValue::PrivateLinkage);
3879 if (!Section.empty())
3880 GV->setSection(Section);
3886 llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
3887 llvm::Constant *Init,
3891 llvm::Type *Ty = Init->getType();
3892 llvm::GlobalVariable *GV =
3893 new llvm::GlobalVariable(CGM.
getModule(), Ty,
false,
3894 llvm::GlobalValue::PrivateLinkage, Init,
Name);
3895 if (!Section.empty())
3896 GV->setSection(Section);
3903 llvm::GlobalVariable *
3905 bool ForceNonFragileABI,
3906 bool NullTerminate) {
3909 case ObjCLabelType::ClassName: Label =
"OBJC_CLASS_NAME_";
break;
3910 case ObjCLabelType::MethodVarName: Label =
"OBJC_METH_VAR_NAME_";
break;
3911 case ObjCLabelType::MethodVarType: Label =
"OBJC_METH_VAR_TYPE_";
break;
3912 case ObjCLabelType::PropertyName: Label =
"OBJC_PROP_NAME_ATTR_";
break;
3915 bool NonFragile = ForceNonFragileABI || isNonFragileABI();
3919 case ObjCLabelType::ClassName:
3920 Section = NonFragile ?
"__TEXT,__objc_classname,cstring_literals"
3921 :
"__TEXT,__cstring,cstring_literals";
3923 case ObjCLabelType::MethodVarName:
3924 Section = NonFragile ?
"__TEXT,__objc_methname,cstring_literals"
3925 :
"__TEXT,__cstring,cstring_literals";
3927 case ObjCLabelType::MethodVarType:
3928 Section = NonFragile ?
"__TEXT,__objc_methtype,cstring_literals"
3929 :
"__TEXT,__cstring,cstring_literals";
3931 case ObjCLabelType::PropertyName:
3932 Section =
"__TEXT,__cstring,cstring_literals";
3936 llvm::Constant *
Value =
3937 llvm::ConstantDataArray::getString(VMContext, Name, NullTerminate);
3938 llvm::GlobalVariable *GV =
3939 new llvm::GlobalVariable(CGM.
getModule(), Value->getType(),
3941 llvm::GlobalValue::PrivateLinkage,
Value,
Label);
3942 if (CGM.
getTriple().isOSBinFormatMachO())
3943 GV->setSection(Section);
3944 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
3945 GV->setAlignment(CharUnits::One().getQuantity());
3951 llvm::Function *CGObjCMac::ModuleInitFunction() {
3957 llvm::Constant *CGObjCMac::GetPropertyGetFunction() {
3958 return ObjCTypes.getGetPropertyFn();
3961 llvm::Constant *CGObjCMac::GetPropertySetFunction() {
3962 return ObjCTypes.getSetPropertyFn();
3965 llvm::Constant *CGObjCMac::GetOptimizedPropertySetFunction(
bool atomic,
3967 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
3970 llvm::Constant *CGObjCMac::GetGetStructFunction() {
3971 return ObjCTypes.getCopyStructFn();
3974 llvm::Constant *CGObjCMac::GetSetStructFunction() {
3975 return ObjCTypes.getCopyStructFn();
3978 llvm::Constant *CGObjCMac::GetCppAtomicObjectGetFunction() {
3979 return ObjCTypes.getCppAtomicObjectFunction();
3982 llvm::Constant *CGObjCMac::GetCppAtomicObjectSetFunction() {
3983 return ObjCTypes.getCppAtomicObjectFunction();
3986 llvm::Constant *CGObjCMac::EnumerationMutationFunction() {
3987 return ObjCTypes.getEnumerationMutationFn();
3991 return EmitTryOrSynchronizedStmt(CGF, S);
3996 return EmitTryOrSynchronizedStmt(CGF, S);
4005 ObjCTypesHelper &ObjCTypes;
4006 PerformFragileFinally(
const Stmt *
S,
4010 ObjCTypesHelper *ObjCTypes)
4011 : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
4012 ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
4017 llvm::BasicBlock *FinallyCallExit =
4019 llvm::BasicBlock *FinallyNoCallExit =
4022 FinallyCallExit, FinallyNoCallExit);
4026 ExceptionData.getPointer());
4030 if (isa<ObjCAtTryStmt>(
S)) {
4032 cast<ObjCAtTryStmt>(
S).getFinallyStmt()) {
4034 if (flags.isForEHCleanup())
return;
4041 CGF.
EmitStmt(FinallyStmt->getFinallyBody());
4060 class FragileHazards {
4065 llvm::InlineAsm *ReadHazard;
4066 llvm::InlineAsm *WriteHazard;
4068 llvm::FunctionType *GetAsmFnType();
4070 void collectLocals();
4076 void emitWriteHazard();
4077 void emitHazardsInNewBlocks();
4089 if (Locals.empty())
return;
4092 for (llvm::Function::iterator
4094 BlocksBeforeTry.insert(&*I);
4096 llvm::FunctionType *AsmFnTy = GetAsmFnType();
4104 std::string Constraint;
4105 for (
unsigned I = 0,
E = Locals.size(); I !=
E; ++
I) {
4106 if (I) Constraint +=
',';
4110 ReadHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
4118 std::string Constraint;
4119 for (
unsigned I = 0,
E = Locals.size(); I !=
E; ++
I) {
4120 if (I) Constraint +=
',';
4121 Constraint +=
"=*m";
4124 WriteHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
4129 void FragileHazards::emitWriteHazard() {
4130 if (Locals.empty())
return;
4136 assert(!Locals.empty());
4137 llvm::CallInst *call = Builder.CreateCall(ReadHazard, Locals);
4138 call->setDoesNotThrow();
4144 void FragileHazards::emitHazardsInNewBlocks() {
4145 if (Locals.empty())
return;
4150 for (llvm::Function::iterator
4151 FI = CGF.
CurFn->begin(), FE = CGF.
CurFn->end(); FI != FE; ++FI) {
4152 llvm::BasicBlock &BB = *FI;
4153 if (BlocksBeforeTry.count(&BB))
continue;
4156 for (llvm::BasicBlock::iterator
4157 BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) {
4158 llvm::Instruction &I = *BI;
4162 if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(
I))
continue;
4163 if (isa<llvm::IntrinsicInst>(I))
4168 llvm::CallSite CS(&I);
4169 if (CS.doesNotThrow())
continue;
4176 Builder.SetInsertPoint(&BB, BI);
4177 emitReadHazard(Builder);
4190 void FragileHazards::collectLocals() {
4198 llvm::BasicBlock &Entry = CGF.
CurFn->getEntryBlock();
4199 for (llvm::BasicBlock::iterator
4200 I = Entry.begin(),
E = Entry.end(); I !=
E; ++
I)
4201 if (isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I))
4202 Locals.push_back(&*I);
4205 llvm::FunctionType *FragileHazards::GetAsmFnType() {
4207 for (
unsigned i = 0, e = Locals.size(); i != e; ++i)
4208 tys[i] = Locals[i]->getType();
4209 return llvm::FunctionType::get(CGF.
VoidTy, tys,
false);
4326 bool isTry = isa<ObjCAtTryStmt>(
S);
4343 Address SyncArgSlot = Address::invalid();
4346 CGF.
EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
4359 "exceptiondata.ptr");
4365 FragileHazards Hazards(CGF);
4381 Address PropagatingExnVar = Address::invalid();
4394 ExceptionData.getPointer());
4397 llvm::Constant *Zero = llvm::ConstantInt::get(CGF.
Builder.getInt32Ty(), 0);
4400 ObjCTypes.ExceptionDataTy, ExceptionData.getPointer(), GEPIndexes,
4403 ObjCTypes.getSetJmpFn(), SetJmpBuffer,
"setjmp_result");
4404 SetJmpResult->setCanReturnTwice();
4411 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
4412 CGF.
Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
4417 CGF.
EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
4418 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
4420 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.
Builder.saveAndClearIP();
4426 Hazards.emitWriteHazard();
4430 if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
4439 llvm::CallInst *Caught =
4441 ExceptionData.getPointer(),
"caught");
4451 llvm::BasicBlock *CatchBlock =
nullptr;
4452 llvm::BasicBlock *CatchHandler =
nullptr;
4458 "propagating_exception");
4464 ExceptionData.getPointer());
4466 llvm::CallInst *SetJmpResult =
4468 SetJmpBuffer,
"setjmp.result");
4469 SetJmpResult->setCanReturnTwice();
4472 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
4476 CGF.
Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
4486 bool AllMatched =
false;
4516 EmitInitOfCatchParam(CGF, Caught, CatchParam);
4522 CatchVarCleanups.ForceCleanup();
4528 assert(OPT &&
"Unexpected non-object pointer type in @catch");
4533 assert(IDecl &&
"Catch parameter must have Objective-C type!");
4539 llvm::CallInst *Match =
4541 matchArgs,
"match");
4546 CGF.
Builder.CreateCondBr(CGF.
Builder.CreateIsNotNull(Match,
"matched"),
4547 MatchedBlock, NextCatchBlock);
4563 EmitInitOfCatchParam(CGF, Tmp, CatchParam);
4568 CatchVarCleanups.ForceCleanup();
4579 if (Caught->use_empty())
4580 Caught->eraseFromParent();
4596 assert(PropagatingExnVar.
isValid());
4597 llvm::CallInst *NewCaught =
4599 ExceptionData.getPointer(),
"caught");
4609 Hazards.emitHazardsInNewBlocks();
4612 CGF.
Builder.restoreIP(TryFallthroughIP);
4616 CGF.
EmitBlock(FinallyEnd.getBlock(),
true);
4619 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
4624 if (PropagatingExnVar.
isValid()) {
4629 llvm::CallInst *Caught =
4631 ExceptionData.getPointer());
4632 PropagatingExn = Caught;
4637 CGF.
Builder.CreateUnreachable();
4640 CGF.
Builder.restoreIP(SavedIP);
4645 bool ClearInsertionPoint) {
4654 "Unexpected rethrow outside @catch block.");
4658 CGF.
EmitRuntimeCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
4659 ->setDoesNotReturn();
4660 CGF.
Builder.CreateUnreachable();
4663 if (ClearInsertionPoint)
4664 CGF.
Builder.ClearInsertionPoint();
4674 ObjCTypes.PtrObjectPtrTy);
4687 llvm::Type * SrcTy = src->
getType();
4688 if (!isa<llvm::PointerType>(SrcTy)) {
4689 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(SrcTy);
4690 assert(Size <= 8 && "does not support size > 8
");
4691 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
4692 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
4693 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4695 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4696 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4697 llvm::Value *args[] = { src, dst.getPointer() };
4698 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(),
4699 args, "weakassign
");
4705 void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
4706 llvm::Value *src, Address dst,
4708 llvm::Type * SrcTy = src->getType();
4709 if (!isa<llvm::PointerType>(SrcTy)) {
4710 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4711 assert(Size <= 8 && "does
not support size > 8
");
4712 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
4713 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
4714 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4716 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4717 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4718 llvm::Value *args[] = { src, dst.getPointer() };
4720 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(),
4721 args, "globalassign
");
4723 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(),
4724 args, "threadlocalassign
");
4730 void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
4731 llvm::Value *src, Address dst,
4732 llvm::Value *ivarOffset) {
4733 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is
NULL");
4734 llvm::Type * SrcTy = src->getType();
4735 if (!isa<llvm::PointerType>(SrcTy)) {
4736 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4737 assert(Size <= 8 && "does
not support size > 8
");
4738 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
4739 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
4740 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4742 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4743 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4744 llvm::Value *args[] = { src, dst.getPointer(), ivarOffset };
4745 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
4751 void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
4752 llvm::Value *src, Address dst) {
4753 llvm::Type * SrcTy = src->getType();
4754 if (!isa<llvm::PointerType>(SrcTy)) {
4755 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4756 assert(Size <= 8 && "does
not support size > 8
");
4757 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
4758 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
4759 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4761 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4762 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4763 llvm::Value *args[] = { src, dst.getPointer() };
4764 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(),
4765 args, "strongassign
");
4768 void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
4771 llvm::Value *size) {
4772 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
4773 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
4774 llvm::Value *args[] = { DestPtr.getPointer(), SrcPtr.getPointer(), size };
4775 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
4780 LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
4782 llvm::Value *BaseValue,
4783 const ObjCIvarDecl *Ivar,
4784 unsigned CVRQualifiers) {
4785 const ObjCInterfaceDecl *ID =
4786 ObjectTy->getAs<ObjCObjectType>()->getInterface();
4787 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
4788 EmitIvarOffset(CGF, ID, Ivar));
4791 llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
4792 const ObjCInterfaceDecl *Interface,
4793 const ObjCIvarDecl *Ivar) {
4794 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
4795 return llvm::ConstantInt::get(
4796 CGM.getTypes().ConvertType(CGM.getContext().LongTy),
4800 /* *** Private Interface *** */
4802 std::string CGObjCCommonMac::GetSectionName(StringRef Section,
4803 StringRef MachOAttributes) {
4804 switch (CGM.getTriple().getObjectFormat()) {
4806 llvm_unreachable("unexpected
object file format
");
4807 case llvm::Triple::MachO: {
4808 if (MachOAttributes.empty())
4809 return ("__DATA,
" + Section).str();
4810 return ("__DATA,
" + Section + ",
" + MachOAttributes).str();
4812 case llvm::Triple::ELF:
4813 assert(Section.substr(0, 2) == "__
" &&
4814 "expected the name to begin with __
");
4815 return Section.substr(2).str();
4816 case llvm::Triple::COFF:
4817 assert(Section.substr(0, 2) == "__
" &&
4818 "expected the name to begin with __
");
4819 return (".
" + Section.substr(2) + "$B
").str();
4831 enum ImageInfoFlags {
4832 eImageInfo_FixAndContinue = (1 << 0), // This flag is no longer set by clang.
4833 eImageInfo_GarbageCollected = (1 << 1),
4834 eImageInfo_GCOnly = (1 << 2),
4835 eImageInfo_OptimizedByDyld = (1 << 3), // This flag is set by the dyld shared cache.
4837 // A flag indicating that the module has no instances of a @synthesize of a
4838 // superclass variable. <rdar://problem/6803242>
4839 eImageInfo_CorrectedSynthesize = (1 << 4), // This flag is no longer set by clang.
4840 eImageInfo_ImageIsSimulated = (1 << 5),
4841 eImageInfo_ClassProperties = (1 << 6)
4844 void CGObjCCommonMac::EmitImageInfo() {
4845 unsigned version = 0; // Version is unused?
4846 std::string Section =
4848 ? "__OBJC,__image_info,regular
"
4849 : GetSectionName("__objc_imageinfo
", "regular,no_dead_strip
");
4851 // Generate module-level named metadata to convey this information to the
4852 // linker and code-gen.
4853 llvm::Module &Mod = CGM.getModule();
4855 // Add the ObjC ABI version to the module flags.
4856 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Version
", ObjCABI);
4857 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Version
",
4859 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Section
",
4860 llvm::MDString::get(VMContext, Section));
4862 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
4863 // Non-GC overrides those files which specify GC.
4864 Mod.addModuleFlag(llvm::Module::Override,
4865 "Objective-C Garbage Collection
", (uint32_t)0);
4867 // Add the ObjC garbage collection value.
4868 Mod.addModuleFlag(llvm::Module::Error,
4869 "Objective-C Garbage Collection
",
4870 eImageInfo_GarbageCollected);
4872 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
4873 // Add the ObjC GC Only value.
4874 Mod.addModuleFlag(llvm::Module::Error, "Objective-C GC Only
",
4877 // Require that GC be specified and set to eImageInfo_GarbageCollected.
4878 llvm::Metadata *Ops[2] = {
4879 llvm::MDString::get(VMContext, "Objective-C Garbage Collection
"),
4880 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
4881 llvm::Type::getInt32Ty(VMContext), eImageInfo_GarbageCollected))};
4882 Mod.addModuleFlag(llvm::Module::Require, "Objective-C GC Only
",
4883 llvm::MDNode::get(VMContext, Ops));
4887 // Indicate whether we're compiling this to run on a simulator.
4888 const llvm::Triple &Triple = CGM.getTarget().getTriple();
4889 if ((Triple.isiOS() || Triple.isWatchOS()) &&
4890 (Triple.getArch() == llvm::Triple::x86 ||
4891 Triple.getArch() == llvm::Triple::x86_64))
4892 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Is Simulated
",
4893 eImageInfo_ImageIsSimulated);
4895 // Indicate whether we are generating class properties.
4896 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Class Properties
",
4897 eImageInfo_ClassProperties);
4900 // struct objc_module {
4901 // unsigned long version;
4902 // unsigned long size;
4903 // const char *name;
4907 // FIXME: Get from somewhere
4908 static const int ModuleVersion = 7;
4910 void CGObjCMac::EmitModuleInfo() {
4911 uint64_t Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ModuleTy);
4913 ConstantInitBuilder builder(CGM);
4914 auto values = builder.beginStruct(ObjCTypes.ModuleTy);
4915 values.addInt(ObjCTypes.LongTy, ModuleVersion);
4916 values.addInt(ObjCTypes.LongTy, Size);
4917 // This used to be the filename, now it is unused. <rdr://4327263>
4918 values.add(GetClassName(StringRef("")));
4919 values.add(EmitModuleSymbols());
4920 CreateMetadataVar("OBJC_MODULES
", values,
4921 "__OBJC,__module_info,regular,no_dead_strip
",
4922 CGM.getPointerAlign(), true);
4925 llvm::Constant *CGObjCMac::EmitModuleSymbols() {
4926 unsigned NumClasses = DefinedClasses.size();
4927 unsigned NumCategories = DefinedCategories.size();
4929 // Return null if no symbols were defined.
4930 if (!NumClasses && !NumCategories)
4931 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
4933 ConstantInitBuilder builder(CGM);
4934 auto values = builder.beginStruct();
4935 values.addInt(ObjCTypes.LongTy, 0);
4936 values.addNullPointer(ObjCTypes.SelectorPtrTy);
4937 values.addInt(ObjCTypes.ShortTy, NumClasses);
4938 values.addInt(ObjCTypes.ShortTy, NumCategories);
4940 // The runtime expects exactly the list of defined classes followed
4941 // by the list of defined categories, in a single array.
4942 auto array = values.beginArray(ObjCTypes.Int8PtrTy);
4943 for (unsigned i=0; i<NumClasses; i++) {
4944 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
4946 if (ObjCImplementationDecl *IMP = ID->getImplementation())
4947 // We are implementing a weak imported interface. Give it external linkage
4948 if (ID->isWeakImported() && !IMP->isWeakImported())
4949 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
4951 array.addBitCast(DefinedClasses[i], ObjCTypes.Int8PtrTy);
4953 for (unsigned i=0; i<NumCategories; i++)
4954 array.addBitCast(DefinedCategories[i], ObjCTypes.Int8PtrTy);
4956 array.finishAndAddTo(values);
4958 llvm::GlobalVariable *GV = CreateMetadataVar(
4959 "OBJC_SYMBOLS
", values, "__OBJC,__symbols,regular,no_dead_strip
",
4960 CGM.getPointerAlign(), true);
4961 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
4964 llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF,
4965 IdentifierInfo *II) {
4966 LazySymbols.insert(II);
4968 llvm::GlobalVariable *&Entry = ClassReferences[II];
4971 llvm::Constant *Casted =
4972 llvm::ConstantExpr::getBitCast(GetClassName(II->getName()),
4973 ObjCTypes.ClassPtrTy);
4974 Entry = CreateMetadataVar(
4975 "OBJC_CLASS_REFERENCES_
", Casted,
4976 "__OBJC,__cls_refs,literal_pointers,no_dead_strip
",
4977 CGM.getPointerAlign(), true);
4980 return CGF.Builder.CreateAlignedLoad(Entry, CGF.getPointerAlign());
4983 llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF,
4984 const ObjCInterfaceDecl *ID) {
4985 // If the class has the objc_runtime_visible attribute, we need to
4986 // use the Objective-C runtime to get the class.
4987 if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
4988 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
4990 return EmitClassRefFromId(CGF, ID->getIdentifier());
4993 llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
4994 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool
");
4995 return EmitClassRefFromId(CGF, II);
4998 llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel) {
4999 return CGF.Builder.CreateLoad(EmitSelectorAddr(CGF, Sel));
5002 Address CGObjCMac::EmitSelectorAddr(CodeGenFunction &CGF, Selector Sel) {
5003 CharUnits Align = CGF.getPointerAlign();
5005 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
5007 llvm::Constant *Casted =
5008 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
5009 ObjCTypes.SelectorPtrTy);
5010 Entry = CreateMetadataVar(
5011 "OBJC_SELECTOR_REFERENCES_
", Casted,
5012 "__OBJC,__message_refs,literal_pointers,no_dead_strip
", Align, true);
5013 Entry->setExternallyInitialized(true);
5016 return Address(Entry, Align);
5019 llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) {
5020 llvm::GlobalVariable *&Entry = ClassNames[RuntimeName];
5022 Entry = CreateCStringLiteral(RuntimeName, ObjCLabelType::ClassName);
5023 return getConstantGEP(VMContext, Entry, 0, 0);
5026 llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
5027 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*>::iterator
5028 I = MethodDefinitions.find(MD);
5029 if (I != MethodDefinitions.end())
5037 llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
5038 const ObjCCommonTypesHelper &ObjCTypes) {
5039 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
5042 void IvarLayoutBuilder::visitRecord(const RecordType *RT,
5044 const RecordDecl *RD = RT->getDecl();
5046 // If this is a union, remember that we had one, because it might mess
5047 // up the ordering of layout entries.
5049 IsDisordered = true;
5051 const ASTRecordLayout *recLayout = nullptr;
5052 visitAggregate(RD->field_begin(), RD->field_end(), offset,
5053 [&](const FieldDecl *field) -> CharUnits {
5055 recLayout = &CGM.getContext().getASTRecordLayout(RD);
5056 auto offsetInBits = recLayout->getFieldOffset(field->getFieldIndex());
5057 return CGM.getContext().toCharUnitsFromBits(offsetInBits);
5061 template <class Iterator, class GetOffsetFn>
5062 void IvarLayoutBuilder::visitAggregate(Iterator begin, Iterator end,
5063 CharUnits aggregateOffset,
5064 const GetOffsetFn &getOffset) {
5065 for (; begin != end; ++begin) {
5066 auto field = *begin;
5068 // Skip over bitfields.
5069 if (field->isBitField()) {
5073 // Compute the offset of the field within the aggregate.
5074 CharUnits fieldOffset = aggregateOffset + getOffset(field);
5076 visitField(field, fieldOffset);
5081 void IvarLayoutBuilder::visitField(const FieldDecl *field,
5082 CharUnits fieldOffset) {
5083 QualType fieldType = field->getType();
5085 // Drill down into arrays.
5086 uint64_t numElts = 1;
5087 while (auto arrayType = CGM.getContext().getAsConstantArrayType(fieldType)) {
5088 numElts *= arrayType->getSize().getZExtValue();
5089 fieldType = arrayType->getElementType();
5092 assert(!fieldType->isArrayType() && "ivar of non-constant array type?
");
5094 // If we ended up with a zero-sized array, we've done what we can do within
5095 // the limits of this layout encoding.
5096 if (numElts == 0) return;
5098 // Recurse if the base element type is a record type.
5099 if (auto recType = fieldType->getAs<RecordType>()) {
5100 size_t oldEnd = IvarsInfo.size();
5102 visitRecord(recType, fieldOffset);
5104 // If we have an array, replicate the first entry's layout information.
5105 auto numEltEntries = IvarsInfo.size() - oldEnd;
5106 if (numElts != 1 && numEltEntries != 0) {
5107 CharUnits eltSize = CGM.getContext().getTypeSizeInChars(recType);
5108 for (uint64_t eltIndex = 1; eltIndex != numElts; ++eltIndex) {
5109 // Copy the last numEltEntries onto the end of the array, adjusting
5110 // each for the element size.
5111 for (size_t i = 0; i != numEltEntries; ++i) {
5112 auto firstEntry = IvarsInfo[oldEnd + i];
5113 IvarsInfo.push_back(IvarInfo(firstEntry.Offset + eltIndex * eltSize,
5114 firstEntry.SizeInWords));
5122 // Classify the element type.
5123 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), fieldType);
5125 // If it matches what we're looking for, add an entry.
5126 if ((ForStrongLayout && GCAttr == Qualifiers::Strong)
5127 || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
5128 assert(CGM.getContext().getTypeSizeInChars(fieldType)
5129 == CGM.getPointerSize());
5130 IvarsInfo.push_back(IvarInfo(fieldOffset, numElts));
5137 llvm::Constant *IvarLayoutBuilder::buildBitmap(CGObjCCommonMac &CGObjC,
5138 llvm::SmallVectorImpl<unsigned char> &buffer) {
5139 // The bitmap is a series of skip/scan instructions, aligned to word
5140 // boundaries. The skip is performed first.
5141 const unsigned char MaxNibble = 0xF;
5142 const unsigned char SkipMask = 0xF0, SkipShift = 4;
5143 const unsigned char ScanMask = 0x0F, ScanShift = 0;
5145 assert(!IvarsInfo.empty() && "generating bitmap
for no data
");
5147 // Sort the ivar info on byte position in case we encounterred a
5148 // union nested in the ivar list.
5150 // This isn't a stable sort, but our algorithm should handle it fine.
5151 llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end());
5153 assert(std::is_sorted(IvarsInfo.begin(), IvarsInfo.end()));
5155 assert(IvarsInfo.back().Offset < InstanceEnd);
5157 assert(buffer.empty());
5159 // Skip the next N words.
5160 auto skip = [&](unsigned numWords) {
5161 assert(numWords > 0);
5163 // Try to merge into the previous byte. Since scans happen second, we
5164 // can't do this if it includes a scan.
5165 if (!buffer.empty() && !(buffer.back() & ScanMask)) {
5166 unsigned lastSkip = buffer.back() >> SkipShift;
5167 if (lastSkip < MaxNibble) {
5168 unsigned claimed = std::min(MaxNibble - lastSkip, numWords);
5169 numWords -= claimed;
5170 lastSkip += claimed;
5171 buffer.back() = (lastSkip << SkipShift);
5175 while (numWords >= MaxNibble) {
5176 buffer.push_back(MaxNibble << SkipShift);
5177 numWords -= MaxNibble;
5180 buffer.push_back(numWords << SkipShift);
5184 // Scan the next N words.
5185 auto scan = [&](unsigned numWords) {
5186 assert(numWords > 0);
5188 // Try to merge into the previous byte. Since scans happen second, we can
5189 // do this even if it includes a skip.
5190 if (!buffer.empty()) {
5191 unsigned lastScan = (buffer.back() & ScanMask) >> ScanShift;
5192 if (lastScan < MaxNibble) {
5193 unsigned claimed = std::min(MaxNibble - lastScan, numWords);
5194 numWords -= claimed;
5195 lastScan += claimed;
5196 buffer.back() = (buffer.back() & SkipMask) | (lastScan << ScanShift);
5200 while (numWords >= MaxNibble) {
5201 buffer.push_back(MaxNibble << ScanShift);
5202 numWords -= MaxNibble;
5205 buffer.push_back(numWords << ScanShift);
5209 // One past the end of the last scan.
5210 unsigned endOfLastScanInWords = 0;
5211 const CharUnits WordSize = CGM.getPointerSize();
5213 // Consider all the scan requests.
5214 for (auto &request : IvarsInfo) {
5215 CharUnits beginOfScan = request.Offset - InstanceBegin;
5217 // Ignore scan requests that don't start at an even multiple of the
5218 // word size. We can't encode them.
5219 if ((beginOfScan % WordSize) != 0) continue;
5221 // Ignore scan requests that start before the instance start.
5222 // This assumes that scans never span that boundary. The boundary
5223 // isn't the true start of the ivars, because in the fragile-ARC case
5224 // it's rounded up to word alignment, but the test above should leave
5225 // us ignoring that possibility.
5226 if (beginOfScan.isNegative()) {
5227 assert(request.Offset + request.SizeInWords * WordSize <= InstanceBegin);
5231 unsigned beginOfScanInWords = beginOfScan / WordSize;
5232 unsigned endOfScanInWords = beginOfScanInWords + request.SizeInWords;
5234 // If the scan starts some number of words after the last one ended,
5236 if (beginOfScanInWords > endOfLastScanInWords) {
5237 skip(beginOfScanInWords - endOfLastScanInWords);
5239 // Otherwise, start scanning where the last left off.
5241 beginOfScanInWords = endOfLastScanInWords;
5243 // If that leaves us with nothing to scan, ignore this request.
5244 if (beginOfScanInWords >= endOfScanInWords) continue;
5247 // Scan to the end of the request.
5248 assert(beginOfScanInWords < endOfScanInWords);
5249 scan(endOfScanInWords - beginOfScanInWords);
5250 endOfLastScanInWords = endOfScanInWords;
5254 return llvm::ConstantPointerNull::get(CGM.Int8PtrTy);
5256 // For GC layouts, emit a skip to the end of the allocation so that we
5257 // have precise information about the entire thing. This isn't useful
5258 // or necessary for the ARC-style layout strings.
5259 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
5260 unsigned lastOffsetInWords =
5261 (InstanceEnd - InstanceBegin + WordSize - CharUnits::One()) / WordSize;
5262 if (lastOffsetInWords > endOfLastScanInWords) {
5263 skip(lastOffsetInWords - endOfLastScanInWords);
5267 // Null terminate the string.
5268 buffer.push_back(0);
5270 auto *Entry = CGObjC.CreateCStringLiteral(
5271 reinterpret_cast<char *>(buffer.data()), ObjCLabelType::ClassName);
5272 return getConstantGEP(CGM.getLLVMContext(), Entry, 0, 0);
5292 CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD,
5293 CharUnits beginOffset, CharUnits endOffset,
5294 bool ForStrongLayout, bool HasMRCWeakIvars) {
5295 // If this is MRC, and we're either building a strong layout or there
5296 // are no weak ivars, bail out early.
5297 llvm::Type *PtrTy = CGM.Int8PtrTy;
5298 if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
5299 !CGM.getLangOpts().ObjCAutoRefCount &&
5300 (ForStrongLayout || !HasMRCWeakIvars))
5301 return llvm::Constant::getNullValue(PtrTy);
5303 const ObjCInterfaceDecl *OI = OMD->getClassInterface();
5304 SmallVector<const ObjCIvarDecl*, 32> ivars;
5306 // GC layout strings include the complete object layout, possibly
5307 // inaccurately in the non-fragile ABI; the runtime knows how to fix this
5310 // ARC layout strings only include the class's ivars. In non-fragile
5311 // runtimes, that means starting at InstanceStart, rounded up to word
5312 // alignment. In fragile runtimes, there's no InstanceStart, so it means
5313 // starting at the offset of the first ivar, rounded up to word alignment.
5315 // MRC weak layout strings follow the ARC style.
5316 CharUnits baseOffset;
5317 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
5318 for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();
5319 IVD; IVD = IVD->getNextIvar())
5320 ivars.push_back(IVD);
5322 if (isNonFragileABI()) {
5323 baseOffset = beginOffset; // InstanceStart
5324 } else if (!ivars.empty()) {
5326 CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivars[0]));
5328 baseOffset = CharUnits::Zero();
5331 baseOffset = baseOffset.alignTo(CGM.getPointerAlign());
5334 CGM.getContext().DeepCollectObjCIvars(OI, true, ivars);
5336 baseOffset = CharUnits::Zero();
5340 return llvm::Constant::getNullValue(PtrTy);
5342 IvarLayoutBuilder builder(CGM, baseOffset, endOffset, ForStrongLayout);
5344 builder.visitAggregate(ivars.begin(), ivars.end(), CharUnits::Zero(),
5345 [&](const ObjCIvarDecl *ivar) -> CharUnits {
5346 return CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivar));
5349 if (!builder.hasBitmapData())
5350 return llvm::Constant::getNullValue(PtrTy);
5352 llvm::SmallVector<unsigned char, 4> buffer;
5353 llvm::Constant *C = builder.buildBitmap(*this, buffer);
5355 if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
5356 printf("\n%s ivar layout
for class '%s':
",
5357 ForStrongLayout ? "strong
" : "weak
",
5358 OMD->getClassInterface()->getName().str().c_str());
5359 builder.dump(buffer);
5364 llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
5365 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
5366 // FIXME: Avoid std::string in "Sel.
getAsString()
"
5368 Entry = CreateCStringLiteral(Sel.getAsString(), ObjCLabelType::MethodVarName);
5369 return getConstantGEP(VMContext, Entry, 0, 0);
5372 // FIXME: Merge into a single cstring creation function.
5373 llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
5374 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
5377 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
5378 std::string TypeStr;
5379 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
5381 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
5383 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType);
5384 return getConstantGEP(VMContext, Entry, 0, 0);
5387 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D,
5389 std::string TypeStr =
5390 CGM.getContext().getObjCEncodingForMethodDecl(D, Extended);
5392 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
5394 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType);
5395 return getConstantGEP(VMContext, Entry, 0, 0);
5398 // FIXME: Merge into a single cstring creation function.
5399 llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
5400 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
5402 Entry = CreateCStringLiteral(Ident->getName(), ObjCLabelType::PropertyName);
5403 return getConstantGEP(VMContext, Entry, 0, 0);
5406 // FIXME: Merge into a single cstring creation function.
5407 // FIXME: This Decl should be more precise.
5409 CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
5410 const Decl *Container) {
5411 std::string TypeStr =
5412 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container);
5413 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
5416 void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D,
5417 const ObjCContainerDecl *CD,
5418 SmallVectorImpl<char> &Name) {
5419 llvm::raw_svector_ostream OS(Name);
5420 assert (CD && "Missing container
decl in GetNameForMethod
");
5421 OS << '\01' << (D->isInstanceMethod() ? '-' : '+')
5422 << '[' << CD->getName();
5423 if (const ObjCCategoryImplDecl *CID =
5424 dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
5425 OS << '(' << *CID << ')';
5426 OS << ' ' << D->getSelector().getAsString() << ']';
5429 void CGObjCMac::FinishModule() {
5432 // Emit the dummy bodies for any protocols which were referenced but
5434 for (auto &entry : Protocols) {
5435 llvm::GlobalVariable *global = entry.second;
5436 if (global->hasInitializer())
5439 ConstantInitBuilder builder(CGM);
5440 auto values = builder.beginStruct(ObjCTypes.ProtocolTy);
5441 values.addNullPointer(ObjCTypes.ProtocolExtensionPtrTy);
5442 values.add(GetClassName(entry.first->getName()));
5443 values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
5444 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy);
5445 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy);
5446 values.finishAndSetAsInitializer(global);
5447 CGM.addCompilerUsedGlobal(global);
5450 // Add assembler directives to add lazy undefined symbol references
5451 // for classes which are referenced but not defined. This is
5452 // important for correct linker interaction.
5454 // FIXME: It would be nice if we had an LLVM construct for this.
5455 if ((!LazySymbols.empty() || !DefinedSymbols.empty()) &&
5456 CGM.getTriple().isOSBinFormatMachO()) {
5457 SmallString<256> Asm;
5458 Asm += CGM.getModule().getModuleInlineAsm();
5459 if (!Asm.empty() && Asm.back() != '\n')
5462 llvm::raw_svector_ostream OS(Asm);
5463 for (const auto *Sym : DefinedSymbols)
5464 OS << "\t.objc_class_name_
" << Sym->getName() << "=0\n
"
5465 << "\t.globl .objc_class_name_
" << Sym->getName() << "\n
";
5466 for (const auto *Sym : LazySymbols)
5467 OS << "\t.lazy_reference .objc_class_name_
" << Sym->getName() << "\n
";
5468 for (const auto &Category : DefinedCategoryNames)
5469 OS << "\t.objc_category_name_
" << Category << "=0\n
"
5470 << "\t.globl .objc_category_name_
" << Category << "\n
";
5472 CGM.getModule().setModuleInlineAsm(OS.str());
5476 CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
5477 : CGObjCCommonMac(cgm), ObjCTypes(cgm), ObjCEmptyCacheVar(nullptr),
5478 ObjCEmptyVtableVar(nullptr) {
5484 ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
5485 : VMContext(cgm.getLLVMContext()), CGM(cgm), ExternalProtocolPtrTy(nullptr)
5487 CodeGen::CodeGenTypes &Types = CGM.getTypes();
5488 ASTContext &Ctx = CGM.getContext();
5490 ShortTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.ShortTy));
5492 LongTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.LongTy));
5493 Int8PtrTy = CGM.Int8PtrTy;
5494 Int8PtrPtrTy = CGM.Int8PtrPtrTy;
5496 // arm64 targets use "int" ivar offset variables. All others,
5497 // including OS X x86_64 and Windows x86_64, use "long" ivar offsets.
5498 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::aarch64)
5499 IvarOffsetVarTy = IntTy;
5501 IvarOffsetVarTy = LongTy;
5504 cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCIdType()));
5506 llvm::PointerType::getUnqual(ObjectPtrTy);
5508 cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCSelType()));
5510 // I'm not sure I like this. The implicit coordination is a bit
5511 // gross. We should solve this in a reasonable fashion because this
5512 // is a pretty common task (match some runtime data structure with
5513 // an LLVM data structure).
5515 // FIXME: This is leaked.
5516 // FIXME: Merge with rewriter code?
5518 // struct _objc_super {
5522 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
5523 Ctx.getTranslationUnitDecl(),
5524 SourceLocation(), SourceLocation(),
5525 &Ctx.Idents.get("_objc_super
"));
5526 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5527 nullptr, Ctx.getObjCIdType(), nullptr, nullptr,
5528 false, ICIS_NoInit));
5529 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5530 nullptr, Ctx.getObjCClassType(), nullptr,
5531 nullptr, false, ICIS_NoInit));
5532 RD->completeDefinition();
5534 SuperCTy = Ctx.getTagDeclType(RD);
5535 SuperPtrCTy = Ctx.getPointerType(SuperCTy);
5537 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
5538 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
5542 // char *attributes;
5544 PropertyTy = llvm::StructType::create("struct._prop_t
", Int8PtrTy, Int8PtrTy);
5546 // struct _prop_list_t {
5547 // uint32_t entsize; // sizeof(struct _prop_t)
5548 // uint32_t count_of_properties;
5549 // struct _prop_t prop_list[count_of_properties];
5551 PropertyListTy = llvm::StructType::create(
5552 "struct._prop_list_t
", IntTy, IntTy, llvm::ArrayType::get(PropertyTy, 0));
5553 // struct _prop_list_t *
5554 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
5556 // struct _objc_method {
5558 // char *method_type;
5561 MethodTy = llvm::StructType::create("struct._objc_method
", SelectorPtrTy,
5562 Int8PtrTy, Int8PtrTy);
5564 // struct _objc_cache *
5565 CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache
");
5566 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
5569 ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
5570 : ObjCCommonTypesHelper(cgm) {
5571 // struct _objc_method_description {
5575 MethodDescriptionTy = llvm::StructType::create(
5576 "struct._objc_method_description
", SelectorPtrTy, Int8PtrTy);
5578 // struct _objc_method_description_list {
5580 // struct _objc_method_description[1];
5582 MethodDescriptionListTy =
5583 llvm::StructType::create("struct._objc_method_description_list
", IntTy,
5584 llvm::ArrayType::get(MethodDescriptionTy, 0));
5586 // struct _objc_method_description_list *
5587 MethodDescriptionListPtrTy =
5588 llvm::PointerType::getUnqual(MethodDescriptionListTy);
5590 // Protocol description structures
5592 // struct _objc_protocol_extension {
5593 // uint32_t size; // sizeof(struct _objc_protocol_extension)
5594 // struct _objc_method_description_list *optional_instance_methods;
5595 // struct _objc_method_description_list *optional_class_methods;
5596 // struct _objc_property_list *instance_properties;
5597 // const char ** extendedMethodTypes;
5598 // struct _objc_property_list *class_properties;
5600 ProtocolExtensionTy = llvm::StructType::create(
5601 "struct._objc_protocol_extension
", IntTy, MethodDescriptionListPtrTy,
5602 MethodDescriptionListPtrTy, PropertyListPtrTy, Int8PtrPtrTy,
5605 // struct _objc_protocol_extension *
5606 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
5608 // Handle recursive construction of Protocol and ProtocolList types
5611 llvm::StructType::create(VMContext, "struct._objc_protocol
");
5614 llvm::StructType::create(VMContext, "struct._objc_protocol_list
");
5615 ProtocolListTy->setBody(llvm::PointerType::getUnqual(ProtocolListTy), LongTy,
5616 llvm::ArrayType::get(ProtocolTy, 0));
5618 // struct _objc_protocol {
5619 // struct _objc_protocol_extension *isa;
5620 // char *protocol_name;
5621 // struct _objc_protocol **_objc_protocol_list;
5622 // struct _objc_method_description_list *instance_methods;
5623 // struct _objc_method_description_list *class_methods;
5625 ProtocolTy->setBody(ProtocolExtensionPtrTy, Int8PtrTy,
5626 llvm::PointerType::getUnqual(ProtocolListTy),
5627 MethodDescriptionListPtrTy, MethodDescriptionListPtrTy);
5629 // struct _objc_protocol_list *
5630 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
5632 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
5634 // Class description structures
5636 // struct _objc_ivar {
5641 IvarTy = llvm::StructType::create("struct._objc_ivar
", Int8PtrTy, Int8PtrTy,
5644 // struct _objc_ivar_list *
5646 llvm::StructType::create(VMContext, "struct._objc_ivar_list
");
5647 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
5649 // struct _objc_method_list *
5651 llvm::StructType::create(VMContext, "struct._objc_method_list
");
5652 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
5654 // struct _objc_class_extension *
5655 ClassExtensionTy = llvm::StructType::create(
5656 "struct._objc_class_extension
", IntTy, Int8PtrTy, PropertyListPtrTy);
5657 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
5659 ClassTy = llvm::StructType::create(VMContext, "struct._objc_class
");
5661 // struct _objc_class {
5663 // Class super_class;
5667 // long instance_size;
5668 // struct _objc_ivar_list *ivars;
5669 // struct _objc_method_list *methods;
5670 // struct _objc_cache *cache;
5671 // struct _objc_protocol_list *protocols;
5672 // char *ivar_layout;
5673 // struct _objc_class_ext *ext;
5675 ClassTy->setBody(llvm::PointerType::getUnqual(ClassTy),
5676 llvm::PointerType::getUnqual(ClassTy), Int8PtrTy, LongTy,
5677 LongTy, LongTy, IvarListPtrTy, MethodListPtrTy, CachePtrTy,
5678 ProtocolListPtrTy, Int8PtrTy, ClassExtensionPtrTy);
5680 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
5682 // struct _objc_category {
5683 // char *category_name;
5684 // char *class_name;
5685 // struct _objc_method_list *instance_method;
5686 // struct _objc_method_list *class_method;
5687 // struct _objc_protocol_list *protocols;
5688 // uint32_t size; // sizeof(struct _objc_category)
5689 // struct _objc_property_list *instance_properties;// category's @property
5690 // struct _objc_property_list *class_properties;
5692 CategoryTy = llvm::StructType::create(
5693 "struct._objc_category
", Int8PtrTy, Int8PtrTy, MethodListPtrTy,
5694 MethodListPtrTy, ProtocolListPtrTy, IntTy, PropertyListPtrTy,
5697 // Global metadata structures
5699 // struct _objc_symtab {
5700 // long sel_ref_cnt;
5702 // short cls_def_cnt;
5703 // short cat_def_cnt;
5704 // char *defs[cls_def_cnt + cat_def_cnt];
5706 SymtabTy = llvm::StructType::create("struct._objc_symtab
", LongTy,
5707 SelectorPtrTy, ShortTy, ShortTy,
5708 llvm::ArrayType::get(Int8PtrTy, 0));
5709 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
5711 // struct _objc_module {
5713 // long size; // sizeof(struct _objc_module)
5715 // struct _objc_symtab* symtab;
5717 ModuleTy = llvm::StructType::create("struct._objc_module
", LongTy, LongTy,
5718 Int8PtrTy, SymtabPtrTy);
5720 // FIXME: This is the size of the setjmp buffer and should be target
5721 // specific. 18 is what's used on 32-bit X86.
5722 uint64_t SetJmpBufferSize = 18;
5725 llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4);
5727 ExceptionDataTy = llvm::StructType::create(
5728 "struct._objc_exception_data
",
5729 llvm::ArrayType::get(CGM.Int32Ty, SetJmpBufferSize), StackPtrTy);
5732 ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm)
5733 : ObjCCommonTypesHelper(cgm) {
5734 // struct _method_list_t {
5735 // uint32_t entsize; // sizeof(struct _objc_method)
5736 // uint32_t method_count;
5737 // struct _objc_method method_list[method_count];
5740 llvm::StructType::create("struct.__method_list_t
", IntTy, IntTy,
5741 llvm::ArrayType::get(MethodTy, 0));
5742 // struct method_list_t *
5743 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy);
5745 // struct _protocol_t {
5747 // const char * const protocol_name;
5748 // const struct _protocol_list_t * protocol_list; // super protocols
5749 // const struct method_list_t * const instance_methods;
5750 // const struct method_list_t * const class_methods;
5751 // const struct method_list_t *optionalInstanceMethods;
5752 // const struct method_list_t *optionalClassMethods;
5753 // const struct _prop_list_t * properties;
5754 // const uint32_t size; // sizeof(struct _protocol_t)
5755 // const uint32_t flags; // = 0
5756 // const char ** extendedMethodTypes;
5757 // const char *demangledName;
5758 // const struct _prop_list_t * class_properties;
5761 // Holder for struct _protocol_list_t *
5762 ProtocolListnfABITy =
5763 llvm::StructType::create(VMContext, "struct._objc_protocol_list
");
5765 ProtocolnfABITy = llvm::StructType::create(
5766 "struct._protocol_t
", ObjectPtrTy, Int8PtrTy,
5767 llvm::PointerType::getUnqual(ProtocolListnfABITy), MethodListnfABIPtrTy,
5768 MethodListnfABIPtrTy, MethodListnfABIPtrTy, MethodListnfABIPtrTy,
5769 PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy, Int8PtrTy,
5772 // struct _protocol_t*
5773 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy);
5775 // struct _protocol_list_t {
5776 // long protocol_count; // Note, this is 32/64 bit
5777 // struct _protocol_t *[protocol_count];
5779 ProtocolListnfABITy->setBody(LongTy,
5780 llvm::ArrayType::get(ProtocolnfABIPtrTy, 0));
5782 // struct _objc_protocol_list*
5783 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy);
5786 // unsigned [long] int *offset; // pointer to ivar offset location
5789 // uint32_t alignment;
5792 IvarnfABITy = llvm::StructType::create(
5793 "struct._ivar_t
", llvm::PointerType::getUnqual(IvarOffsetVarTy),
5794 Int8PtrTy, Int8PtrTy, IntTy, IntTy);
5796 // struct _ivar_list_t {
5797 // uint32 entsize; // sizeof(struct _ivar_t)
5799 // struct _iver_t list[count];
5802 llvm::StructType::create("struct._ivar_list_t
", IntTy, IntTy,
5803 llvm::ArrayType::get(IvarnfABITy, 0));
5805 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy);
5807 // struct _class_ro_t {
5808 // uint32_t const flags;
5809 // uint32_t const instanceStart;
5810 // uint32_t const instanceSize;
5811 // uint32_t const reserved; // only when building for 64bit targets
5812 // const uint8_t * const ivarLayout;
5813 // const char *const name;
5814 // const struct _method_list_t * const baseMethods;
5815 // const struct _objc_protocol_list *const baseProtocols;
5816 // const struct _ivar_list_t *const ivars;
5817 // const uint8_t * const weakIvarLayout;
5818 // const struct _prop_list_t * const properties;
5821 // FIXME. Add 'reserved' field in 64bit abi mode!
5822 ClassRonfABITy = llvm::StructType::create(
5823 "struct._class_ro_t
", IntTy, IntTy, IntTy, Int8PtrTy, Int8PtrTy,
5824 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, IvarListnfABIPtrTy,
5825 Int8PtrTy, PropertyListPtrTy);
5827 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
5828 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
5829 ImpnfABITy = llvm::FunctionType::get(ObjectPtrTy, params, false)
5832 // struct _class_t {
5833 // struct _class_t *isa;
5834 // struct _class_t * const superclass;
5837 // struct class_ro_t *ro;
5840 ClassnfABITy = llvm::StructType::create(VMContext, "struct._class_t
");
5841 ClassnfABITy->setBody(llvm::PointerType::getUnqual(ClassnfABITy),
5842 llvm::PointerType::getUnqual(ClassnfABITy), CachePtrTy,
5843 llvm::PointerType::getUnqual(ImpnfABITy),
5844 llvm::PointerType::getUnqual(ClassRonfABITy));
5846 // LLVM for struct _class_t *
5847 ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy);
5849 // struct _category_t {
5850 // const char * const name;
5851 // struct _class_t *const cls;
5852 // const struct _method_list_t * const instance_methods;
5853 // const struct _method_list_t * const class_methods;
5854 // const struct _protocol_list_t * const protocols;
5855 // const struct _prop_list_t * const properties;
5856 // const struct _prop_list_t * const class_properties;
5857 // const uint32_t size;
5859 CategorynfABITy = llvm::StructType::create(
5860 "struct._category_t
", Int8PtrTy, ClassnfABIPtrTy, MethodListnfABIPtrTy,
5861 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, PropertyListPtrTy,
5862 PropertyListPtrTy, IntTy);
5864 // New types for nonfragile abi messaging.
5865 CodeGen::CodeGenTypes &Types = CGM.getTypes();
5866 ASTContext &Ctx = CGM.getContext();
5868 // MessageRefTy - LLVM for:
5869 // struct _message_ref_t {
5874 // First the clang type for struct _message_ref_t
5875 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
5876 Ctx.getTranslationUnitDecl(),
5877 SourceLocation(), SourceLocation(),
5878 &Ctx.Idents.get("_message_ref_t
"));
5879 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5880 nullptr, Ctx.VoidPtrTy, nullptr, nullptr, false,
5882 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5883 nullptr, Ctx.getObjCSelType(), nullptr, nullptr,
5884 false, ICIS_NoInit));
5885 RD->completeDefinition();
5887 MessageRefCTy = Ctx.getTagDeclType(RD);
5888 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy);
5889 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy));
5891 // MessageRefPtrTy - LLVM for struct _message_ref_t*
5892 MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy);
5894 // SuperMessageRefTy - LLVM for:
5895 // struct _super_message_ref_t {
5896 // SUPER_IMP messenger;
5899 SuperMessageRefTy = llvm::StructType::create("struct._super_message_ref_t
",
5900 ImpnfABITy, SelectorPtrTy);
5902 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
5903 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy);
5906 // struct objc_typeinfo {
5907 // const void** vtable; // objc_ehtype_vtable + 2
5908 // const char* name; // c++ typeinfo string
5911 EHTypeTy = llvm::StructType::create("struct._objc_typeinfo
",
5912 llvm::PointerType::getUnqual(Int8PtrTy),
5913 Int8PtrTy, ClassnfABIPtrTy);
5914 EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy);
5917 llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
5918 FinishNonFragileABIModule();
5923 void CGObjCNonFragileABIMac::AddModuleClassList(
5924 ArrayRef<llvm::GlobalValue *> Container, StringRef SymbolName,
5925 StringRef SectionName) {
5926 unsigned NumClasses = Container.size();
5931 SmallVector<llvm::Constant*, 8> Symbols(NumClasses);
5932 for (unsigned i=0; i<NumClasses; i++)
5933 Symbols[i] = llvm::ConstantExpr::getBitCast(Container[i],
5934 ObjCTypes.Int8PtrTy);
5935 llvm::Constant *Init =
5936 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
5940 llvm::GlobalVariable *GV =
5941 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
5942 llvm::GlobalValue::PrivateLinkage,
5945 GV->setAlignment(CGM.getDataLayout().getABITypeAlignment(Init->getType()));
5946 GV->setSection(SectionName);
5947 CGM.addCompilerUsedGlobal(GV);
5950 void CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
5951 // nonfragile abi has no module definition.
5953 // Build list of all implemented class addresses in array
5954 // L_OBJC_LABEL_CLASS_$.
5956 for (unsigned i=0, NumClasses=ImplementedClasses.size(); i<NumClasses; i++) {
5957 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
5959 if (ObjCImplementationDecl *IMP = ID->getImplementation())
5960 // We are implementing a weak imported interface. Give it external linkage
5961 if (ID->isWeakImported() && !IMP->isWeakImported()) {
5962 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
5963 DefinedMetaClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
5967 AddModuleClassList(DefinedClasses, "OBJC_LABEL_CLASS_$
",
5968 GetSectionName("__objc_classlist
",
5969 "regular,no_dead_strip
"));
5971 AddModuleClassList(DefinedNonLazyClasses, "OBJC_LABEL_NONLAZY_CLASS_$
",
5972 GetSectionName("__objc_nlclslist
",
5973 "regular,no_dead_strip
"));
5975 // Build list of all implemented category addresses in array
5976 // L_OBJC_LABEL_CATEGORY_$.
5977 AddModuleClassList(DefinedCategories, "OBJC_LABEL_CATEGORY_$
",
5978 GetSectionName("__objc_catlist
",
5979 "regular,no_dead_strip
"));
5980 AddModuleClassList(DefinedNonLazyCategories, "OBJC_LABEL_NONLAZY_CATEGORY_$
",
5981 GetSectionName("__objc_nlcatlist
",
5982 "regular,no_dead_strip
"));
5991 bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
5992 // At various points we've experimented with using vtable-based
5993 // dispatch for all methods.
5994 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
5995 case CodeGenOptions::Legacy:
5997 case CodeGenOptions::NonLegacy:
5999 case CodeGenOptions::Mixed:
6003 // If so, see whether this selector is in the white-list of things which must
6004 // use the new dispatch convention. We lazily build a dense set for this.
6005 if (VTableDispatchMethods.empty()) {
6006 VTableDispatchMethods.insert(GetNullarySelector("alloc
"));
6007 VTableDispatchMethods.insert(GetNullarySelector("class"));
6008 VTableDispatchMethods.insert(GetNullarySelector("self"));
6009 VTableDispatchMethods.insert(GetNullarySelector("isFlipped
"));
6010 VTableDispatchMethods.insert(GetNullarySelector("length"));
6011 VTableDispatchMethods.insert(GetNullarySelector("count
"));
6013 // These are vtable-based if GC is disabled.
6014 // Optimistically use vtable dispatch for hybrid compiles.
6015 if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) {
6016 VTableDispatchMethods.insert(GetNullarySelector("retain
"));
6017 VTableDispatchMethods.insert(GetNullarySelector("release
"));
6018 VTableDispatchMethods.insert(GetNullarySelector("autorelease
"));
6021 VTableDispatchMethods.insert(GetUnarySelector("allocWithZone
"));
6022 VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass
"));
6023 VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector
"));
6024 VTableDispatchMethods.insert(GetUnarySelector("objectForKey
"));
6025 VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex
"));
6026 VTableDispatchMethods.insert(GetUnarySelector("isEqualToString
"));
6027 VTableDispatchMethods.insert(GetUnarySelector("isEqual
"));
6029 // These are vtable-based if GC is enabled.
6030 // Optimistically use vtable dispatch for hybrid compiles.
6031 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
6032 VTableDispatchMethods.insert(GetNullarySelector("hash
"));
6033 VTableDispatchMethods.insert(GetUnarySelector("addObject
"));
6035 // "countByEnumeratingWithState:objects:count
"
6036 IdentifierInfo *KeyIdents[] = {
6037 &CGM.getContext().Idents.get("countByEnumeratingWithState
"),
6038 &CGM.getContext().Idents.get("objects
"),
6039 &CGM.getContext().Idents.get("count
")
6041 VTableDispatchMethods.insert(
6042 CGM.getContext().Selectors.getSelector(3, KeyIdents));
6046 return VTableDispatchMethods.count(Sel);
6064 llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
6066 unsigned InstanceStart,
6067 unsigned InstanceSize,
6068 const ObjCImplementationDecl *ID) {
6069 std::string ClassName = ID->getObjCRuntimeNameAsString();
6071 CharUnits beginInstance = CharUnits::fromQuantity(InstanceStart);
6072 CharUnits endInstance = CharUnits::fromQuantity(InstanceSize);
6074 bool hasMRCWeak = false;
6075 if (CGM.getLangOpts().ObjCAutoRefCount)
6076 flags |= NonFragileABI_Class_CompiledByARC;
6077 else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))
6078 flags |= NonFragileABI_Class_HasMRCWeakIvars;
6080 ConstantInitBuilder builder(CGM);
6081 auto values = builder.beginStruct(ObjCTypes.ClassRonfABITy);
6083 values.addInt(ObjCTypes.IntTy, flags);
6084 values.addInt(ObjCTypes.IntTy, InstanceStart);
6085 values.addInt(ObjCTypes.IntTy, InstanceSize);
6086 values.add((flags & NonFragileABI_Class_Meta)
6087 ? GetIvarLayoutName(nullptr, ObjCTypes)
6088 : BuildStrongIvarLayout(ID, beginInstance, endInstance));
6089 values.add(GetClassName(ID->getObjCRuntimeNameAsString()));
6091 // const struct _method_list_t * const baseMethods;
6092 SmallVector<const ObjCMethodDecl*, 16> methods;
6093 if (flags & NonFragileABI_Class_Meta) {
6094 for (const auto *MD : ID->class_methods())
6095 methods.push_back(MD);
6097 for (const auto *MD : ID->instance_methods())
6098 methods.push_back(MD);
6100 for (const auto *PID : ID->property_impls()) {
6101 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){
6102 ObjCPropertyDecl *PD = PID->getPropertyDecl();
6104 if (auto MD = PD->getGetterMethodDecl())
6105 if (GetMethodDefinition(MD))
6106 methods.push_back(MD);
6107 if (auto MD = PD->getSetterMethodDecl())
6108 if (GetMethodDefinition(MD))
6109 methods.push_back(MD);
6114 values.add(emitMethodList(ID->getObjCRuntimeNameAsString(),
6115 (flags & NonFragileABI_Class_Meta)
6116 ? MethodListType::ClassMethods
6117 : MethodListType::InstanceMethods,
6120 const ObjCInterfaceDecl *OID = ID->getClassInterface();
6121 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer
");
6122 values.add(EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_
"
6123 + OID->getObjCRuntimeNameAsString(),
6124 OID->all_referenced_protocol_begin(),
6125 OID->all_referenced_protocol_end()));
6127 if (flags & NonFragileABI_Class_Meta) {
6128 values.addNullPointer(ObjCTypes.IvarListnfABIPtrTy);
6129 values.add(GetIvarLayoutName(nullptr, ObjCTypes));
6130 values.add(EmitPropertyList(
6131 "\01l_OBJC_$_CLASS_PROP_LIST_
" + ID->getObjCRuntimeNameAsString(),
6132 ID, ID->getClassInterface(), ObjCTypes, true));
6134 values.add(EmitIvarList(ID));
6135 values.add(BuildWeakIvarLayout(ID, beginInstance, endInstance, hasMRCWeak));
6136 values.add(EmitPropertyList(
6137 "\01l_OBJC_$_PROP_LIST_
" + ID->getObjCRuntimeNameAsString(),
6138 ID, ID->getClassInterface(), ObjCTypes, false));
6141 llvm::SmallString<64> roLabel;
6142 llvm::raw_svector_ostream(roLabel)
6143 << ((flags & NonFragileABI_Class_Meta) ? "\01l_OBJC_METACLASS_RO_$_
"
6144 : "\01l_OBJC_CLASS_RO_$_
")
6147 llvm::GlobalVariable *CLASS_RO_GV =
6148 values.finishAndCreateGlobal(roLabel, CGM.getPointerAlign(),
6150 llvm::GlobalValue::PrivateLinkage);
6151 if (CGM.getTriple().isOSBinFormatMachO())
6152 CLASS_RO_GV->setSection("__DATA, __objc_const
");
6166 llvm::GlobalVariable *
6167 CGObjCNonFragileABIMac::BuildClassObject(const ObjCInterfaceDecl *CI,
6169 llvm::Constant *IsAGV,
6170 llvm::Constant *SuperClassGV,
6171 llvm::Constant *ClassRoGV,
6172 bool HiddenVisibility) {
6173 ConstantInitBuilder builder(CGM);
6174 auto values = builder.beginStruct(ObjCTypes.ClassnfABITy);
6177 values.add(SuperClassGV);
6179 values.addNullPointer(ObjCTypes.ClassnfABIPtrTy);
6181 values.add(ObjCEmptyCacheVar);
6182 values.add(ObjCEmptyVtableVar);
6183 values.add(ClassRoGV);
6185 llvm::GlobalVariable *GV =
6186 cast<llvm::GlobalVariable>(GetClassGlobal(CI, isMetaclass, ForDefinition));
6187 values.finishAndSetAsInitializer(GV);
6189 if (CGM.getTriple().isOSBinFormatMachO())
6190 GV->setSection("__DATA, __objc_data
");
6192 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassnfABITy));
6193 if (!CGM.getTriple().isOSBinFormatCOFF())
6194 if (HiddenVisibility)
6195 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
6200 CGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
6201 return OD->getClassMethod(GetNullarySelector("load
")) != nullptr;
6204 void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
6205 uint32_t &InstanceStart,
6206 uint32_t &InstanceSize) {
6207 const ASTRecordLayout &RL =
6208 CGM.getContext().getASTObjCImplementationLayout(OID);
6210 // InstanceSize is really instance end.
6211 InstanceSize = RL.getDataSize().getQuantity();
6213 // If there are no fields, the start is the same as the end.
6214 if (!RL.getFieldCount())
6215 InstanceStart = InstanceSize;
6217 InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth();
6220 static llvm::GlobalValue::DLLStorageClassTypes getStorage(CodeGenModule &CGM,
6222 IdentifierInfo &II = CGM.getContext().Idents.get(Name);
6223 TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl();
6224 DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl);
6226 const VarDecl *VD = nullptr;
6227 for (const auto &Result : DC->lookup(&II))
6228 if ((VD = dyn_cast<VarDecl>(Result)))
6232 return llvm::GlobalValue::DLLImportStorageClass;
6233 if (VD->hasAttr<DLLExportAttr>())
6234 return llvm::GlobalValue::DLLExportStorageClass;
6235 if (VD->hasAttr<DLLImportAttr>())
6236 return llvm::GlobalValue::DLLImportStorageClass;
6237 return llvm::GlobalValue::DefaultStorageClass;
6240 void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
6241 if (!ObjCEmptyCacheVar) {
6243 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CacheTy, false,
6244 llvm::GlobalValue::ExternalLinkage, nullptr,
6245 "_objc_empty_cache
");
6246 if (CGM.getTriple().isOSBinFormatCOFF())
6247 ObjCEmptyCacheVar->setDLLStorageClass(getStorage(CGM, "_objc_empty_cache
"));
6249 // Only OS X with deployment version <10.9 use the empty vtable symbol
6250 const llvm::Triple &Triple = CGM.getTarget().getTriple();
6251 if (Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 9))
6252 ObjCEmptyVtableVar =
6253 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ImpnfABITy, false,
6254 llvm::GlobalValue::ExternalLinkage, nullptr,
6255 "_objc_empty_vtable
");
6257 ObjCEmptyVtableVar =
6258 llvm::ConstantPointerNull::get(ObjCTypes.ImpnfABITy->getPointerTo());
6261 // FIXME: Is this correct (that meta class size is never computed)?
6262 uint32_t InstanceStart =
6263 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy);
6264 uint32_t InstanceSize = InstanceStart;
6265 uint32_t flags = NonFragileABI_Class_Meta;
6267 llvm::Constant *SuperClassGV, *IsAGV;
6269 const auto *CI = ID->getClassInterface();
6270 assert(CI && "CGObjCNonFragileABIMac::GenerateClass -
class is 0");
6273 bool classIsHidden = (CGM.
getTriple().isOSBinFormatCOFF())
6274 ? !CI->hasAttr<DLLExportAttr>()
6287 if (!CI->getSuperClass()) {
6304 llvm::GlobalVariable *CLASS_RO_GV =
6305 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
6307 llvm::GlobalVariable *MetaTClass =
6308 BuildClassObject(CI,
true,
6309 IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden);
6310 if (CGM.
getTriple().isOSBinFormatCOFF())
6311 if (CI->hasAttr<DLLExportAttr>())
6312 MetaTClass->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
6313 DefinedMetaClasses.push_back(MetaTClass);
6336 if (!CI->getSuperClass()) {
6338 SuperClassGV =
nullptr;
6341 const auto *Super = CI->getSuperClass();
6345 GetClassSizeInfo(ID, InstanceStart, InstanceSize);
6347 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
6349 llvm::GlobalVariable *ClassMD =
6350 BuildClassObject(CI,
false,
6351 MetaTClass, SuperClassGV, CLASS_RO_GV, classIsHidden);
6352 if (CGM.
getTriple().isOSBinFormatCOFF())
6353 if (CI->hasAttr<DLLExportAttr>())
6354 ClassMD->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
6355 DefinedClasses.push_back(ClassMD);
6356 ImplementedClasses.push_back(CI);
6359 if (ImplementationIsNonLazy(ID))
6360 DefinedNonLazyClasses.push_back(ClassMD);
6366 MethodDefinitions.clear();
6383 llvm::Constant *Init =
6384 llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD),
6385 ObjCTypes.getExternalProtocolPtrTy());
6387 std::string ProtocolName(
"\01l_OBJC_PROTOCOL_REFERENCE_$_");
6392 llvm::GlobalVariable *PTGV = CGM.
getModule().getGlobalVariable(ProtocolName);
6395 PTGV =
new llvm::GlobalVariable(CGM.
getModule(), Init->getType(),
false,
6396 llvm::GlobalValue::WeakAnyLinkage, Init,
6398 PTGV->setSection(GetSectionName(
"__objc_protorefs",
6399 "coalesced,no_dead_strip"));
6402 if (!CGM.
getTriple().isOSBinFormatMachO())
6403 PTGV->setComdat(CGM.
getModule().getOrInsertComdat(ProtocolName));
6422 const char *Prefix =
"\01l_OBJC_$_CATEGORY_";
6426 ExtCatName +=
"_$_";
6430 auto values = builder.
beginStruct(ObjCTypes.CategorynfABITy);
6434 std::string listName =
6439 for (
const auto *MD : OCD->
methods()) {
6441 instanceMethods.push_back(MD);
6443 classMethods.push_back(MD);
6447 values.add(emitMethodList(listName, MethodListType::CategoryInstanceMethods,
6449 values.add(emitMethodList(listName, MethodListType::CategoryClassMethods,
6458 values.add(EmitProtocolList(
"\01l_OBJC_CATEGORY_PROTOCOLS_$_"
6463 values.add(EmitPropertyList(
"\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
6465 values.add(EmitPropertyList(
"\01l_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(),
6468 values.addNullPointer(ObjCTypes.ProtocolListnfABIPtrTy);
6469 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
6470 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
6473 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.CategorynfABITy);
6474 values.addInt(ObjCTypes.IntTy, Size);
6476 llvm::GlobalVariable *GCATV =
6479 llvm::GlobalValue::PrivateLinkage);
6480 if (CGM.
getTriple().isOSBinFormatMachO())
6481 GCATV->setSection(
"__DATA, __objc_const");
6483 DefinedCategories.push_back(GCATV);
6486 if (ImplementationIsNonLazy(OCD))
6487 DefinedNonLazyCategories.push_back(GCATV);
6489 MethodDefinitions.clear();
6504 auto method = builder.
beginStruct(ObjCTypes.MethodTy);
6505 method.addBitCast(GetMethodVarName(MD->
getSelector()),
6506 ObjCTypes.SelectorPtrTy);
6507 method.add(GetMethodVarType(MD));
6511 method.addNullPointer(ObjCTypes.Int8PtrTy);
6513 llvm::Function *fn = GetMethodDefinition(MD);
6514 assert(fn &&
"no definition for method?");
6515 method.addBitCast(fn, ObjCTypes.Int8PtrTy);
6518 method.finishAndAddTo(builder);
6530 CGObjCNonFragileABIMac::emitMethodList(Twine name,
MethodListType kind,
6533 if (methods.empty())
6534 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
6539 case MethodListType::CategoryInstanceMethods:
6540 prefix =
"\01l_OBJC_$_CATEGORY_INSTANCE_METHODS_";
6541 forProtocol =
false;
6543 case MethodListType::CategoryClassMethods:
6544 prefix =
"\01l_OBJC_$_CATEGORY_CLASS_METHODS_";
6545 forProtocol =
false;
6547 case MethodListType::InstanceMethods:
6548 prefix =
"\01l_OBJC_$_INSTANCE_METHODS_";
6549 forProtocol =
false;
6551 case MethodListType::ClassMethods:
6552 prefix =
"\01l_OBJC_$_CLASS_METHODS_";
6553 forProtocol =
false;
6556 case MethodListType::ProtocolInstanceMethods:
6557 prefix =
"\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_";
6560 case MethodListType::ProtocolClassMethods:
6561 prefix =
"\01l_OBJC_$_PROTOCOL_CLASS_METHODS_";
6564 case MethodListType::OptionalProtocolInstanceMethods:
6565 prefix =
"\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_";
6568 case MethodListType::OptionalProtocolClassMethods:
6569 prefix =
"\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_";
6578 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.MethodTy);
6579 values.addInt(ObjCTypes.IntTy, Size);
6581 values.addInt(ObjCTypes.IntTy, methods.size());
6582 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
6583 for (
auto MD : methods) {
6584 emitMethodConstant(methodArray, MD, forProtocol);
6586 methodArray.finishAndAddTo(values);
6588 auto *GV = values.finishAndCreateGlobal(prefix + name, CGM.
getPointerAlign(),
6590 llvm::GlobalValue::PrivateLinkage);
6591 if (CGM.
getTriple().isOSBinFormatMachO())
6592 GV->setSection(
"__DATA, __objc_const");
6594 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListnfABIPtrTy);
6599 llvm::GlobalVariable *
6607 llvm::GlobalVariable *IvarOffsetGV = CGM.
getModule().getGlobalVariable(Name);
6608 if (!IvarOffsetGV) {
6610 new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.IvarOffsetVarTy,
6612 nullptr, Name.str());
6613 if (CGM.
getTriple().isOSBinFormatCOFF()) {
6614 bool IsPrivateOrPackage =
6618 if (ID->
hasAttr<DLLExportAttr>() && !IsPrivateOrPackage)
6619 IvarOffsetGV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
6620 else if (ID->
hasAttr<DLLImportAttr>())
6621 IvarOffsetGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
6624 return IvarOffsetGV;
6630 unsigned long int Offset) {
6631 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
6632 IvarOffsetGV->setInitializer(
6633 llvm::ConstantInt::get(ObjCTypes.IvarOffsetVarTy, Offset));
6634 IvarOffsetGV->setAlignment(
6635 CGM.
getDataLayout().getABITypeAlignment(ObjCTypes.IvarOffsetVarTy));
6637 if (!CGM.
getTriple().isOSBinFormatCOFF()) {
6648 if (CGM.
getTriple().isOSBinFormatMachO())
6649 IvarOffsetGV->setSection(
"__DATA, __objc_ivar");
6650 return IvarOffsetGV;
6670 llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
6675 ivarList.addInt(ObjCTypes.IntTy,
6676 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.IvarnfABITy));
6677 auto ivarCountSlot = ivarList.addPlaceholder();
6678 auto ivars = ivarList.beginArray(ObjCTypes.IvarnfABITy);
6681 assert(OID &&
"CGObjCNonFragileABIMac::EmitIvarList - null interface");
6688 if (!IVD->getDeclName())
6691 auto ivar = ivars.beginStruct(ObjCTypes.IvarnfABITy);
6693 ComputeIvarBaseOffset(CGM, ID, IVD)));
6694 ivar.add(GetMethodVarName(IVD->getIdentifier()));
6695 ivar.add(GetMethodVarType(IVD));
6696 llvm::Type *FieldTy =
6698 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(FieldTy);
6700 IVD->getType().getTypePtr()) >> 3;
6701 Align = llvm::Log2_32(Align);
6702 ivar.addInt(ObjCTypes.IntTy, Align);
6708 ivar.addInt(ObjCTypes.IntTy, Size);
6709 ivar.finishAndAddTo(ivars);
6712 if (ivars.empty()) {
6715 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
6718 auto ivarCount = ivars.size();
6719 ivars.finishAndAddTo(ivarList);
6720 ivarList.fillPlaceholderWithInt(ivarCountSlot, ObjCTypes.IntTy, ivarCount);
6722 const char *Prefix =
"\01l_OBJC_$_INSTANCE_VARIABLES_";
6723 llvm::GlobalVariable *GV =
6726 llvm::GlobalValue::PrivateLinkage);
6727 if (CGM.
getTriple().isOSBinFormatMachO())
6728 GV->setSection(
"__DATA, __objc_const");
6730 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy);
6733 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(
6735 llvm::GlobalVariable *&Entry = Protocols[PD->
getIdentifier()];
6742 llvm::raw_svector_ostream(Protocol) <<
"\01l_OBJC_PROTOCOL_$_"
6745 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolnfABITy,
6748 if (!CGM.
getTriple().isOSBinFormatMachO())
6749 Entry->setComdat(CGM.
getModule().getOrInsertComdat(Protocol));
6775 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
6777 llvm::GlobalVariable *Entry = Protocols[PD->
getIdentifier()];
6780 if (Entry && Entry->hasInitializer())
6787 auto methodLists = ProtocolMethodLists::get(PD);
6790 auto values = builder.
beginStruct(ObjCTypes.ProtocolnfABITy);
6793 values.addNullPointer(ObjCTypes.ObjectPtrTy);
6795 values.add(EmitProtocolList(
"\01l_OBJC_$_PROTOCOL_REFS_"
6799 values.add(methodLists.emitMethodList(
this, PD,
6800 ProtocolMethodLists::RequiredInstanceMethods));
6801 values.add(methodLists.emitMethodList(
this, PD,
6802 ProtocolMethodLists::RequiredClassMethods));
6803 values.add(methodLists.emitMethodList(
this, PD,
6804 ProtocolMethodLists::OptionalInstanceMethods));
6805 values.add(methodLists.emitMethodList(
this, PD,
6806 ProtocolMethodLists::OptionalClassMethods));
6807 values.add(EmitPropertyList(
6809 nullptr, PD, ObjCTypes,
false));
6811 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
6812 values.addInt(ObjCTypes.IntTy, Size);
6813 values.addInt(ObjCTypes.IntTy, 0);
6814 values.add(EmitProtocolMethodTypes(
"\01l_OBJC_$_PROTOCOL_METHOD_TYPES_"
6816 methodLists.emitExtendedTypesArray(
this),
6820 values.addNullPointer(ObjCTypes.Int8PtrTy);
6822 values.add(EmitPropertyList(
6824 nullptr, PD, ObjCTypes,
true));
6828 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
6829 values.finishAndSetAsInitializer(Entry);
6832 llvm::raw_svector_ostream(symbolName)
6835 Entry = values.finishAndCreateGlobal(symbolName, CGM.
getPointerAlign(),
6837 llvm::GlobalValue::WeakAnyLinkage);
6838 if (!CGM.
getTriple().isOSBinFormatMachO())
6839 Entry->setComdat(CGM.
getModule().getOrInsertComdat(symbolName));
6849 llvm::raw_svector_ostream(ProtocolRef) <<
"\01l_OBJC_LABEL_PROTOCOL_$_"
6852 llvm::GlobalVariable *PTGV =
6853 new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolnfABIPtrTy,
6854 false, llvm::GlobalValue::WeakAnyLinkage, Entry,
6856 if (!CGM.
getTriple().isOSBinFormatMachO())
6857 PTGV->setComdat(CGM.
getModule().getOrInsertComdat(ProtocolRef));
6859 CGM.
getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy));
6860 PTGV->setSection(GetSectionName(
"__objc_protolist",
6861 "coalesced,no_dead_strip"));
6876 CGObjCNonFragileABIMac::EmitProtocolList(Twine Name,
6883 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
6887 Name.toVector(TmpName);
6888 llvm::GlobalVariable *GV =
6889 CGM.
getModule().getGlobalVariable(TmpName.str(),
true);
6891 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy);
6895 auto countSlot = values.addPlaceholder();
6898 auto array = values.beginArray(ObjCTypes.ProtocolnfABIPtrTy);
6899 for (; begin != end; ++begin)
6900 array.add(GetProtocolRef(*begin));
6901 auto count = array.size();
6902 array.addNullPointer(ObjCTypes.ProtocolnfABIPtrTy);
6904 array.finishAndAddTo(values);
6905 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
6909 llvm::GlobalValue::PrivateLinkage);
6910 if (CGM.
getTriple().isOSBinFormatMachO())
6911 GV->setSection(
"__DATA, __objc_const");
6913 return llvm::ConstantExpr::getBitCast(GV,
6914 ObjCTypes.ProtocolListnfABIPtrTy);
6923 LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
6928 unsigned CVRQualifiers) {
6930 llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
6931 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
6935 llvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset(
6939 llvm::Value *IvarOffsetValue = ObjCIvarOffsetVariable(Interface, Ivar);
6942 if (IsIvarOffsetKnownIdempotent(CGF, Ivar))
6943 cast<llvm::LoadInst>(IvarOffsetValue)
6944 ->setMetadata(CGM.
getModule().getMDKindID(
"invariant.load"),
6945 llvm::MDNode::get(VMContext, None));
6950 if (ObjCTypes.IvarOffsetVarTy == ObjCTypes.IntTy)
6951 IvarOffsetValue = CGF.
Builder.CreateIntCast(
6952 IvarOffsetValue, ObjCTypes.LongTy,
true,
"ivar.conv");
6953 return IvarOffsetValue;
6956 static void appendSelectorForMessageRefTable(std::string &buffer,
6963 for (
unsigned i = 0, e = selector.
getNumArgs(); i != e; ++i) {
6995 args.
add(RValue::get(arg0), arg0Type);
6999 args.
add(RValue::get(
nullptr), ObjCTypes.MessageRefCPtrTy);
7001 args.insert(args.end(), formalArgs.begin(), formalArgs.end());
7003 MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);
7005 NullReturnState nullReturn;
7014 llvm::Constant *fn =
nullptr;
7015 std::string messageRefName(
"\01l_");
7018 fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
7019 messageRefName +=
"objc_msgSendSuper2_stret_fixup";
7021 nullReturn.init(CGF, arg0);
7022 fn = ObjCTypes.getMessageSendStretFixupFn();
7023 messageRefName +=
"objc_msgSend_stret_fixup";
7026 fn = ObjCTypes.getMessageSendFpretFixupFn();
7027 messageRefName +=
"objc_msgSend_fpret_fixup";
7030 fn = ObjCTypes.getMessageSendSuper2FixupFn();
7031 messageRefName +=
"objc_msgSendSuper2_fixup";
7033 fn = ObjCTypes.getMessageSendFixupFn();
7034 messageRefName +=
"objc_msgSend_fixup";
7037 assert(fn &&
"CGObjCNonFragileABIMac::EmitMessageSend");
7038 messageRefName +=
'_';
7042 appendSelectorForMessageRefTable(messageRefName, selector);
7044 llvm::GlobalVariable *messageRef
7045 = CGM.
getModule().getGlobalVariable(messageRefName);
7051 values.add(GetMethodVarName(selector));
7052 messageRef = values.finishAndCreateGlobal(messageRefName,
7053 CharUnits::fromQuantity(16),
7055 llvm::GlobalValue::WeakAnyLinkage);
7057 messageRef->setSection(GetSectionName(
"__objc_msgrefs",
"coalesced"));
7060 bool requiresnullCheck =
false;
7062 for (
const auto *ParamDecl : method->
parameters()) {
7063 if (ParamDecl->
hasAttr<NSConsumedAttr>()) {
7064 if (!nullReturn.NullBB)
7065 nullReturn.init(CGF, arg0);
7066 requiresnullCheck =
true;
7086 RValue result = CGF.
EmitCall(MSI.CallInfo, callee, returnSlot, args);
7087 return nullReturn.complete(CGF, returnSlot, result, resultType, formalArgs,
7088 requiresnullCheck ? method :
nullptr);
7101 return isVTableDispatchedSelector(Sel)
7102 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
7104 false, CallArgs, Method)
7105 : EmitMessageSend(CGF, Return, ResultType,
7106 EmitSelector(CGF, Sel),
7108 false, CallArgs, Method, Class, ObjCTypes);
7116 (metaclass ? getMetaclassSymbolPrefix() : getClassSymbolPrefix());
7122 && ID->
hasAttr<DLLImportAttr>());
7126 CGObjCNonFragileABIMac::GetClassGlobal(StringRef Name,
7128 bool Weak,
bool DLLImport) {
7129 llvm::GlobalValue::LinkageTypes L =
7130 Weak ? llvm::GlobalValue::ExternalWeakLinkage
7135 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name);
7137 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassnfABITy,
7138 false, L,
nullptr,
Name);
7141 GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
7144 assert(GV->getLinkage() == L);
7153 llvm::GlobalVariable *&Entry = ClassReferences[II];
7156 llvm::Constant *ClassGV;
7160 ClassGV = GetClassGlobal((getClassSymbolPrefix() + II->
getName()).str(),
7164 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassnfABIPtrTy,
7165 false, llvm::GlobalValue::PrivateLinkage,
7166 ClassGV,
"OBJC_CLASSLIST_REFERENCES_$_");
7168 Entry->setSection(GetSectionName(
"__objc_classrefs",
7169 "regular,no_dead_strip"));
7179 if (ID->
hasAttr<ObjCRuntimeVisibleAttr>())
7180 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
7185 llvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(
7188 return EmitClassRefFromId(CGF, II,
nullptr);
7195 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->
getIdentifier()];
7199 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassnfABIPtrTy,
7200 false, llvm::GlobalValue::PrivateLinkage,
7201 ClassGV,
"OBJC_CLASSLIST_SUP_REFS_$_");
7203 Entry->setSection(GetSectionName(
"__objc_superrefs",
7204 "regular,no_dead_strip"));
7217 llvm::GlobalVariable * &Entry = MetaClassReferences[ID->
getIdentifier()];
7221 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassnfABIPtrTy,
7222 false, llvm::GlobalValue::PrivateLinkage,
7223 MetaClassGV,
"OBJC_CLASSLIST_SUP_REFS_$_");
7226 Entry->setSection(GetSectionName(
"__objc_superrefs",
7227 "regular,no_dead_strip"));
7241 assert(!isa<llvm::GlobalVariable>(ClassGV) ||
7242 cast<llvm::GlobalVariable>(ClassGV)->hasExternalWeakLinkage());
7245 return EmitClassRef(CGF, ID);
7257 bool isCategoryImpl,
7259 bool IsClassMessage,
7280 Target = EmitSuperClassRef(CGF, Class);
7284 llvm::Type *ClassTy =
7290 return (isVTableDispatchedSelector(Sel))
7291 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
7292 ObjCSuper.
getPointer(), ObjCTypes.SuperPtrCTy,
7293 true, CallArgs, Method)
7294 : EmitMessageSend(CGF, Return, ResultType,
7295 EmitSelector(CGF, Sel),
7296 ObjCSuper.
getPointer(), ObjCTypes.SuperPtrCTy,
7297 true, CallArgs, Method, Class, ObjCTypes);
7302 Address Addr = EmitSelectorAddr(CGF, Sel);
7305 LI->setMetadata(CGM.
getModule().getMDKindID(
"invariant.load"),
7306 llvm::MDNode::get(VMContext, None));
7312 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
7316 llvm::Constant *Casted =
7317 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
7318 ObjCTypes.SelectorPtrTy);
7319 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.SelectorPtrTy,
7320 false, llvm::GlobalValue::PrivateLinkage,
7321 Casted,
"OBJC_SELECTOR_REFERENCES_");
7322 Entry->setExternallyInitialized(
true);
7323 Entry->setSection(GetSectionName(
"__objc_selrefs",
7324 "literal_pointers,no_dead_strip"));
7339 llvm::Type * SrcTy = src->getType();
7340 if (!isa<llvm::PointerType>(SrcTy)) {
7341 unsigned Size = CGM.
getDataLayout().getTypeAllocSize(SrcTy);
7342 assert(Size <= 8 && "does not support size > 8
");
7343 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7344 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7345 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7347 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7348 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
7349 llvm::Value *args[] = { src, dst.getPointer(), ivarOffset };
7350 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
7356 void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
7357 CodeGen::CodeGenFunction &CGF,
7358 llvm::Value *src, Address dst) {
7359 llvm::Type * SrcTy = src->getType();
7360 if (!isa<llvm::PointerType>(SrcTy)) {
7361 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7362 assert(Size <= 8 && "does
not support size > 8
");
7363 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7364 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7365 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7367 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7368 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
7369 llvm::Value *args[] = { src, dst.getPointer() };
7370 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(),
7371 args, "weakassign
");
7374 void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
7375 CodeGen::CodeGenFunction &CGF,
7378 llvm::Value *Size) {
7379 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
7380 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
7381 llvm::Value *args[] = { DestPtr.getPointer(), SrcPtr.getPointer(), Size };
7382 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
7388 llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(
7389 CodeGen::CodeGenFunction &CGF,
7390 Address AddrWeakObj) {
7391 llvm::Type *DestTy = AddrWeakObj.getElementType();
7392 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy);
7393 llvm::Value *read_weak =
7394 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(),
7395 AddrWeakObj.getPointer(), "weakread
");
7396 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
7403 void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
7404 llvm::Value *src, Address dst) {
7405 llvm::Type * SrcTy = src->getType();
7406 if (!isa<llvm::PointerType>(SrcTy)) {
7407 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7408 assert(Size <= 8 && "does
not support size > 8
");
7409 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7410 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7411 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7413 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7414 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
7415 llvm::Value *args[] = { src, dst.getPointer() };
7416 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(),
7417 args, "weakassign
");
7423 void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
7424 llvm::Value *src, Address dst,
7426 llvm::Type * SrcTy = src->getType();
7427 if (!isa<llvm::PointerType>(SrcTy)) {
7428 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7429 assert(Size <= 8 && "does
not support size > 8
");
7430 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7431 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7432 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7434 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7435 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
7436 llvm::Value *args[] = { src, dst.getPointer() };
7438 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(),
7439 args, "globalassign
");
7441 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(),
7442 args, "threadlocalassign
");
7446 CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
7447 const ObjCAtSynchronizedStmt &S) {
7448 EmitAtSynchronizedStmt(CGF, S,
7449 cast<llvm::Function>(ObjCTypes.getSyncEnterFn()),
7450 cast<llvm::Function>(ObjCTypes.getSyncExitFn()));
7454 CGObjCNonFragileABIMac::GetEHType(QualType T) {
7455 // There's a particular fixed type info for 'id'.
7456 if (T->isObjCIdType() || T->isObjCQualifiedIdType()) {
7457 auto *IDEHType = CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id
");
7460 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
7461 llvm::GlobalValue::ExternalLinkage, nullptr,
7463 if (CGM.getTriple().isOSBinFormatCOFF())
7464 IDEHType->setDLLStorageClass(getStorage(CGM, "OBJC_EHTYPE_id
"));
7469 // All other types should be Objective-C interface pointer types.
7470 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
7471 assert(PT && "Invalid
@catch type.
");
7473 const ObjCInterfaceType *IT = PT->getInterfaceType();
7474 assert(IT && "Invalid
@catch type.
");
7476 return GetInterfaceEHType(IT->getDecl(), NotForDefinition);
7479 void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
7480 const ObjCAtTryStmt &S) {
7481 EmitTryCatchStmt(CGF, S,
7482 cast<llvm::Function>(ObjCTypes.getObjCBeginCatchFn()),
7483 cast<llvm::Function>(ObjCTypes.getObjCEndCatchFn()),
7484 cast<llvm::Function>(ObjCTypes.getExceptionRethrowFn()));
7488 void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
7489 const ObjCAtThrowStmt &S,
7490 bool ClearInsertionPoint) {
7491 if (const Expr *ThrowExpr = S.getThrowExpr()) {
7492 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
7493 Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
7494 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception)
7495 .setDoesNotReturn();
7497 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionRethrowFn())
7498 .setDoesNotReturn();
7501 CGF.Builder.CreateUnreachable();
7502 if (ClearInsertionPoint)
7503 CGF.Builder.ClearInsertionPoint();
7507 CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
7508 ForDefinition_t IsForDefinition) {
7509 llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
7510 StringRef ClassName = ID->getObjCRuntimeNameAsString();
7512 // If we don't need a definition, return the entry if found or check
7513 // if we use an external reference.
7514 if (!IsForDefinition) {
7518 // If this type (or a super class) has the __objc_exception__
7519 // attribute, emit an external reference.
7520 if (hasObjCExceptionAttribute(CGM.getContext(), ID)) {
7521 std::string EHTypeName = ("OBJC_EHTYPE_$_
" + ClassName).str();
7522 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy,
7523 false, llvm::GlobalValue::ExternalLinkage,
7524 nullptr, EHTypeName);
7525 if (CGM.getTriple().isOSBinFormatCOFF()) {
7526 if (ID->hasAttr<DLLExportAttr>())
7527 Entry->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
7528 else if (ID->hasAttr<DLLImportAttr>())
7529 Entry->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
7535 // Otherwise we need to either make a new entry or fill in the initializer.
7536 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition
");
7538 std::string VTableName = "objc_ehtype_vtable
";
7539 auto *VTableGV = CGM.getModule().getGlobalVariable(VTableName);
7542 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy, false,
7543 llvm::GlobalValue::ExternalLinkage, nullptr,
7545 if (CGM.getTriple().isOSBinFormatCOFF())
7546 VTableGV->setDLLStorageClass(getStorage(CGM, VTableName));
7549 llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2);
7550 ConstantInitBuilder builder(CGM);
7551 auto values = builder.beginStruct(ObjCTypes.EHTypeTy);
7552 values.add(llvm::ConstantExpr::getGetElementPtr(VTableGV->getValueType(),
7553 VTableGV, VTableIdx));
7554 values.add(GetClassName(ClassName));
7555 values.add(GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition));
7557 llvm::GlobalValue::LinkageTypes L = IsForDefinition
7558 ? llvm::GlobalValue::ExternalLinkage
7559 : llvm::GlobalValue::WeakAnyLinkage;
7561 values.finishAndSetAsInitializer(Entry);
7562 Entry->setAlignment(CGM.getPointerAlign().getQuantity());
7564 Entry = values.finishAndCreateGlobal("OBJC_EHTYPE_$_
" + ClassName,
7565 CGM.getPointerAlign(),
7568 if (CGM.getTriple().isOSBinFormatCOFF())
7569 if (hasObjCExceptionAttribute(CGM.getContext(), ID))
7570 if (ID->hasAttr<DLLExportAttr>())
7571 Entry->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
7573 assert(Entry->getLinkage() == L);
7575 if (!CGM.getTriple().isOSBinFormatCOFF())
7576 if (ID->getVisibility() == HiddenVisibility)
7577 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
7579 if (IsForDefinition)
7580 if (CGM.getTriple().isOSBinFormatMachO())
7581 Entry->setSection("__DATA,__objc_const
");
7588 CodeGen::CGObjCRuntime *
7589 CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
7590 switch (CGM.getLangOpts().ObjCRuntime.getKind()) {
7591 case ObjCRuntime::FragileMacOSX:
7592 return new CGObjCMac(CGM);
7594 case ObjCRuntime::MacOSX:
7595 case ObjCRuntime::iOS:
7596 case ObjCRuntime::WatchOS:
7597 return new CGObjCNonFragileABIMac(CGM);
7599 case ObjCRuntime::GNUstep:
7600 case ObjCRuntime::GCC:
7601 case ObjCRuntime::ObjFW:
7602 llvm_unreachable("these runtimes are
not Mac runtimes
");
7604 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
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.
__SIZE_TYPE__ size_t
The unsigned integer type of the result of the sizeof operator.
llvm::Module & getModule() const
protocol_iterator protocol_end() const
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
The standard implementation of ConstantInitBuilder used in Clang.
Stmt - This represents one statement.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
CharUnits getOffset() const
Implements runtime-specific code generation functions.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
bool isRecordType() const
Decl - This represents one declaration (or definition), e.g.
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.
The base class of the type hierarchy.
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 isWeakImported() const
Determine whether this is a weak-imported symbol.
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.
llvm::GlobalVariable * finishAndCreateGlobal(As &&...args)
Given that this builder was created by beginning an array or struct directly on a ConstantInitBuilder...
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.
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have...
A jump destination is an abstract label, branching to which may require a jump out through normal cle...
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...
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.
method_range methods() const
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
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)
static void PushProtocolProperties(llvm::SmallPtrSet< const IdentifierInfo *, 16 > &PropertySet, SmallVectorImpl< const ObjCPropertyDecl * > &Properties, const ObjCProtocolDecl *Proto, bool IsClassProperty)
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.
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
Represents an ObjC class declaration.
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)
Add all the arguments from another CallArgList to this one.
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 isInstanceMethod() const
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
QualType getObjCIdType() const
Represents the Objective-CC id type.
unsigned Map[FirstTargetAddressSpace]
The type of a lookup table which maps from language-specific address spaces to target-specific ones...
static llvm::Constant * getConstantGEP(llvm::LLVMContext &VMContext, llvm::GlobalVariable *C, unsigned idx0, unsigned idx1)
getConstantGEP() - Help routine to construct simple GEPs.
CharUnits getSizeAlign() const
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.
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
All available information about a concrete callee.
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)
The given basic block lies in the current EH scope, but may be a target of a potentially scope-crossi...
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...
This class organizes the cross-function state that is used while generating LLVM code.
StructBuilder beginStruct(llvm::StructType *ty=nullptr)
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.
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="")
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::IntegerType * IntPtrTy
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.
StringRef getString() const
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.
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
BoundNodesTreeBuilder *const Builder
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.
A helper class of ConstantInitBuilder, used for building constant struct initializers.
const BlockDecl * getBlockDecl() const
unsigned kind
All of the diagnostics that can be emitted by the frontend.
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)
const llvm::Triple & getTriple() const
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...
static llvm::StringMapEntry< llvm::GlobalVariable * > & GetConstantStringEntry(llvm::StringMap< llvm::GlobalVariable * > &Map, const StringLiteral *Literal, unsigned &StringLength)
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.
A helper class of ConstantInitBuilder, used for building constant array initializers.
Abstract information about a function or function prototype.
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, 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.
ObjCCompatibleAliasDecl - Represents alias of a class.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.