29#include "llvm/ADT/CachedHashString.h"
30#include "llvm/ADT/DenseSet.h"
31#include "llvm/ADT/SetVector.h"
32#include "llvm/ADT/SmallPtrSet.h"
33#include "llvm/ADT/SmallString.h"
34#include "llvm/IR/DataLayout.h"
35#include "llvm/IR/InlineAsm.h"
36#include "llvm/IR/IntrinsicInst.h"
37#include "llvm/IR/LLVMContext.h"
38#include "llvm/IR/Module.h"
39#include "llvm/Support/ScopedPrinter.h"
40#include "llvm/Support/raw_ostream.h"
44using namespace CodeGen;
51class ObjCCommonTypesHelper {
53 llvm::LLVMContext &VMContext;
63 llvm::FunctionCallee getMessageSendFn()
const {
66 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
67 return CGM.CreateRuntimeFunction(
68 llvm::FunctionType::get(ObjectPtrTy, params,
true),
"objc_msgSend",
69 llvm::AttributeList::get(CGM.getLLVMContext(),
70 llvm::AttributeList::FunctionIndex,
71 llvm::Attribute::NonLazyBind));
79 llvm::FunctionCallee getMessageSendStretFn()
const {
80 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
81 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy,
83 "objc_msgSend_stret");
91 llvm::FunctionCallee getMessageSendFpretFn()
const {
92 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
93 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.DoubleTy,
95 "objc_msgSend_fpret");
103 llvm::FunctionCallee getMessageSendFp2retFn()
const {
104 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
105 llvm::Type *longDoubleType = llvm::Type::getX86_FP80Ty(VMContext);
106 llvm::Type *resultType =
107 llvm::StructType::get(longDoubleType, longDoubleType);
109 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(resultType,
111 "objc_msgSend_fp2ret");
119 llvm::FunctionCallee getMessageSendSuperFn()
const {
120 llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
121 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
123 "objc_msgSendSuper");
130 llvm::FunctionCallee getMessageSendSuperFn2()
const {
131 llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
132 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
134 "objc_msgSendSuper2");
141 llvm::FunctionCallee getMessageSendSuperStretFn()
const {
142 llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
143 return CGM.CreateRuntimeFunction(
144 llvm::FunctionType::get(CGM.VoidTy, params,
true),
145 "objc_msgSendSuper_stret");
152 llvm::FunctionCallee getMessageSendSuperStretFn2()
const {
153 llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
154 return CGM.CreateRuntimeFunction(
155 llvm::FunctionType::get(CGM.VoidTy, params,
true),
156 "objc_msgSendSuper2_stret");
159 llvm::FunctionCallee getMessageSendSuperFpretFn()
const {
161 return getMessageSendSuperFn();
164 llvm::FunctionCallee getMessageSendSuperFpretFn2()
const {
166 return getMessageSendSuperFn2();
173 llvm::IntegerType *ShortTy, *IntTy, *LongTy;
174 llvm::PointerType *Int8PtrTy, *Int8PtrPtrTy;
175 llvm::PointerType *Int8PtrProgramASTy;
176 llvm::Type *IvarOffsetVarTy;
179 llvm::PointerType *ObjectPtrTy;
182 llvm::PointerType *PtrObjectPtrTy;
185 llvm::PointerType *SelectorPtrTy;
190 llvm::Type *ExternalProtocolPtrTy;
193 llvm::Type *getExternalProtocolPtrTy() {
194 if (!ExternalProtocolPtrTy) {
200 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(
T);
203 return ExternalProtocolPtrTy;
212 llvm::StructType *SuperTy;
214 llvm::PointerType *SuperPtrTy;
218 llvm::StructType *PropertyTy;
222 llvm::StructType *PropertyListTy;
224 llvm::PointerType *PropertyListPtrTy;
227 llvm::StructType *MethodTy;
232 llvm::PointerType *CachePtrTy;
234 llvm::FunctionCallee getGetPropertyFn() {
243 llvm::FunctionType *FTy =
244 Types.GetFunctionType(
245 Types.arrangeBuiltinFunctionDeclaration(IdType, Params));
249 llvm::FunctionCallee getSetPropertyFn() {
262 llvm::FunctionType *FTy =
263 Types.GetFunctionType(
264 Types.arrangeBuiltinFunctionDeclaration(Ctx.
VoidTy, Params));
268 llvm::FunctionCallee getOptimizedSetPropertyFn(
bool atomic,
bool copy) {
283 Params.push_back(IdType);
284 Params.push_back(SelType);
285 Params.push_back(IdType);
287 llvm::FunctionType *FTy =
288 Types.GetFunctionType(
289 Types.arrangeBuiltinFunctionDeclaration(Ctx.
VoidTy, Params));
292 name =
"objc_setProperty_atomic_copy";
293 else if (atomic && !copy)
294 name =
"objc_setProperty_atomic";
295 else if (!atomic && copy)
296 name =
"objc_setProperty_nonatomic_copy";
298 name =
"objc_setProperty_nonatomic";
303 llvm::FunctionCallee getCopyStructFn() {
311 Params.push_back(Ctx.
BoolTy);
312 Params.push_back(Ctx.
BoolTy);
313 llvm::FunctionType *FTy =
314 Types.GetFunctionType(
315 Types.arrangeBuiltinFunctionDeclaration(Ctx.
VoidTy, Params));
323 llvm::FunctionCallee getCppAtomicObjectFunction() {
331 llvm::FunctionType *FTy =
332 Types.GetFunctionType(
333 Types.arrangeBuiltinFunctionDeclaration(Ctx.
VoidTy, Params));
337 llvm::FunctionCallee getEnumerationMutationFn() {
343 llvm::FunctionType *FTy =
344 Types.GetFunctionType(
345 Types.arrangeBuiltinFunctionDeclaration(Ctx.
VoidTy, Params));
349 llvm::FunctionCallee getLookUpClassFn() {
356 llvm::FunctionType *FTy =
357 Types.GetFunctionType(Types.arrangeBuiltinFunctionDeclaration(
364 llvm::FunctionCallee getGcReadWeakFn() {
367 llvm::FunctionType *FTy =
368 llvm::FunctionType::get(ObjectPtrTy, args,
false);
373 llvm::FunctionCallee getGcAssignWeakFn() {
375 llvm::Type *args[] = {ObjectPtrTy, CGM.
UnqualPtrTy};
376 llvm::FunctionType *FTy =
377 llvm::FunctionType::get(ObjectPtrTy, args,
false);
382 llvm::FunctionCallee getGcAssignGlobalFn() {
384 llvm::Type *args[] = {ObjectPtrTy, CGM.
UnqualPtrTy};
385 llvm::FunctionType *FTy =
386 llvm::FunctionType::get(ObjectPtrTy, args,
false);
391 llvm::FunctionCallee getGcAssignThreadLocalFn() {
393 llvm::Type *args[] = {ObjectPtrTy, CGM.
UnqualPtrTy};
394 llvm::FunctionType *FTy =
395 llvm::FunctionType::get(ObjectPtrTy, args,
false);
400 llvm::FunctionCallee getGcAssignIvarFn() {
403 llvm::FunctionType *FTy =
404 llvm::FunctionType::get(ObjectPtrTy, args,
false);
409 llvm::FunctionCallee GcMemmoveCollectableFn() {
411 llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, LongTy };
412 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, args,
false);
417 llvm::FunctionCallee getGcAssignStrongCastFn() {
419 llvm::Type *args[] = {ObjectPtrTy, CGM.
UnqualPtrTy};
420 llvm::FunctionType *FTy =
421 llvm::FunctionType::get(ObjectPtrTy, args,
false);
426 llvm::FunctionCallee getExceptionThrowFn() {
428 llvm::Type *args[] = { ObjectPtrTy };
429 llvm::FunctionType *FTy =
430 llvm::FunctionType::get(CGM.
VoidTy, args,
false);
435 llvm::FunctionCallee getExceptionRethrowFn() {
437 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
442 llvm::FunctionCallee getSyncEnterFn() {
444 llvm::Type *args[] = { ObjectPtrTy };
445 llvm::FunctionType *FTy =
446 llvm::FunctionType::get(CGM.
IntTy, args,
false);
451 llvm::FunctionCallee getSyncExitFn() {
453 llvm::Type *args[] = { ObjectPtrTy };
454 llvm::FunctionType *FTy =
455 llvm::FunctionType::get(CGM.
IntTy, args,
false);
459 llvm::FunctionCallee getSendFn(
bool IsSuper)
const {
460 return IsSuper ? getMessageSendSuperFn() : getMessageSendFn();
463 llvm::FunctionCallee getSendFn2(
bool IsSuper)
const {
464 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();
467 llvm::FunctionCallee getSendStretFn(
bool IsSuper)
const {
468 return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();
471 llvm::FunctionCallee getSendStretFn2(
bool IsSuper)
const {
472 return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();
475 llvm::FunctionCallee getSendFpretFn(
bool IsSuper)
const {
476 return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();
479 llvm::FunctionCallee getSendFpretFn2(
bool IsSuper)
const {
480 return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();
483 llvm::FunctionCallee getSendFp2retFn(
bool IsSuper)
const {
484 return IsSuper ? getMessageSendSuperFn() : getMessageSendFp2retFn();
487 llvm::FunctionCallee getSendFp2RetFn2(
bool IsSuper)
const {
488 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFp2retFn();
496class ObjCTypesHelper :
public ObjCCommonTypesHelper {
499 llvm::StructType *SymtabTy;
501 llvm::PointerType *SymtabPtrTy;
503 llvm::StructType *ModuleTy;
506 llvm::StructType *ProtocolTy;
508 llvm::PointerType *ProtocolPtrTy;
511 llvm::StructType *ProtocolExtensionTy;
514 llvm::PointerType *ProtocolExtensionPtrTy;
517 llvm::StructType *MethodDescriptionTy;
520 llvm::StructType *MethodDescriptionListTy;
523 llvm::PointerType *MethodDescriptionListPtrTy;
525 llvm::StructType *ProtocolListTy;
527 llvm::PointerType *ProtocolListPtrTy;
529 llvm::StructType *CategoryTy;
531 llvm::StructType *ClassTy;
533 llvm::PointerType *ClassPtrTy;
535 llvm::StructType *ClassExtensionTy;
537 llvm::PointerType *ClassExtensionPtrTy;
539 llvm::StructType *IvarTy;
541 llvm::StructType *IvarListTy;
543 llvm::PointerType *IvarListPtrTy;
545 llvm::StructType *MethodListTy;
547 llvm::PointerType *MethodListPtrTy;
550 llvm::StructType *ExceptionDataTy;
553 llvm::FunctionCallee getExceptionTryEnterFn() {
556 llvm::FunctionType::get(CGM.
VoidTy, params,
false),
557 "objc_exception_try_enter");
561 llvm::FunctionCallee getExceptionTryExitFn() {
564 llvm::FunctionType::get(CGM.
VoidTy, params,
false),
565 "objc_exception_try_exit");
569 llvm::FunctionCallee getExceptionExtractFn() {
573 "objc_exception_extract");
577 llvm::FunctionCallee getExceptionMatchFn() {
578 llvm::Type *params[] = { ClassPtrTy, ObjectPtrTy };
580 llvm::FunctionType::get(CGM.
Int32Ty, params,
false),
581 "objc_exception_match");
585 llvm::FunctionCallee getSetJmpFn() {
589 llvm::FunctionType::get(CGM.
Int32Ty, params,
false),
"_setjmp",
591 llvm::AttributeList::FunctionIndex,
592 llvm::Attribute::NonLazyBind));
601class ObjCNonFragileABITypesHelper :
public ObjCCommonTypesHelper {
604 llvm::StructType *MethodListnfABITy;
607 llvm::PointerType *MethodListnfABIPtrTy;
610 llvm::StructType *ProtocolnfABITy;
613 llvm::PointerType *ProtocolnfABIPtrTy;
616 llvm::StructType *ProtocolListnfABITy;
619 llvm::PointerType *ProtocolListnfABIPtrTy;
622 llvm::StructType *ClassnfABITy;
625 llvm::PointerType *ClassnfABIPtrTy;
628 llvm::StructType *IvarnfABITy;
631 llvm::StructType *IvarListnfABITy;
634 llvm::PointerType *IvarListnfABIPtrTy;
637 llvm::StructType *ClassRonfABITy;
640 llvm::PointerType *ImpnfABITy;
643 llvm::StructType *CategorynfABITy;
652 llvm::StructType *MessageRefTy;
657 llvm::Type *MessageRefPtrTy;
666 llvm::StructType *SuperMessageRefTy;
669 llvm::PointerType *SuperMessageRefPtrTy;
671 llvm::FunctionCallee getMessageSendFixupFn() {
673 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
676 "objc_msgSend_fixup");
679 llvm::FunctionCallee getMessageSendFpretFixupFn() {
681 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
684 "objc_msgSend_fpret_fixup");
687 llvm::FunctionCallee getMessageSendStretFixupFn() {
689 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
692 "objc_msgSend_stret_fixup");
695 llvm::FunctionCallee getMessageSendSuper2FixupFn() {
698 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
701 "objc_msgSendSuper2_fixup");
704 llvm::FunctionCallee getMessageSendSuper2StretFixupFn() {
707 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
710 "objc_msgSendSuper2_stret_fixup");
713 llvm::FunctionCallee getObjCEndCatchFn() {
718 llvm::FunctionCallee getObjCBeginCatchFn() {
719 llvm::Type *params[] = { Int8PtrTy };
730 llvm::FunctionCallee getLoadClassrefFn()
const {
736 llvm::Type *params[] = { Int8PtrPtrTy };
738 llvm::AttributeSet AS = llvm::AttributeSet::get(
C, {
739 llvm::Attribute::get(
C, llvm::Attribute::NonLazyBind),
740 llvm::Attribute::getWithMemoryEffects(
C, llvm::MemoryEffects::none()),
741 llvm::Attribute::get(
C, llvm::Attribute::NoUnwind),
744 llvm::FunctionType::get(ClassnfABIPtrTy, params,
false),
747 llvm::AttributeList::FunctionIndex, AS));
748 if (!CGM.
getTriple().isOSBinFormatCOFF())
749 cast<llvm::Function>(F.getCallee())->setLinkage(
750 llvm::Function::ExternalWeakLinkage);
755 llvm::StructType *EHTypeTy;
756 llvm::Type *EHTypePtrTy;
761enum class ObjCLabelType {
774 SKIP_SCAN(
unsigned _skip = 0,
unsigned _scan = 0)
775 : skip(_skip), scan(_scan) {}
782 enum BLOCK_LAYOUT_OPCODE {
789 BLOCK_LAYOUT_OPERATOR = 0,
795 BLOCK_LAYOUT_NON_OBJECT_BYTES = 1,
800 BLOCK_LAYOUT_NON_OBJECT_WORDS = 2,
804 BLOCK_LAYOUT_STRONG = 3,
807 BLOCK_LAYOUT_BYREF = 4,
811 BLOCK_LAYOUT_WEAK = 5,
815 BLOCK_LAYOUT_UNRETAINED = 6
832 enum BLOCK_LAYOUT_OPCODE opcode;
835 RUN_SKIP(
enum BLOCK_LAYOUT_OPCODE Opcode = BLOCK_LAYOUT_OPERATOR,
838 : opcode(
Opcode), block_var_bytepos(BytePos), block_var_size(
Size) {}
842 return block_var_bytepos <
b.block_var_bytepos;
847 llvm::LLVMContext &VMContext;
856 llvm::SetVector<IdentifierInfo*> LazySymbols;
862 llvm::SetVector<IdentifierInfo*> DefinedSymbols;
865 llvm::StringMap<llvm::GlobalVariable*> ClassNames;
868 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
875 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
879 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
883 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> DirectMethodDefinitions;
886 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
889 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
892 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
897 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
901 llvm::DenseSet<IdentifierInfo*> DefinedProtocols;
923 llvm::WeakTrackingVH ConstantStringClassRef;
926 llvm::StructType *NSConstantStringType =
nullptr;
928 llvm::StringMap<llvm::GlobalVariable *> NSConstantStringMap;
932 llvm::Constant *GetMethodVarName(
Selector Sel);
940 bool Extended =
false);
941 llvm::Constant *GetMethodVarType(
const FieldDecl *
D);
949 const Decl *Container);
954 llvm::Constant *GetClassName(StringRef RuntimeName);
968 bool forStrongLayout,
974 return BuildIvarLayout(OI, beginOffset, endOffset,
true,
false);
981 return BuildIvarLayout(OI, beginOffset, endOffset,
false,
hasMRCWeakIvars);
986 void UpdateRunSkipBlockVars(
bool IsByref,
991 void BuildRCBlockVarRecordLayout(
const RecordType *RT,
993 bool ByrefLayout=
false);
995 void BuildRCRecordLayout(
const llvm::StructLayout *RecLayout,
1003 llvm::Constant *getBitmapBlockLayout(
bool ComputeByrefLayout);
1008 const ObjCCommonTypesHelper &ObjCTypes);
1012 llvm::Constant *EmitPropertyList(Twine Name,
1013 const Decl *Container,
1015 const ObjCCommonTypesHelper &ObjCTypes,
1016 bool IsClassProperty);
1020 llvm::Constant *EmitProtocolMethodTypes(Twine Name,
1022 const ObjCCommonTypesHelper &ObjCTypes);
1033 ObjCCommonTypesHelper &ObjCTypes);
1035 std::string GetSectionName(StringRef Section, StringRef MachOAttributes);
1052 llvm::GlobalVariable *CreateMetadataVar(Twine Name,
1056 llvm::GlobalVariable *CreateMetadataVar(Twine Name,
1057 llvm::Constant *
Init,
1061 llvm::GlobalVariable *CreateCStringLiteral(StringRef Name,
1062 ObjCLabelType LabelType,
1063 bool ForceNonFragileABI =
false,
1064 bool NullTerminate =
true);
1077 const ObjCCommonTypesHelper &ObjCTypes);
1081 void EmitImageInfo();
1087 bool isNonFragileABI()
const {
1088 return ObjCABI == 2;
1110 virtual llvm::Constant *GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD)=0;
1112 virtual llvm::Constant *getNSConstantStringClassRef() = 0;
1130enum class MethodListType {
1131 CategoryInstanceMethods,
1132 CategoryClassMethods,
1135 ProtocolInstanceMethods,
1136 ProtocolClassMethods,
1137 OptionalProtocolInstanceMethods,
1138 OptionalProtocolClassMethods,
1143class ProtocolMethodLists {
1146 RequiredInstanceMethods,
1147 RequiredClassMethods,
1148 OptionalInstanceMethods,
1149 OptionalClassMethods
1152 NumProtocolMethodLists = 4
1155 static MethodListType getMethodListKind(Kind kind) {
1157 case RequiredInstanceMethods:
1158 return MethodListType::ProtocolInstanceMethods;
1159 case RequiredClassMethods:
1160 return MethodListType::ProtocolClassMethods;
1161 case OptionalInstanceMethods:
1162 return MethodListType::OptionalProtocolInstanceMethods;
1163 case OptionalClassMethods:
1164 return MethodListType::OptionalProtocolClassMethods;
1166 llvm_unreachable(
"bad kind");
1172 ProtocolMethodLists result;
1174 for (
auto *MD : PD->
methods()) {
1175 size_t index = (2 *
size_t(MD->isOptional()))
1176 + (
size_t(MD->isClassMethod()));
1177 result.Methods[index].push_back(MD);
1183 template <
class Self>
1194 for (
auto &list : Methods) {
1195 for (
auto MD : list) {
1196 result.push_back(self->GetMethodVarType(MD,
true));
1203 template <
class Self>
1207 getMethodListKind(kind), Methods[kind]);
1213class CGObjCMac :
public CGObjCCommonMac {
1215 friend ProtocolMethodLists;
1217 ObjCTypesHelper ObjCTypes;
1221 void EmitModuleInfo();
1225 llvm::Constant *EmitModuleSymbols();
1229 void FinishModule();
1247 llvm::Value *EmitNSAutoreleasePoolClassRef(
CodeGenFunction &CGF)
override;
1268 llvm::Constant *Protocols,
1279 llvm::Constant *emitMethodList(Twine Name, MethodListType MLT,
1299 const ProtocolMethodLists &methodLists);
1303 llvm::Constant *EmitProtocolList(Twine Name,
1315 llvm::Constant *getNSConstantStringClassRef()
override;
1317 llvm::Function *ModuleInitFunction()
override;
1322 Selector Sel, llvm::Value *Receiver,
1331 bool isCategoryImpl, llvm::Value *Receiver,
1346 llvm::Constant *GetEHType(
QualType T)
override;
1357 llvm::FunctionCallee GetPropertyGetFunction()
override;
1358 llvm::FunctionCallee GetPropertySetFunction()
override;
1359 llvm::FunctionCallee GetOptimizedPropertySetFunction(
bool atomic,
1360 bool copy)
override;
1361 llvm::FunctionCallee GetGetStructFunction()
override;
1362 llvm::FunctionCallee GetSetStructFunction()
override;
1363 llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override;
1364 llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override;
1365 llvm::FunctionCallee EnumerationMutationFunction()
override;
1373 bool ClearInsertionPoint=
true)
override;
1375 Address AddrWeakObj)
override;
1377 llvm::Value *src,
Address dst)
override;
1379 llvm::Value *src,
Address dest,
1380 bool threadlocal =
false)
override;
1382 llvm::Value *src,
Address dest,
1383 llvm::Value *ivarOffset)
override;
1385 llvm::Value *src,
Address dest)
override;
1388 llvm::Value *size)
override;
1392 unsigned CVRQualifiers)
override;
1398class CGObjCNonFragileABIMac :
public CGObjCCommonMac {
1400 friend ProtocolMethodLists;
1401 ObjCNonFragileABITypesHelper ObjCTypes;
1402 llvm::GlobalVariable* ObjCEmptyCacheVar;
1403 llvm::Constant* ObjCEmptyVtableVar;
1406 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences;
1409 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences;
1412 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences;
1416 llvm::DenseSet<Selector> VTableDispatchMethods;
1419 std::vector<llvm::GlobalValue*> DefinedMetaClasses;
1423 bool isVTableDispatchedSelector(
Selector Sel);
1427 void FinishNonFragileABIModule();
1432 StringRef SymbolName, StringRef SectionName);
1434 llvm::GlobalVariable * BuildClassRoTInitializer(
unsigned flags,
1435 unsigned InstanceStart,
1436 unsigned InstanceSize,
1440 llvm::Constant *IsAGV,
1441 llvm::Constant *SuperClassGV,
1442 llvm::Constant *ClassRoGV,
1451 llvm::Constant *emitMethodList(Twine Name, MethodListType MLT,
1463 unsigned long int offset);
1478 llvm::Constant *EmitProtocolList(Twine Name,
1486 llvm::Value *Receiver,
1494 llvm::Constant *GetClassGlobal(StringRef Name,
1496 bool Weak =
false,
bool DLLImport =
false);
1505 llvm::GlobalVariable *Entry);
1516 llvm::Value *EmitNSAutoreleasePoolClassRef(
CodeGenFunction &CGF)
override;
1531 llvm::GlobalVariable * ObjCIvarOffsetVariable(
1545 StringRef getMetaclassSymbolPrefix()
const {
return "OBJC_METACLASS_$_"; }
1547 StringRef getClassSymbolPrefix()
const {
return "OBJC_CLASS_$_"; }
1550 uint32_t &InstanceStart,
1551 uint32_t &InstanceSize);
1566 bool ImplementationIsNonLazy(
const ObjCImplDecl *OD)
const;
1585 dyn_cast_or_null<ObjCMethodDecl>(CGF.
CurFuncDecl))
1586 if (MD->isInstanceMethod() && !MD->isDirectMethod())
1595 for (;
ID;
ID =
ID->getSuperClass()) {
1598 if (
ID->getIdentifier()->getName() ==
"NSObject")
1603 if (!
ID->getImplementation())
1612 llvm::Constant *getNSConstantStringClassRef()
override;
1614 llvm::Function *ModuleInitFunction()
override;
1619 llvm::Value *Receiver,
1628 bool isCategoryImpl, llvm::Value *Receiver,
1636 {
return EmitSelector(CGF, Sel); }
1638 {
return EmitSelectorAddr(Sel); }
1644 {
return EmitSelector(CGF, Method->
getSelector()); }
1655 llvm::Constant *GetEHType(
QualType T)
override;
1657 llvm::FunctionCallee GetPropertyGetFunction()
override {
1658 return ObjCTypes.getGetPropertyFn();
1660 llvm::FunctionCallee GetPropertySetFunction()
override {
1661 return ObjCTypes.getSetPropertyFn();
1664 llvm::FunctionCallee GetOptimizedPropertySetFunction(
bool atomic,
1665 bool copy)
override {
1666 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
1669 llvm::FunctionCallee GetSetStructFunction()
override {
1670 return ObjCTypes.getCopyStructFn();
1673 llvm::FunctionCallee GetGetStructFunction()
override {
1674 return ObjCTypes.getCopyStructFn();
1677 llvm::FunctionCallee GetCppAtomicObjectSetFunction()
override {
1678 return ObjCTypes.getCppAtomicObjectFunction();
1681 llvm::FunctionCallee GetCppAtomicObjectGetFunction()
override {
1682 return ObjCTypes.getCppAtomicObjectFunction();
1685 llvm::FunctionCallee EnumerationMutationFunction()
override {
1686 return ObjCTypes.getEnumerationMutationFn();
1694 bool ClearInsertionPoint=
true)
override;
1696 Address AddrWeakObj)
override;
1698 llvm::Value *src,
Address edst)
override;
1700 llvm::Value *src,
Address dest,
1701 bool threadlocal =
false)
override;
1703 llvm::Value *src,
Address dest,
1704 llvm::Value *ivarOffset)
override;
1706 llvm::Value *src,
Address dest)
override;
1709 llvm::Value *size)
override;
1712 unsigned CVRQualifiers)
override;
1720struct NullReturnState {
1721 llvm::BasicBlock *NullBB =
nullptr;
1722 NullReturnState() =
default;
1735 CGF.
Builder.CreateCondBr(isNull, NullBB, callBB);
1750 if (!NullBB)
return result;
1754 llvm::BasicBlock *contBB =
nullptr;
1757 llvm::BasicBlock *callBB = CGF.
Builder.GetInsertBlock();
1772 assert(CGF.
Builder.GetInsertBlock() == NullBB);
1792 llvm::PHINode *phi = CGF.
Builder.CreatePHI(null->getType(), 2);
1794 phi->addIncoming(null, NullBB);
1803 assert(result.
isAggregate() &&
"null init of non-aggregate result?");
1812 CodeGenFunction::ComplexPairTy callResult = result.
getComplexVal();
1815 llvm::Type *scalarTy = callResult.first->getType();
1816 llvm::Constant *scalarZero = llvm::Constant::getNullValue(scalarTy);
1819 llvm::PHINode *real = CGF.
Builder.CreatePHI(scalarTy, 2);
1820 real->addIncoming(callResult.first, callBB);
1821 real->addIncoming(scalarZero, NullBB);
1822 llvm::PHINode *imag = CGF.
Builder.CreatePHI(scalarTy, 2);
1823 imag->addIncoming(callResult.second, callBB);
1824 imag->addIncoming(scalarZero, NullBB);
1835 llvm::GlobalVariable *
C,
unsigned idx0,
1837 llvm::Value *Idxs[] = {
1838 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),
1839 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)
1841 return llvm::ConstantExpr::getGetElementPtr(
C->getValueType(),
C, Idxs);
1848 if (OID->
hasAttr<ObjCExceptionAttr>())
1855static llvm::GlobalValue::LinkageTypes
1857 if (CGM.
getTriple().isOSBinFormatMachO() &&
1858 (Section.empty() || Section.starts_with(
"__DATA")))
1859 return llvm::GlobalValue::InternalLinkage;
1860 return llvm::GlobalValue::PrivateLinkage;
1864static llvm::GlobalVariable *
1867 std::string SectionName;
1868 if (CGM.
getTriple().isOSBinFormatMachO())
1869 SectionName =
"__DATA, __objc_const";
1870 auto *GV = Builder.finishAndCreateGlobal(
1873 GV->setSection(SectionName);
1889 return EmitClassRef(CGF, ID);
1894 return EmitSelector(CGF, Sel);
1897 return EmitSelectorAddr(Sel);
1904llvm::Constant *CGObjCMac::GetEHType(
QualType T) {
1918 llvm_unreachable(
"asking for catch type for ObjC type in fragile runtime");
1941CGObjCCommonMac::GenerateConstantString(
const StringLiteral *SL) {
1944 : GenerateConstantNSString(SL));
1947static llvm::StringMapEntry<llvm::GlobalVariable *> &
1950 StringRef String = Literal->getString();
1951 StringLength = String.size();
1952 return *Map.insert(std::make_pair(String,
nullptr)).first;
1955llvm::Constant *CGObjCMac::getNSConstantStringClassRef() {
1956 if (llvm::Value *
V = ConstantStringClassRef)
1957 return cast<llvm::Constant>(
V);
1961 StringClass.empty() ?
"_NSConstantStringClassReference"
1962 :
"_" + StringClass +
"ClassReference";
1964 llvm::Type *PTy = llvm::ArrayType::get(CGM.
IntTy, 0);
1966 ConstantStringClassRef = GV;
1970llvm::Constant *CGObjCNonFragileABIMac::getNSConstantStringClassRef() {
1971 if (llvm::Value *
V = ConstantStringClassRef)
1972 return cast<llvm::Constant>(
V);
1976 StringClass.empty() ?
"OBJC_CLASS_$_NSConstantString"
1977 :
"OBJC_CLASS_$_" + StringClass;
1979 ConstantStringClassRef = GV;
1984CGObjCCommonMac::GenerateConstantNSString(
const StringLiteral *Literal) {
1985 unsigned StringLength = 0;
1986 llvm::StringMapEntry<llvm::GlobalVariable *> &Entry =
1989 if (
auto *
C = Entry.second)
1994 llvm::Constant *
Class = getNSConstantStringClassRef();
1997 if (!NSConstantStringType) {
1998 NSConstantStringType =
2000 "struct.__builtin_NSString");
2004 auto Fields = Builder.beginStruct(NSConstantStringType);
2011 llvm::ConstantDataArray::getString(VMContext, Entry.first());
2013 llvm::GlobalValue::LinkageTypes
Linkage = llvm::GlobalValue::PrivateLinkage;
2014 bool isConstant = !CGM.
getLangOpts().WritableStrings;
2016 auto *GV =
new llvm::GlobalVariable(CGM.
getModule(),
C->getType(), isConstant,
2018 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2021 GV->setAlignment(llvm::Align(1));
2025 Fields.addInt(CGM.
IntTy, StringLength);
2029 GV = Fields.finishAndCreateGlobal(
"_unnamed_nsstring_", Alignment,
2031 llvm::GlobalVariable::PrivateLinkage);
2032 const char *NSStringSection =
"__OBJC,__cstring_object,regular,no_dead_strip";
2033 const char *NSStringNonFragileABISection =
2034 "__DATA,__objc_stringobj,regular,no_dead_strip";
2037 ? NSStringNonFragileABISection
2057 bool isCategoryImpl,
2058 llvm::Value *Receiver,
2059 bool IsClassMessage,
2066 llvm::Value *ReceiverAsObject =
2067 CGF.
Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
2072 llvm::Type *ClassTyPtr = llvm::PointerType::getUnqual(ObjCTypes.ClassTy);
2074 if (IsClassMessage) {
2075 if (isCategoryImpl) {
2082 Target = EmitClassRef(CGF,
Class->getSuperClass());
2087 llvm::Constant *MetaClassPtr = EmitMetaClassRef(
Class);
2088 llvm::Value *SuperPtr =
2094 }
else if (isCategoryImpl)
2095 Target = EmitClassRef(CGF,
Class->getSuperClass());
2097 llvm::Value *ClassPtr = EmitSuperClassRef(Class);
2104 llvm::Type *ClassTy =
2108 return EmitMessageSend(CGF, Return, ResultType, Sel, ObjCSuper.
getPointer(),
2109 ObjCTypes.SuperPtrCTy,
true, CallArgs, Method, Class,
2118 llvm::Value *Receiver,
2122 return EmitMessageSend(CGF, Return, ResultType, Sel, Receiver,
2124 Method, Class, ObjCTypes);
2138 const ObjCCommonTypesHelper &ObjCTypes) {
2141 llvm::Value *SelValue = llvm::UndefValue::get(Types.ConvertType(selTy));
2145 Arg0 = CGF.
Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy);
2152 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2157 "Result type mismatch!");
2159 bool ReceiverCanBeNull =
2160 canMessageReceiverBeNull(CGF, Method, IsSuper, ClassReceiver, Arg0);
2162 bool RequiresNullCheck =
false;
2163 bool RequiresSelValue =
true;
2165 llvm::FunctionCallee
Fn =
nullptr;
2171 RequiresSelValue =
false;
2173 if (ReceiverCanBeNull) RequiresNullCheck =
true;
2174 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
2175 : ObjCTypes.getSendStretFn(IsSuper);
2177 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
2178 : ObjCTypes.getSendFpretFn(IsSuper);
2180 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)
2181 : ObjCTypes.getSendFp2retFn(IsSuper);
2186 RequiresNullCheck =
true;
2187 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
2188 : ObjCTypes.getSendFn(IsSuper);
2192 llvm::Constant *BitcastFn = cast<llvm::Constant>(
2193 CGF.
Builder.CreateBitCast(
Fn.getCallee(), MSI.MessengerType));
2198 RequiresNullCheck =
false;
2202 RequiresNullCheck =
true;
2204 NullReturnState nullReturn;
2205 if (RequiresNullCheck) {
2206 nullReturn.init(CGF, Arg0);
2210 if (RequiresSelValue) {
2211 SelValue = GetSelector(CGF, Sel);
2215 llvm::CallBase *CallSite;
2217 RValue rvalue = CGF.
EmitCall(MSI.CallInfo, Callee, Return, ActualArgs,
2222 if (Method && Method->
hasAttr<NoReturnAttr>() && !ReceiverCanBeNull) {
2223 CallSite->setDoesNotReturn();
2226 return nullReturn.complete(CGF, Return, rvalue, ResultType, CallArgs,
2227 RequiresNullCheck ? Method :
nullptr);
2231 bool pointee =
false) {
2244 switch (ownership) {
2251 llvm_unreachable(
"bad objc ownership");
2259 if (Ctx.
getLangOpts().getGC() != LangOptions::NonGC) {
2271 IvarInfo(
CharUnits offset, uint64_t sizeInWords)
2272 : Offset(offset), SizeInWords(sizeInWords) {}
2275 bool operator<(
const IvarInfo &other)
const {
2276 return Offset < other.Offset;
2281 class IvarLayoutBuilder {
2292 bool ForStrongLayout;
2295 bool IsDisordered =
false;
2301 CharUnits instanceEnd,
bool forStrongLayout)
2302 : CGM(CGM), InstanceBegin(instanceBegin), InstanceEnd(instanceEnd),
2303 ForStrongLayout(forStrongLayout) {
2308 template <
class Iterator,
class GetOffsetFn>
2309 void visitAggregate(Iterator begin, Iterator end,
2311 const GetOffsetFn &getOffset);
2319 bool hasBitmapData()
const {
return !IvarsInfo.empty(); }
2321 llvm::Constant *buildBitmap(CGObjCCommonMac &CGObjC,
2325 const unsigned char *
s = buffer.data();
2326 for (
unsigned i = 0, e = buffer.size(); i < e; i++)
2328 printf(
"0x0%x%s",
s[i],
s[i] != 0 ?
", " :
"");
2330 printf(
"0x%x%s",
s[i],
s[i] != 0 ?
", " :
"");
2336llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(
CodeGenModule &CGM,
2339 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2340 if (CGM.
getLangOpts().getGC() == LangOptions::NonGC)
2346 builder.visitBlock(blockInfo);
2348 if (!builder.hasBitmapData())
2352 llvm::Constant *
C = builder.buildBitmap(*
this, buffer);
2353 if (CGM.
getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
2354 printf(
"\n block variable layout for block: ");
2355 builder.dump(buffer);
2361void IvarLayoutBuilder::visitBlock(
const CGBlockInfo &blockInfo) {
2374 for (
const auto &CI :
blockDecl->captures()) {
2375 const VarDecl *variable = CI.getVariable();
2387 if (fieldOffset < lastFieldOffset)
2388 IsDisordered =
true;
2389 lastFieldOffset = fieldOffset;
2393 IvarsInfo.push_back(IvarInfo(fieldOffset, 1));
2397 assert(!
type->isArrayType() &&
"array variable should not be caught");
2399 visitRecord(record, fieldOffset);
2408 IvarsInfo.push_back(IvarInfo(fieldOffset, 1));
2433void CGObjCCommonMac::UpdateRunSkipBlockVars(
bool IsByref,
2439 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset,
2442 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset,
2445 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset,
2448 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset,
2451 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES,
2456void CGObjCCommonMac::BuildRCRecordLayout(
const llvm::StructLayout *RecLayout,
2461 bool IsUnion = (RD && RD->
isUnion());
2464 const FieldDecl *LastFieldBitfieldOrUnnamed =
nullptr;
2468 if (RecFields.empty())
2472 for (
unsigned i = 0, e = RecFields.size(); i != e; ++i) {
2481 if (!
Field->getIdentifier() ||
Field->isBitField()) {
2482 LastFieldBitfieldOrUnnamed =
Field;
2483 LastBitfieldOrUnnamedOffset = FieldOffset;
2487 LastFieldBitfieldOrUnnamed =
nullptr;
2494 BytePos + FieldOffset, HasUnion);
2499 auto *CArray = cast<ConstantArrayType>(Array);
2500 uint64_t ElCount = CArray->getZExtSize();
2501 assert(CArray &&
"only array with known element size is supported");
2502 FQT = CArray->getElementType();
2504 auto *CArray = cast<ConstantArrayType>(Array);
2505 ElCount *= CArray->getZExtSize();
2506 FQT = CArray->getElementType();
2509 int OldIndex = RunSkipBlockVars.size() - 1;
2511 BuildRCBlockVarRecordLayout(RT, BytePos + FieldOffset, HasUnion);
2516 for (
int FirstIndex = RunSkipBlockVars.size() - 1 ;ElIx < ElCount; ElIx++) {
2518 for (
int i = OldIndex+1; i <= FirstIndex; ++i)
2519 RunSkipBlockVars.push_back(
2520 RUN_SKIP(RunSkipBlockVars[i].opcode,
2521 RunSkipBlockVars[i].block_var_bytepos + Size*ElIx,
2522 RunSkipBlockVars[i].block_var_size));
2530 if (UnionIvarSize > MaxUnionSize) {
2531 MaxUnionSize = UnionIvarSize;
2533 MaxFieldOffset = FieldOffset;
2536 UpdateRunSkipBlockVars(
false,
2537 getBlockCaptureLifetime(FQT, ByrefLayout),
2538 BytePos + FieldOffset,
2543 if (LastFieldBitfieldOrUnnamed) {
2544 if (LastFieldBitfieldOrUnnamed->
isBitField()) {
2547 unsigned UnsSize = (BitFieldSize / ByteSizeInBits) +
2548 ((BitFieldSize % ByteSizeInBits) != 0);
2550 Size += LastBitfieldOrUnnamedOffset;
2551 UpdateRunSkipBlockVars(
false,
2552 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
2554 BytePos + LastBitfieldOrUnnamedOffset,
2557 assert(!LastFieldBitfieldOrUnnamed->
getIdentifier() &&
"Expected unnamed");
2561 UpdateRunSkipBlockVars(
false,
2562 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->
getType(),
2564 BytePos + LastBitfieldOrUnnamedOffset,
2570 UpdateRunSkipBlockVars(
false,
2571 getBlockCaptureLifetime(MaxField->
getType(), ByrefLayout),
2572 BytePos + MaxFieldOffset,
2576void CGObjCCommonMac::BuildRCBlockVarRecordLayout(
const RecordType *RT,
2583 const llvm::StructLayout *RecLayout =
2584 CGM.
getDataLayout().getStructLayout(cast<llvm::StructType>(Ty));
2586 BuildRCRecordLayout(RecLayout, RD, Fields, BytePos, HasUnion, ByrefLayout);
2598uint64_t CGObjCCommonMac::InlineLayoutInstruction(
2601 if (Layout.size() <= 3) {
2602 unsigned size = Layout.size();
2603 unsigned strong_word_count = 0, byref_word_count=0, weak_word_count=0;
2605 enum BLOCK_LAYOUT_OPCODE opcode ;
2609 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2610 if (opcode == BLOCK_LAYOUT_STRONG)
2611 strong_word_count = (inst & 0xF)+1;
2615 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2616 if (opcode == BLOCK_LAYOUT_BYREF)
2617 byref_word_count = (inst & 0xF)+1;
2621 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2622 if (opcode == BLOCK_LAYOUT_WEAK)
2623 weak_word_count = (inst & 0xF)+1;
2630 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2631 if (opcode == BLOCK_LAYOUT_STRONG) {
2632 strong_word_count = (inst & 0xF)+1;
2634 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2635 if (opcode == BLOCK_LAYOUT_BYREF)
2636 byref_word_count = (inst & 0xF)+1;
2637 else if (opcode == BLOCK_LAYOUT_WEAK)
2638 weak_word_count = (inst & 0xF)+1;
2642 else if (opcode == BLOCK_LAYOUT_BYREF) {
2643 byref_word_count = (inst & 0xF)+1;
2645 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2646 if (opcode == BLOCK_LAYOUT_WEAK)
2647 weak_word_count = (inst & 0xF)+1;
2657 opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2658 if (opcode == BLOCK_LAYOUT_STRONG)
2659 strong_word_count = (inst & 0xF)+1;
2660 else if (opcode == BLOCK_LAYOUT_BYREF)
2661 byref_word_count = (inst & 0xF)+1;
2662 else if (opcode == BLOCK_LAYOUT_WEAK)
2663 weak_word_count = (inst & 0xF)+1;
2675 if (strong_word_count == 16 || byref_word_count == 16 || weak_word_count == 16)
2679 (strong_word_count != 0) + (byref_word_count != 0) + (weak_word_count != 0);
2681 if (size == count) {
2682 if (strong_word_count)
2683 Result = strong_word_count;
2685 if (byref_word_count)
2686 Result += byref_word_count;
2688 if (weak_word_count)
2689 Result += weak_word_count;
2695llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(
bool ComputeByrefLayout) {
2696 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2697 if (RunSkipBlockVars.empty())
2701 unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2705 llvm::array_pod_sort(RunSkipBlockVars.begin(), RunSkipBlockVars.end());
2708 unsigned size = RunSkipBlockVars.size();
2709 for (
unsigned i = 0; i < size; i++) {
2710 enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode;
2711 CharUnits start_byte_pos = RunSkipBlockVars[i].block_var_bytepos;
2712 CharUnits end_byte_pos = start_byte_pos;
2715 if (opcode == RunSkipBlockVars[j].opcode) {
2716 end_byte_pos = RunSkipBlockVars[j++].block_var_bytepos;
2723 end_byte_pos - start_byte_pos + RunSkipBlockVars[j-1].block_var_size;
2726 RunSkipBlockVars[j].block_var_bytepos -
2727 RunSkipBlockVars[j-1].block_var_bytepos - RunSkipBlockVars[j-1].block_var_size;
2728 size_in_bytes += gap;
2731 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) {
2732 residue_in_bytes = size_in_bytes % WordSizeInBytes;
2733 size_in_bytes -= residue_in_bytes;
2734 opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS;
2737 unsigned size_in_words = size_in_bytes.
getQuantity() / WordSizeInBytes;
2738 while (size_in_words >= 16) {
2741 unsigned char inst = (opcode << 4) | 0xf;
2742 Layout.push_back(inst);
2743 size_in_words -= 16;
2745 if (size_in_words > 0) {
2748 unsigned char inst = (opcode << 4) | (size_in_words-1);
2749 Layout.push_back(inst);
2752 unsigned char inst =
2753 (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) | (residue_in_bytes.
getQuantity()-1);
2754 Layout.push_back(inst);
2758 while (!Layout.empty()) {
2759 unsigned char inst = Layout.back();
2760 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2761 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES || opcode == BLOCK_LAYOUT_NON_OBJECT_WORDS)
2767 uint64_t Result = InlineLayoutInstruction(Layout);
2771 if (ComputeByrefLayout)
2772 printf(
"\n Inline BYREF variable layout: ");
2774 printf(
"\n Inline block variable layout: ");
2775 printf(
"0x0%" PRIx64
"", Result);
2776 if (
auto numStrong = (Result & 0xF00) >> 8)
2777 printf(
", BL_STRONG:%d", (
int) numStrong);
2778 if (
auto numByref = (Result & 0x0F0) >> 4)
2779 printf(
", BL_BYREF:%d", (
int) numByref);
2780 if (
auto numWeak = (Result & 0x00F) >> 0)
2781 printf(
", BL_WEAK:%d", (
int) numWeak);
2782 printf(
", BL_OPERATOR:0\n");
2784 return llvm::ConstantInt::get(CGM.
IntPtrTy, Result);
2787 unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0;
2788 Layout.push_back(inst);
2790 for (
unsigned i = 0, e = Layout.size(); i != e; i++)
2791 BitMap += Layout[i];
2794 if (ComputeByrefLayout)
2795 printf(
"\n Byref variable layout: ");
2797 printf(
"\n Block variable layout: ");
2798 for (
unsigned i = 0, e = BitMap.size(); i != e; i++) {
2799 unsigned char inst = BitMap[i];
2800 enum BLOCK_LAYOUT_OPCODE opcode = (
enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2803 case BLOCK_LAYOUT_OPERATOR:
2807 case BLOCK_LAYOUT_NON_OBJECT_BYTES:
2808 printf(
"BL_NON_OBJECT_BYTES:");
2810 case BLOCK_LAYOUT_NON_OBJECT_WORDS:
2811 printf(
"BL_NON_OBJECT_WORD:");
2813 case BLOCK_LAYOUT_STRONG:
2816 case BLOCK_LAYOUT_BYREF:
2819 case BLOCK_LAYOUT_WEAK:
2822 case BLOCK_LAYOUT_UNRETAINED:
2823 printf(
"BL_UNRETAINED:");
2828 printf(
"%d", (inst & 0xf) + delta);
2836 auto *Entry = CreateCStringLiteral(BitMap, ObjCLabelType::ClassName,
2844 bool HasCopyDisposeHelpers) {
2846 for (
const CGObjCCommonMac::RUN_SKIP &R : RunSkipBlockVars) {
2847 if (R.opcode == CGObjCCommonMac::BLOCK_LAYOUT_UNRETAINED) {
2851 }
else if (HasCopyDisposeHelpers) {
2859 case CGObjCCommonMac::BLOCK_LAYOUT_STRONG:
2862 case CGObjCCommonMac::BLOCK_LAYOUT_BYREF:
2865 case CGObjCCommonMac::BLOCK_LAYOUT_WEAK:
2872 Str += llvm::to_string(R.block_var_bytepos.getQuantity());
2873 Str +=
"l" + llvm::to_string(R.block_var_size.getQuantity());
2878void CGObjCCommonMac::fillRunSkipBlockVars(
CodeGenModule &CGM,
2880 assert(CGM.
getLangOpts().getGC() == LangOptions::NonGC);
2882 RunSkipBlockVars.clear();
2883 bool hasUnion =
false;
2887 unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2892 const llvm::StructLayout *layout =
2902 for (
const auto &CI :
blockDecl->captures()) {
2903 const VarDecl *variable = CI.getVariable();
2914 assert(!
type->isArrayType() &&
"array variable should not be caught");
2917 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion);
2925 UpdateRunSkipBlockVars(CI.isByRef(), getBlockCaptureLifetime(
type,
false),
2926 fieldOffset, fieldSize);
2933 fillRunSkipBlockVars(CGM, blockInfo);
2934 return getBitmapBlockLayout(
false);
2937std::string CGObjCCommonMac::getRCBlockLayoutStr(
CodeGenModule &CGM,
2939 fillRunSkipBlockVars(CGM, blockInfo);
2945 assert(CGM.
getLangOpts().getGC() == LangOptions::NonGC);
2946 assert(!
T->
isArrayType() &&
"__block array variable should not be caught");
2948 RunSkipBlockVars.clear();
2949 bool hasUnion =
false;
2951 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion,
true );
2952 llvm::Constant *Result = getBitmapBlockLayout(
true);
2953 if (isa<llvm::ConstantInt>(Result))
2954 Result = llvm::ConstantExpr::getIntToPtr(Result, CGM.
Int8PtrTy);
2957 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
2967 return GetProtocolRef(PD);
2979 GetOrEmitProtocol(PD);
2982llvm::Constant *CGObjCCommonMac::GetProtocolRef(
const ObjCProtocolDecl *PD) {
2984 return GetOrEmitProtocol(PD);
2986 return GetOrEmitProtocolRef(PD);
2989llvm::Value *CGObjCCommonMac::EmitClassRefViaRuntime(
2992 ObjCCommonTypesHelper &ObjCTypes) {
2993 llvm::FunctionCallee lookUpClassFn = ObjCTypes.getLookUpClassFn();
2995 llvm::Value *className = CGF.
CGM
2997 ID->getObjCRuntimeNameAsString()))
3001 CGF.
Builder.CreateBitCast(className,
3004 llvm::CallInst *call = CGF.
Builder.CreateCall(lookUpClassFn, className);
3005 call->setDoesNotThrow();
3022 llvm::GlobalVariable *Entry = Protocols[PD->
getIdentifier()];
3025 if (Entry && Entry->hasInitializer())
3037 auto methodLists = ProtocolMethodLists::get(PD);
3040 auto values = builder.beginStruct(ObjCTypes.ProtocolTy);
3041 values.add(EmitProtocolExtension(PD, methodLists));
3043 values.add(EmitProtocolList(
"OBJC_PROTOCOL_REFS_" + PD->
getName(),
3045 values.add(methodLists.emitMethodList(
this, PD,
3046 ProtocolMethodLists::RequiredInstanceMethods));
3047 values.add(methodLists.emitMethodList(
this, PD,
3048 ProtocolMethodLists::RequiredClassMethods));
3052 assert(Entry->hasPrivateLinkage());
3053 values.finishAndSetAsInitializer(Entry);
3055 Entry = values.finishAndCreateGlobal(
"OBJC_PROTOCOL_" + PD->
getName(),
3058 llvm::GlobalValue::PrivateLinkage);
3059 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
3068llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(
const ObjCProtocolDecl *PD) {
3069 llvm::GlobalVariable *&Entry = Protocols[PD->
getIdentifier()];
3075 Entry =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ProtocolTy,
3076 false, llvm::GlobalValue::PrivateLinkage,
3077 nullptr,
"OBJC_PROTOCOL_" + PD->
getName());
3078 Entry->setSection(
"__OBJC,__protocol,regular,no_dead_strip");
3080 Entry->setAlignment(llvm::Align(4));
3098 const ProtocolMethodLists &methodLists) {
3099 auto optInstanceMethods =
3100 methodLists.emitMethodList(
this, PD,
3101 ProtocolMethodLists::OptionalInstanceMethods);
3102 auto optClassMethods =
3103 methodLists.emitMethodList(
this, PD,
3104 ProtocolMethodLists::OptionalClassMethods);
3106 auto extendedMethodTypes =
3107 EmitProtocolMethodTypes(
"OBJC_PROTOCOL_METHOD_TYPES_" + PD->
getName(),
3108 methodLists.emitExtendedTypesArray(
this),
3111 auto instanceProperties =
3112 EmitPropertyList(
"OBJC_$_PROP_PROTO_LIST_" + PD->
getName(),
nullptr, PD,
3114 auto classProperties =
3115 EmitPropertyList(
"OBJC_$_CLASS_PROP_PROTO_LIST_" + PD->
getName(),
nullptr,
3116 PD, ObjCTypes,
true);
3119 if (optInstanceMethods->isNullValue() &&
3120 optClassMethods->isNullValue() &&
3121 extendedMethodTypes->isNullValue() &&
3122 instanceProperties->isNullValue() &&
3123 classProperties->isNullValue()) {
3124 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
3128 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
3131 auto values = builder.beginStruct(ObjCTypes.ProtocolExtensionTy);
3132 values.addInt(ObjCTypes.IntTy, size);
3133 values.add(optInstanceMethods);
3134 values.add(optClassMethods);
3135 values.add(instanceProperties);
3136 values.add(extendedMethodTypes);
3137 values.add(classProperties);
3140 return CreateMetadataVar(
"_OBJC_PROTOCOLEXT_" + PD->
getName(), values,
3152CGObjCMac::EmitProtocolList(Twine name,
3156 auto PDs = GetRuntimeProtocolList(begin, end);
3158 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
3161 auto values = builder.beginStruct();
3164 values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
3167 auto countSlot = values.addPlaceholder();
3169 auto refsArray = values.beginArray(ObjCTypes.ProtocolPtrTy);
3170 for (
const auto *Proto : PDs)
3171 refsArray.add(GetProtocolRef(Proto));
3173 auto count = refsArray.size();
3176 refsArray.addNullPointer(ObjCTypes.ProtocolPtrTy);
3178 refsArray.finishAndAddTo(values);
3179 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
3182 if (CGM.
getTriple().isOSBinFormatMachO())
3183 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3185 llvm::GlobalVariable *GV =
3186 CreateMetadataVar(name, values, section, CGM.
getPointerAlign(),
false);
3194 bool IsClassProperty) {
3196 if (IsClassProperty != PD->isClassProperty())
3200 Properties.push_back(PD);
3219llvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name,
3220 const Decl *Container,
3222 const ObjCCommonTypesHelper &ObjCTypes,
3223 bool IsClassProperty) {
3224 if (IsClassProperty) {
3228 if ((Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 11)) ||
3229 (Triple.isiOS() && Triple.isOSVersionLT(9)))
3230 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3238 for (
auto *PD : ClassExt->properties()) {
3239 if (IsClassProperty != PD->isClassProperty())
3241 if (PD->isDirectProperty())
3244 Properties.push_back(PD);
3248 if (IsClassProperty != PD->isClassProperty())
3254 if (PD->isDirectProperty())
3256 Properties.push_back(PD);
3260 for (
const auto *
P : OID->all_referenced_protocols())
3264 for (
const auto *
P : CD->protocols())
3269 if (Properties.empty())
3270 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3272 unsigned propertySize =
3276 auto values = builder.beginStruct();
3277 values.addInt(ObjCTypes.IntTy, propertySize);
3278 values.addInt(ObjCTypes.IntTy, Properties.size());
3279 auto propertiesArray = values.beginArray(ObjCTypes.PropertyTy);
3280 for (
auto PD : Properties) {
3281 auto property = propertiesArray.beginStruct(ObjCTypes.PropertyTy);
3283 property.add(GetPropertyTypeString(PD, Container));
3284 property.finishAndAddTo(propertiesArray);
3286 propertiesArray.finishAndAddTo(values);
3289 if (CGM.
getTriple().isOSBinFormatMachO())
3290 Section = (ObjCABI == 2) ?
"__DATA, __objc_const"
3291 :
"__OBJC,__property,regular,no_dead_strip";
3293 llvm::GlobalVariable *GV =
3294 CreateMetadataVar(Name, values, Section, CGM.
getPointerAlign(),
true);
3299CGObjCCommonMac::EmitProtocolMethodTypes(Twine Name,
3301 const ObjCCommonTypesHelper &ObjCTypes) {
3303 if (MethodTypes.empty())
3304 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy);
3306 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
3307 MethodTypes.size());
3308 llvm::Constant *
Init = llvm::ConstantArray::get(AT, MethodTypes);
3311 if (CGM.
getTriple().isOSBinFormatMachO() && ObjCABI == 2)
3312 Section =
"__DATA, __objc_const";
3314 llvm::GlobalVariable *GV =
3343 llvm::raw_svector_ostream(ExtName) <<
Interface->getName() <<
'_'
3347 auto Values = Builder.beginStruct(ObjCTypes.CategoryTy);
3355 for (
const auto *MD : OCD->
methods()) {
3356 if (!MD->isDirectMethod())
3357 Methods[
unsigned(MD->isClassMethod())].push_back(MD);
3360 Values.add(GetClassName(OCD->
getName()));
3361 Values.add(GetClassName(
Interface->getObjCRuntimeNameAsString()));
3362 LazySymbols.insert(
Interface->getIdentifier());
3364 Values.add(emitMethodList(ExtName, MethodListType::CategoryInstanceMethods,
3365 Methods[InstanceMethods]));
3366 Values.add(emitMethodList(ExtName, MethodListType::CategoryClassMethods,
3367 Methods[ClassMethods]));
3370 EmitProtocolList(
"OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
3373 Values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
3375 Values.addInt(ObjCTypes.IntTy, Size);
3379 Values.add(EmitPropertyList(
"_OBJC_$_PROP_LIST_" + ExtName.str(),
3381 Values.add(EmitPropertyList(
"_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(),
3384 Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
3385 Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
3388 llvm::GlobalVariable *GV =
3389 CreateMetadataVar(
"OBJC_CATEGORY_" + ExtName.str(), Values,
3390 "__OBJC,__category,regular,no_dead_strip",
3392 DefinedCategories.push_back(GV);
3393 DefinedCategoryNames.insert(llvm::CachedHashString(ExtName));
3395 MethodDefinitions.clear();
3455 for (
auto *field : recType->getDecl()->fields()) {
3470 assert(CGM.
getLangOpts().getGC() == LangOptions::NonGC);
3473 ID->getClassInterface()->all_declared_ivar_begin();
3474 ivar; ivar = ivar->getNextIvar()) {
3504 DefinedSymbols.insert(RuntimeName);
3506 std::string ClassName =
ID->getNameAsString();
3510 llvm::Constant *Protocols =
3511 EmitProtocolList(
"OBJC_CLASS_PROTOCOLS_" +
ID->getName(),
3512 Interface->all_referenced_protocol_begin(),
3513 Interface->all_referenced_protocol_end());
3515 if (
ID->hasNonZeroConstructors() ||
ID->hasDestructors())
3518 bool hasMRCWeak =
false;
3538 for (
const auto *MD :
ID->methods()) {
3539 if (!MD->isDirectMethod())
3540 Methods[
unsigned(MD->isClassMethod())].push_back(MD);
3543 for (
const auto *PID :
ID->property_impls()) {
3545 if (PID->getPropertyDecl()->isDirectProperty())
3548 if (GetMethodDefinition(MD))
3549 Methods[InstanceMethods].push_back(MD);
3551 if (GetMethodDefinition(MD))
3552 Methods[InstanceMethods].push_back(MD);
3557 auto values = builder.beginStruct(ObjCTypes.ClassTy);
3558 values.add(EmitMetaClass(ID, Protocols, Methods[ClassMethods]));
3561 LazySymbols.insert(Super->getIdentifier());
3563 values.add(GetClassName(Super->getObjCRuntimeNameAsString()));
3565 values.addNullPointer(ObjCTypes.ClassPtrTy);
3567 values.add(GetClassName(
ID->getObjCRuntimeNameAsString()));
3569 values.addInt(ObjCTypes.LongTy, 0);
3570 values.addInt(ObjCTypes.LongTy, Flags);
3571 values.addInt(ObjCTypes.LongTy,
Size.getQuantity());
3572 values.add(EmitIvarList(ID,
false));
3573 values.add(emitMethodList(
ID->getName(), MethodListType::InstanceMethods,
3574 Methods[InstanceMethods]));
3576 values.addNullPointer(ObjCTypes.CachePtrTy);
3577 values.add(Protocols);
3579 values.add(EmitClassExtension(ID, Size, hasMRCWeak,
3582 std::string Name(
"OBJC_CLASS_");
3584 const char *Section =
"__OBJC,__class,regular,no_dead_strip";
3586 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3588 assert(GV->getValueType() == ObjCTypes.ClassTy &&
3589 "Forward metaclass reference has incorrect type.");
3590 values.finishAndSetAsInitializer(GV);
3591 GV->setSection(Section);
3595 GV = CreateMetadataVar(Name, values, Section, CGM.
getPointerAlign(),
true);
3596 DefinedClasses.push_back(GV);
3597 ImplementedClasses.push_back(
Interface);
3599 MethodDefinitions.clear();
3603 llvm::Constant *Protocols,
3612 auto values = builder.beginStruct(ObjCTypes.ClassTy);
3622 values.add(GetClassName(Super->getObjCRuntimeNameAsString()));
3624 values.addNullPointer(ObjCTypes.ClassPtrTy);
3626 values.add(GetClassName(
ID->getObjCRuntimeNameAsString()));
3628 values.addInt(ObjCTypes.LongTy, 0);
3629 values.addInt(ObjCTypes.LongTy, Flags);
3630 values.addInt(ObjCTypes.LongTy, Size);
3631 values.add(EmitIvarList(ID,
true));
3632 values.add(emitMethodList(
ID->getName(), MethodListType::ClassMethods,
3635 values.addNullPointer(ObjCTypes.CachePtrTy);
3636 values.add(Protocols);
3638 values.addNullPointer(ObjCTypes.Int8PtrTy);
3643 std::string Name(
"OBJC_METACLASS_");
3644 Name +=
ID->getName();
3647 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3649 assert(GV->getValueType() == ObjCTypes.ClassTy &&
3650 "Forward metaclass reference has incorrect type.");
3651 values.finishAndSetAsInitializer(GV);
3655 llvm::GlobalValue::PrivateLinkage);
3657 GV->setSection(
"__OBJC,__meta_class,regular,no_dead_strip");
3664 std::string Name =
"OBJC_METACLASS_" +
ID->getNameAsString();
3674 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3676 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
3677 llvm::GlobalValue::PrivateLinkage,
nullptr,
3680 assert(GV->getValueType() == ObjCTypes.ClassTy &&
3681 "Forward metaclass reference has incorrect type.");
3686 std::string Name =
"OBJC_CLASS_" +
ID->getNameAsString();
3687 llvm::GlobalVariable *GV = CGM.
getModule().getGlobalVariable(Name,
true);
3690 GV =
new llvm::GlobalVariable(CGM.
getModule(), ObjCTypes.ClassTy,
false,
3691 llvm::GlobalValue::PrivateLinkage,
nullptr,
3694 assert(GV->getValueType() == ObjCTypes.ClassTy &&
3695 "Forward class metadata reference has incorrect type.");
3715 llvm::Constant *layout;
3717 layout = llvm::ConstantPointerNull::get(CGM.
Int8PtrTy);
3724 llvm::Constant *propertyList =
3725 EmitPropertyList((isMetaclass ? Twine(
"_OBJC_$_CLASS_PROP_LIST_")
3726 : Twine(
"_OBJC_$_PROP_LIST_"))
3728 ID,
ID->getClassInterface(), ObjCTypes, isMetaclass);
3731 if (layout->isNullValue() && propertyList->isNullValue()) {
3732 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
3736 CGM.
getDataLayout().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
3739 auto values = builder.beginStruct(ObjCTypes.ClassExtensionTy);
3740 values.addInt(ObjCTypes.IntTy, size);
3742 values.add(propertyList);
3744 return CreateMetadataVar(
"OBJC_CLASSEXT_" +
ID->getName(), values,
3745 "__OBJC,__class_ext,regular,no_dead_strip",
3769 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3774 auto ivarList = builder.beginStruct();
3775 auto countSlot = ivarList.addPlaceholder();
3776 auto ivars = ivarList.beginArray(ObjCTypes.IvarTy);
3781 if (!IVD->getDeclName())
3784 auto ivar = ivars.beginStruct(ObjCTypes.IvarTy);
3785 ivar.add(GetMethodVarName(IVD->getIdentifier()));
3786 ivar.add(GetMethodVarType(IVD));
3787 ivar.addInt(ObjCTypes.IntTy, ComputeIvarBaseOffset(CGM, OID, IVD));
3788 ivar.finishAndAddTo(ivars);
3792 auto count = ivars.size();
3796 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3799 ivars.finishAndAddTo(ivarList);
3800 ivarList.fillPlaceholderWithInt(countSlot, ObjCTypes.IntTy, count);
3802 llvm::GlobalVariable *GV;
3803 GV = CreateMetadataVar(
"OBJC_INSTANCE_VARIABLES_" +
ID->getName(), ivarList,
3804 "__OBJC,__instance_vars,regular,no_dead_strip",
3817 auto description = builder.
beginStruct(ObjCTypes.MethodDescriptionTy);
3818 description.add(GetMethodVarName(MD->
getSelector()));
3819 description.add(GetMethodVarType(MD));
3820 description.finishAndAddTo(builder);
3832 llvm::Function *fn = GetMethodDefinition(MD);
3833 assert(fn &&
"no definition registered for method");
3835 auto method = builder.
beginStruct(ObjCTypes.MethodTy);
3837 method.add(GetMethodVarType(MD));
3839 method.finishAndAddTo(builder);
3855llvm::Constant *CGObjCMac::emitMethodList(Twine name, MethodListType MLT,
3859 bool forProtocol =
false;
3861 case MethodListType::CategoryInstanceMethods:
3862 prefix =
"OBJC_CATEGORY_INSTANCE_METHODS_";
3863 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
3864 forProtocol =
false;
3866 case MethodListType::CategoryClassMethods:
3867 prefix =
"OBJC_CATEGORY_CLASS_METHODS_";
3868 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3869 forProtocol =
false;
3871 case MethodListType::InstanceMethods:
3872 prefix =
"OBJC_INSTANCE_METHODS_";
3873 section =
"__OBJC,__inst_meth,regular,no_dead_strip";
3874 forProtocol =
false;
3876 case MethodListType::ClassMethods:
3877 prefix =
"OBJC_CLASS_METHODS_";
3878 section =
"__OBJC,__cls_meth,regular,no_dead_strip";
3879 forProtocol =
false;
3881 case MethodListType::ProtocolInstanceMethods:
3882 prefix =
"OBJC_PROTOCOL_INSTANCE_METHODS_";
3883 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
3886 case MethodListType::ProtocolClassMethods:
3887 prefix =
"OBJC_PROTOCOL_CLASS_METHODS_";
3888 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3891 case MethodListType::OptionalProtocolInstanceMethods:
3892 prefix =
"OBJC_PROTOCOL_INSTANCE_METHODS_OPT_";
3893 section =
"__OBJC,__cat_inst_meth,regular,no_dead_strip";
3896 case MethodListType::OptionalProtocolClassMethods:
3897 prefix =
"OBJC_PROTOCOL_CLASS_METHODS_OPT_";
3898 section =
"__OBJC,__cat_cls_meth,regular,no_dead_strip";
3904 if (methods.empty())
3905 return llvm::Constant::getNullValue(forProtocol
3906 ? ObjCTypes.MethodDescriptionListPtrTy
3907 : ObjCTypes.MethodListPtrTy);
3914 values.addInt(ObjCTypes.IntTy, methods.size());
3915 auto methodArray = values.beginArray(ObjCTypes.MethodDescriptionTy);
3916 for (
auto MD : methods) {
3917 emitMethodDescriptionConstant(methodArray, MD);
3919 methodArray.finishAndAddTo(values);
3921 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
3929 values.addNullPointer(ObjCTypes.Int8PtrTy);
3930 values.addInt(ObjCTypes.IntTy, methods.size());
3931 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
3932 for (
auto MD : methods) {
3934 emitMethodConstant(methodArray, MD);
3936 methodArray.finishAndAddTo(values);
3938 llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
3943llvm::Function *CGObjCCommonMac::GenerateMethod(
const ObjCMethodDecl *OMD,
3945 llvm::Function *Method;
3948 Method = GenerateDirectMethod(OMD, CD);
3950 auto Name = getSymbolNameForMethod(OMD);
3953 llvm::FunctionType *MethodTy =
3954 Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
3956 llvm::Function::Create(MethodTy, llvm::GlobalValue::InternalLinkage,
3960 MethodDefinitions.insert(std::make_pair(OMD, Method));
3969 auto I = DirectMethodDefinitions.find(COMD);
3970 llvm::Function *OldFn =
nullptr, *
Fn =
nullptr;
3972 if (I != DirectMethodDefinitions.end()) {
3988 llvm::FunctionType *MethodTy =
3989 Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
3992 Fn = llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,
3994 Fn->takeName(OldFn);
3995 OldFn->replaceAllUsesWith(Fn);
3996 OldFn->eraseFromParent();
4001 auto Name = getSymbolNameForMethod(OMD,
false);
4003 Fn = llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,
4005 DirectMethodDefinitions.insert(std::make_pair(COMD, Fn));
4011void CGObjCCommonMac::GenerateDirectMethodPrologue(
4015 bool ReceiverCanBeNull =
true;
4017 auto selfValue = Builder.CreateLoad(selfAddr);
4035 "GenerateDirectMethod() should be called with the Class Interface");
4048 result = GeneratePossiblySpecializedMessageSend(
4056 ReceiverCanBeNull = isWeakLinkedClass(OID);
4059 if (ReceiverCanBeNull) {
4060 llvm::BasicBlock *SelfIsNilBlock =
4062 llvm::BasicBlock *ContBlock =
4066 auto selfTy = cast<llvm::PointerType>(selfValue->getType());
4067 auto Zero = llvm::ConstantPointerNull::get(selfTy);
4070 Builder.CreateCondBr(Builder.CreateICmpEQ(selfValue, Zero), SelfIsNilBlock,
4071 ContBlock, MDHelper.createUnlikelyBranchWeights());
4077 Builder.SetInsertPoint(SelfIsNilBlock);
4078 if (!retTy->isVoidType()) {
4086 Builder.SetInsertPoint(ContBlock);
4094 Builder.CreateStore(GetSelector(CGF, OMD),
4099llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
4104 llvm::GlobalValue::LinkageTypes
LT =
4106 llvm::GlobalVariable *GV =
4107 Init.finishAndCreateGlobal(Name, Align,
false,
LT);
4108 if (!Section.empty())
4109 GV->setSection(Section);
4115llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
4116 llvm::Constant *
Init,
4120 llvm::Type *Ty =
Init->getType();
4121 llvm::GlobalValue::LinkageTypes
LT =
4123 llvm::GlobalVariable *GV =
4125 if (!Section.empty())
4126 GV->setSection(Section);
4133llvm::GlobalVariable *
4134CGObjCCommonMac::CreateCStringLiteral(StringRef Name, ObjCLabelType
Type,
4135 bool ForceNonFragileABI,
4136 bool NullTerminate) {
4139 case ObjCLabelType::ClassName:
Label =
"OBJC_CLASS_NAME_";
break;
4140 case ObjCLabelType::MethodVarName:
Label =
"OBJC_METH_VAR_NAME_";
break;
4141 case ObjCLabelType::MethodVarType:
Label =
"OBJC_METH_VAR_TYPE_";
break;
4142 case ObjCLabelType::PropertyName:
Label =
"OBJC_PROP_NAME_ATTR_";
break;
4145 bool NonFragile = ForceNonFragileABI || isNonFragileABI();
4149 case ObjCLabelType::ClassName:
4150 Section = NonFragile ?
"__TEXT,__objc_classname,cstring_literals"
4151 :
"__TEXT,__cstring,cstring_literals";
4153 case ObjCLabelType::MethodVarName:
4154 Section = NonFragile ?
"__TEXT,__objc_methname,cstring_literals"
4155 :
"__TEXT,__cstring,cstring_literals";
4157 case ObjCLabelType::MethodVarType:
4158 Section = NonFragile ?
"__TEXT,__objc_methtype,cstring_literals"
4159 :
"__TEXT,__cstring,cstring_literals";
4161 case ObjCLabelType::PropertyName:
4162 Section = NonFragile ?
"__TEXT,__objc_methname,cstring_literals"
4163 :
"__TEXT,__cstring,cstring_literals";
4167 llvm::Constant *
Value =
4168 llvm::ConstantDataArray::getString(VMContext, Name, NullTerminate);
4169 llvm::GlobalVariable *GV =
4172 llvm::GlobalValue::PrivateLinkage,
Value,
Label);
4173 if (CGM.
getTriple().isOSBinFormatMachO())
4174 GV->setSection(Section);
4175 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4182llvm::Function *CGObjCMac::ModuleInitFunction() {
4188llvm::FunctionCallee CGObjCMac::GetPropertyGetFunction() {
4189 return ObjCTypes.getGetPropertyFn();
4192llvm::FunctionCallee CGObjCMac::GetPropertySetFunction() {
4193 return ObjCTypes.getSetPropertyFn();
4196llvm::FunctionCallee CGObjCMac::GetOptimizedPropertySetFunction(
bool atomic,
4198 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
4201llvm::FunctionCallee CGObjCMac::GetGetStructFunction() {
4202 return ObjCTypes.getCopyStructFn();
4205llvm::FunctionCallee CGObjCMac::GetSetStructFunction() {
4206 return ObjCTypes.getCopyStructFn();
4209llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectGetFunction() {
4210 return ObjCTypes.getCppAtomicObjectFunction();
4213llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectSetFunction() {
4214 return ObjCTypes.getCppAtomicObjectFunction();
4217llvm::FunctionCallee CGObjCMac::EnumerationMutationFunction() {
4218 return ObjCTypes.getEnumerationMutationFn();
4222 return EmitTryOrSynchronizedStmt(CGF, S);
4227 return EmitTryOrSynchronizedStmt(CGF, S);
4236 ObjCTypesHelper &ObjCTypes;
4237 PerformFragileFinally(
const Stmt *S,
4241 ObjCTypesHelper *ObjCTypes)
4242 : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
4243 ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
4248 llvm::BasicBlock *FinallyCallExit =
4250 llvm::BasicBlock *FinallyNoCallExit =
4253 FinallyCallExit, FinallyNoCallExit);
4261 if (isa<ObjCAtTryStmt>(S)) {
4263 cast<ObjCAtTryStmt>(S).getFinallyStmt()) {
4265 if (flags.isForEHCleanup())
return;
4269 llvm::Value *CurCleanupDest =
4272 CGF.
EmitStmt(FinallyStmt->getFinallyBody());
4291 class FragileHazards {
4294 llvm::DenseSet<llvm::BasicBlock*> BlocksBeforeTry;
4296 llvm::InlineAsm *ReadHazard;
4297 llvm::InlineAsm *WriteHazard;
4299 llvm::FunctionType *GetAsmFnType();
4301 void collectLocals();
4307 void emitWriteHazard();
4308 void emitHazardsInNewBlocks();
4320 if (Locals.empty())
return;
4323 for (llvm::Function::iterator
4324 I = CGF.
CurFn->begin(),
E = CGF.
CurFn->end(); I !=
E; ++I)
4325 BlocksBeforeTry.insert(&*I);
4327 llvm::FunctionType *AsmFnTy = GetAsmFnType();
4335 std::string Constraint;
4336 for (
unsigned I = 0,
E = Locals.size(); I !=
E; ++I) {
4337 if (I) Constraint +=
',';
4341 ReadHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
4349 std::string Constraint;
4350 for (
unsigned I = 0,
E = Locals.size(); I !=
E; ++I) {
4351 if (I) Constraint +=
',';
4352 Constraint +=
"=*m";
4355 WriteHazard = llvm::InlineAsm::get(AsmFnTy,
"", Constraint,
true,
false);
4360void FragileHazards::emitWriteHazard() {
4361 if (Locals.empty())
return;
4364 for (
auto Pair : llvm::enumerate(Locals))
4365 Call->addParamAttr(Pair.index(), llvm::Attribute::get(
4367 cast<llvm::AllocaInst>(Pair.value())->getAllocatedType()));
4370void FragileHazards::emitReadHazard(
CGBuilderTy &Builder) {
4371 assert(!Locals.empty());
4372 llvm::CallInst *call = Builder.CreateCall(ReadHazard, Locals);
4373 call->setDoesNotThrow();
4375 for (
auto Pair : llvm::enumerate(Locals))
4376 call->addParamAttr(Pair.index(), llvm::Attribute::get(
4377 Builder.getContext(), llvm::Attribute::ElementType,
4378 cast<llvm::AllocaInst>(Pair.value())->getAllocatedType()));
4383void FragileHazards::emitHazardsInNewBlocks() {
4384 if (Locals.empty())
return;
4389 for (llvm::Function::iterator
4390 FI = CGF.
CurFn->begin(), FE = CGF.
CurFn->end(); FI != FE; ++FI) {
4391 llvm::BasicBlock &BB = *FI;
4392 if (BlocksBeforeTry.count(&BB))
continue;
4395 for (llvm::BasicBlock::iterator
4396 BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) {
4397 llvm::Instruction &I = *BI;
4401 if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I))
4403 if (isa<llvm::IntrinsicInst>(I))
4408 if (cast<llvm::CallBase>(I).doesNotThrow())
4416 Builder.SetInsertPoint(&BB, BI);
4417 emitReadHazard(Builder);
4424 if (llvm::Value *Ptr =
V.getBasePointer())
4428void FragileHazards::collectLocals() {
4430 llvm::DenseSet<llvm::Value*> AllocasToIgnore;
4436 llvm::BasicBlock &Entry = CGF.
CurFn->getEntryBlock();
4437 for (llvm::BasicBlock::iterator
4438 I = Entry.begin(),
E = Entry.end(); I !=
E; ++I)
4439 if (isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I))
4440 Locals.push_back(&*I);
4443llvm::FunctionType *FragileHazards::GetAsmFnType() {
4445 for (
unsigned i = 0, e = Locals.size(); i != e; ++i)
4446 tys[i] = Locals[i]->getType();
4447 return llvm::FunctionType::get(CGF.
VoidTy, tys,
false);
4560 bool isTry = isa<ObjCAtTryStmt>(S);
4564 CodeGenFunction::JumpDest FinallyEnd =
4569 CodeGenFunction::JumpDest FinallyRethrow =
4579 llvm::Value *SyncArg =
4580 CGF.
EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
4581 SyncArg = CGF.
Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
4593 "exceptiondata.ptr");
4599 FragileHazards Hazards(CGF);
4628 ExceptionData.emitRawPointer(CGF));
4631 llvm::Constant *
Zero = llvm::ConstantInt::get(CGF.
Builder.getInt32Ty(), 0);
4634 ObjCTypes.ExceptionDataTy, ExceptionData.emitRawPointer(CGF), GEPIndexes,
4637 ObjCTypes.getSetJmpFn(), SetJmpBuffer,
"setjmp_result");
4638 SetJmpResult->setCanReturnTwice();
4644 llvm::Value *DidCatch =
4645 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
4646 CGF.
Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
4651 CGF.
EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
4652 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
4654 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.
Builder.saveAndClearIP();
4660 Hazards.emitWriteHazard();
4664 if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
4674 ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF),
4685 llvm::BasicBlock *CatchBlock =
nullptr;
4686 llvm::BasicBlock *CatchHandler =
nullptr;
4692 "propagating_exception");
4698 ExceptionData.emitRawPointer(CGF));
4700 llvm::CallInst *SetJmpResult =
4702 SetJmpBuffer,
"setjmp.result");
4703 SetJmpResult->setCanReturnTwice();
4705 llvm::Value *Threw =
4706 CGF.
Builder.CreateIsNotNull(SetJmpResult,
"did_catch_exception");
4710 CGF.
Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
4720 bool AllMatched =
false;
4722 const VarDecl *CatchParam = CatchStmt->getCatchParamDecl();
4741 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
4748 EmitInitOfCatchParam(CGF, Caught, CatchParam);
4751 CGF.
EmitStmt(CatchStmt->getCatchBody());
4754 CatchVarCleanups.ForceCleanup();
4760 assert(OPT &&
"Unexpected non-object pointer type in @catch");
4765 assert(IDecl &&
"Catch parameter must have Objective-C type!");
4768 llvm::Value *
Class = EmitClassRef(CGF, IDecl);
4770 llvm::Value *matchArgs[] = {
Class, Caught };
4771 llvm::CallInst *Match =
4773 matchArgs,
"match");
4778 CGF.
Builder.CreateCondBr(CGF.
Builder.CreateIsNotNull(Match,
"matched"),
4779 MatchedBlock, NextCatchBlock);
4786 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
4793 CGF.
Builder.CreateBitCast(Caught,
4795 EmitInitOfCatchParam(CGF, Tmp, CatchParam);
4797 CGF.
EmitStmt(CatchStmt->getCatchBody());
4800 CatchVarCleanups.ForceCleanup();
4811 if (Caught->use_empty())
4812 Caught->eraseFromParent();
4828 assert(PropagatingExnVar.
isValid());
4830 ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF),
4841 Hazards.emitHazardsInNewBlocks();
4844 CGF.
Builder.restoreIP(TryFallthroughIP);
4848 CGF.
EmitBlock(FinallyEnd.getBlock(),
true);
4851 CGBuilderTy::InsertPoint SavedIP = CGF.
Builder.saveAndClearIP();
4852 CGF.
EmitBlock(FinallyRethrow.getBlock(),
true);
4855 llvm::Value *PropagatingExn;
4856 if (PropagatingExnVar.
isValid()) {
4862 ObjCTypes.getExceptionExtractFn(), ExceptionData.emitRawPointer(CGF));
4863 PropagatingExn = Caught;
4868 CGF.
Builder.CreateUnreachable();
4871 CGF.
Builder.restoreIP(SavedIP);
4876 bool ClearInsertionPoint) {
4877 llvm::Value *ExceptionAsObject;
4879 if (
const Expr *ThrowExpr = S.getThrowExpr()) {
4882 CGF.
Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
4885 "Unexpected rethrow outside @catch block.");
4889 CGF.
EmitRuntimeCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
4890 ->setDoesNotReturn();
4891 CGF.
Builder.CreateUnreachable();
4894 if (ClearInsertionPoint)
4895 CGF.
Builder.ClearInsertionPoint();
4904 llvm::Value *AddrWeakObjVal = CGF.
Builder.CreateBitCast(
4906 llvm::Value *read_weak =
4908 AddrWeakObjVal,
"weakread");
4909 read_weak = CGF.
Builder.CreateBitCast(read_weak, DestTy);
4917 llvm::Value *src,
Address dst) {
4918 llvm::Type * SrcTy = src->getType();
4919 if (!isa<llvm::PointerType>(SrcTy)) {
4921 assert(Size <= 8 && "does not support size > 8
");
4922 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
4923 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
4924 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4926 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4927 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
4928 ObjCTypes.PtrObjectPtrTy);
4929 llvm::Value *args[] = { src, dstVal };
4930 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(),
4931 args, "weakassign
");
4937void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
4938 llvm::Value *src, Address dst,
4940 llvm::Type * SrcTy = src->getType();
4941 if (!isa<llvm::PointerType>(SrcTy)) {
4942 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4943 assert(Size <= 8 && "does
not support size > 8
");
4944 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
4945 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
4946 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4948 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4949 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
4950 ObjCTypes.PtrObjectPtrTy);
4951 llvm::Value *args[] = {src, dstVal};
4953 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(),
4954 args, "globalassign
");
4956 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(),
4957 args, "threadlocalassign
");
4963void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
4964 llvm::Value *src, Address dst,
4965 llvm::Value *ivarOffset) {
4966 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is
NULL");
4967 llvm::Type * SrcTy = src->getType();
4968 if (!isa<llvm::PointerType>(SrcTy)) {
4969 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4970 assert(Size <= 8 && "does
not support size > 8
");
4971 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
4972 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
4973 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4975 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4976 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
4977 ObjCTypes.PtrObjectPtrTy);
4978 llvm::Value *args[] = {src, dstVal, ivarOffset};
4979 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
4985void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
4986 llvm::Value *src, Address dst) {
4987 llvm::Type * SrcTy = src->getType();
4988 if (!isa<llvm::PointerType>(SrcTy)) {
4989 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4990 assert(Size <= 8 && "does
not support size > 8
");
4991 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
4992 : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
4993 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4995 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4996 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
4997 ObjCTypes.PtrObjectPtrTy);
4998 llvm::Value *args[] = {src, dstVal};
4999 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(),
5000 args, "strongassign
");
5003void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
5004 Address DestPtr, Address SrcPtr,
5005 llvm::Value *size) {
5006 llvm::Value *args[] = {DestPtr.emitRawPointer(CGF),
5007 SrcPtr.emitRawPointer(CGF), size};
5008 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
5013LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
5015 llvm::Value *BaseValue,
5016 const ObjCIvarDecl *Ivar,
5017 unsigned CVRQualifiers) {
5018 const ObjCInterfaceDecl *ID =
5019 ObjectTy->castAs<ObjCObjectType>()->getInterface();
5020 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
5021 EmitIvarOffset(CGF, ID, Ivar));
5024llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
5025 const ObjCInterfaceDecl *Interface,
5026 const ObjCIvarDecl *Ivar) {
5027 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
5028 return llvm::ConstantInt::get(
5029 CGM.getTypes().ConvertType(CGM.getContext().LongTy),
5033/* *** Private Interface *** */
5035std::string CGObjCCommonMac::GetSectionName(StringRef Section,
5036 StringRef MachOAttributes) {
5037 switch (CGM.getTriple().getObjectFormat()) {
5038 case llvm::Triple::UnknownObjectFormat:
5039 llvm_unreachable("unexpected
object file format
");
5040 case llvm::Triple::MachO: {
5041 if (MachOAttributes.empty())
5042 return ("__DATA,
" + Section).str();
5043 return ("__DATA,
" + Section + ",
" + MachOAttributes).str();
5045 case llvm::Triple::ELF:
5046 assert(Section.starts_with("__
") && "expected the name to begin with __
");
5047 return Section.substr(2).str();
5048 case llvm::Triple::COFF:
5049 assert(Section.starts_with("__
") && "expected the name to begin with __
");
5050 return (".
" + Section.substr(2) + "$B
").str();
5051 case llvm::Triple::Wasm:
5052 case llvm::Triple::GOFF:
5053 case llvm::Triple::SPIRV:
5054 case llvm::Triple::XCOFF:
5055 case llvm::Triple::DXContainer:
5056 llvm::report_fatal_error(
5057 "Objective-
C support is unimplemented
for object file format
");
5060 llvm_unreachable("Unhandled llvm::Triple::ObjectFormatType
enum");
5071enum ImageInfoFlags {
5072 eImageInfo_FixAndContinue = (1 << 0), // This flag is no longer set by clang.
5073 eImageInfo_GarbageCollected = (1 << 1),
5074 eImageInfo_GCOnly = (1 << 2),
5075 eImageInfo_OptimizedByDyld = (1 << 3), // This flag is set by the dyld shared cache.
5077 // A flag indicating that the module has no instances of a @synthesize of a
5078 // superclass variable. This flag used to be consumed by the runtime to work
5079 // around miscompile by gcc.
5080 eImageInfo_CorrectedSynthesize = (1 << 4), // This flag is no longer set by clang.
5081 eImageInfo_ImageIsSimulated = (1 << 5),
5082 eImageInfo_ClassProperties = (1 << 6)
5085void CGObjCCommonMac::EmitImageInfo() {
5086 unsigned version = 0; // Version is unused?
5087 std::string Section =
5089 ? "__OBJC,__image_info,regular
"
5090 : GetSectionName("__objc_imageinfo
", "regular,no_dead_strip
");
5092 // Generate module-level named metadata to convey this information to the
5093 // linker and code-gen.
5094 llvm::Module &Mod = CGM.getModule();
5096 // Add the ObjC ABI version to the module flags.
5097 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Version
", ObjCABI);
5098 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Image Info Version
",
5100 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Image Info Section
",
5101 llvm::MDString::get(VMContext, Section));
5103 auto Int8Ty = llvm::Type::getInt8Ty(VMContext);
5104 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
5105 // Non-GC overrides those files which specify GC.
5106 Mod.addModuleFlag(llvm::Module::Error,
5107 "Objective-
C Garbage Collection
",
5108 llvm::ConstantInt::get(Int8Ty,0));
5110 // Add the ObjC garbage collection value.
5111 Mod.addModuleFlag(llvm::Module::Error,
5112 "Objective-
C Garbage Collection
",
5113 llvm::ConstantInt::get(Int8Ty,
5114 (uint8_t)eImageInfo_GarbageCollected));
5116 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
5117 // Add the ObjC GC Only value.
5118 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C GC Only
",
5121 // Require that GC be specified and set to eImageInfo_GarbageCollected.
5122 llvm::Metadata *Ops[2] = {
5123 llvm::MDString::get(VMContext, "Objective-
C Garbage Collection
"),
5124 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
5125 Int8Ty, eImageInfo_GarbageCollected))};
5126 Mod.addModuleFlag(llvm::Module::Require, "Objective-
C GC Only
",
5127 llvm::MDNode::get(VMContext, Ops));
5131 // Indicate whether we're compiling this to run on a simulator.
5132 if (CGM.getTarget().getTriple().isSimulatorEnvironment())
5133 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Is Simulated
",
5134 eImageInfo_ImageIsSimulated);
5136 // Indicate whether we are generating class properties.
5137 Mod.addModuleFlag(llvm::Module::Error, "Objective-
C Class Properties
",
5138 eImageInfo_ClassProperties);
5141// struct objc_module {
5142// unsigned long version;
5143// unsigned long size;
5148// FIXME: Get from somewhere
5149static const int ModuleVersion = 7;
5151void CGObjCMac::EmitModuleInfo() {
5152 uint64_t Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ModuleTy);
5154 ConstantInitBuilder builder(CGM);
5155 auto values = builder.beginStruct(ObjCTypes.ModuleTy);
5156 values.addInt(ObjCTypes.LongTy, ModuleVersion);
5157 values.addInt(ObjCTypes.LongTy, Size);
5158 // This used to be the filename, now it is unused. <rdr://4327263>
5159 values.add(GetClassName(StringRef("")));
5160 values.add(EmitModuleSymbols());
5161 CreateMetadataVar("OBJC_MODULES
", values,
5162 "__OBJC,__module_info,regular,no_dead_strip
",
5163 CGM.getPointerAlign(), true);
5166llvm::Constant *CGObjCMac::EmitModuleSymbols() {
5167 unsigned NumClasses = DefinedClasses.size();
5168 unsigned NumCategories = DefinedCategories.size();
5170 // Return null if no symbols were defined.
5171 if (!NumClasses && !NumCategories)
5172 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
5174 ConstantInitBuilder builder(CGM);
5175 auto values = builder.beginStruct();
5176 values.addInt(ObjCTypes.LongTy, 0);
5177 values.addNullPointer(ObjCTypes.SelectorPtrTy);
5178 values.addInt(ObjCTypes.ShortTy, NumClasses);
5179 values.addInt(ObjCTypes.ShortTy, NumCategories);
5181 // The runtime expects exactly the list of defined classes followed
5182 // by the list of defined categories, in a single array.
5183 auto array = values.beginArray(ObjCTypes.Int8PtrTy);
5184 for (unsigned i=0; i<NumClasses; i++) {
5185 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
5187 if (ObjCImplementationDecl *IMP = ID->getImplementation())
5188 // We are implementing a weak imported interface. Give it external linkage
5189 if (ID->isWeakImported() && !IMP->isWeakImported())
5190 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
5192 array.add(DefinedClasses[i]);
5194 for (unsigned i=0; i<NumCategories; i++)
5195 array.add(DefinedCategories[i]);
5197 array.finishAndAddTo(values);
5199 llvm::GlobalVariable *GV = CreateMetadataVar(
5200 "OBJC_SYMBOLS
", values, "__OBJC,__symbols,regular,no_dead_strip
",
5201 CGM.getPointerAlign(), true);
5205llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF,
5206 IdentifierInfo *II) {
5207 LazySymbols.insert(II);
5209 llvm::GlobalVariable *&Entry = ClassReferences[II];
5213 CreateMetadataVar("OBJC_CLASS_REFERENCES_
", GetClassName(II->getName()),
5214 "__OBJC,__cls_refs,literal_pointers,no_dead_strip
",
5215 CGM.getPointerAlign(), true);
5218 return CGF.Builder.CreateAlignedLoad(Entry->getValueType(), Entry,
5219 CGF.getPointerAlign());
5222llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF,
5223 const ObjCInterfaceDecl *ID) {
5224 // If the class has the objc_runtime_visible attribute, we need to
5225 // use the Objective-C runtime to get the class.
5226 if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
5227 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
5229 IdentifierInfo *RuntimeName =
5230 &CGM.getContext().Idents.get(ID->getObjCRuntimeNameAsString());
5231 return EmitClassRefFromId(CGF, RuntimeName);
5234llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
5235 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool
");
5236 return EmitClassRefFromId(CGF, II);
5239llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel) {
5240 return CGF.Builder.CreateLoad(EmitSelectorAddr(Sel));
5243ConstantAddress CGObjCMac::EmitSelectorAddr(Selector Sel) {
5244 CharUnits Align = CGM.getPointerAlign();
5246 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
5248 Entry = CreateMetadataVar(
5249 "OBJC_SELECTOR_REFERENCES_
", GetMethodVarName(Sel),
5250 "__OBJC,__message_refs,literal_pointers,no_dead_strip
", Align, true);
5251 Entry->setExternallyInitialized(true);
5254 return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align);
5257llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) {
5258 llvm::GlobalVariable *&Entry = ClassNames[RuntimeName];
5260 Entry = CreateCStringLiteral(RuntimeName, ObjCLabelType::ClassName);
5261 return getConstantGEP(VMContext, Entry, 0, 0);
5264llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
5265 return MethodDefinitions.lookup(MD);
5270llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
5271 const ObjCCommonTypesHelper &ObjCTypes) {
5272 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
5275void IvarLayoutBuilder::visitRecord(const RecordType *RT,
5277 const RecordDecl *RD = RT->getDecl();
5279 // If this is a union, remember that we had one, because it might mess
5280 // up the ordering of layout entries.
5282 IsDisordered = true;
5284 const ASTRecordLayout *recLayout = nullptr;
5285 visitAggregate(RD->field_begin(), RD->field_end(), offset,
5286 [&](const FieldDecl *field) -> CharUnits {
5288 recLayout = &CGM.getContext().getASTRecordLayout(RD);
5289 auto offsetInBits = recLayout->getFieldOffset(field->getFieldIndex());
5290 return CGM.getContext().toCharUnitsFromBits(offsetInBits);
5294template <class Iterator, class GetOffsetFn>
5295void IvarLayoutBuilder::visitAggregate(Iterator begin, Iterator end,
5296 CharUnits aggregateOffset,
5297 const GetOffsetFn &getOffset) {
5298 for (; begin != end; ++begin) {
5299 auto field = *begin;
5301 // Skip over bitfields.
5302 if (field->isBitField()) {
5306 // Compute the offset of the field within the aggregate.
5307 CharUnits fieldOffset = aggregateOffset + getOffset(field);
5309 visitField(field, fieldOffset);
5314void IvarLayoutBuilder::visitField(const FieldDecl *field,
5315 CharUnits fieldOffset) {
5316 QualType fieldType = field->getType();
5318 // Drill down into arrays.
5319 uint64_t numElts = 1;
5320 if (auto arrayType = CGM.getContext().getAsIncompleteArrayType(fieldType)) {
5322 fieldType = arrayType->getElementType();
5324 // Unlike incomplete arrays, constant arrays can be nested.
5325 while (auto arrayType = CGM.getContext().getAsConstantArrayType(fieldType)) {
5326 numElts *= arrayType->getZExtSize();
5327 fieldType = arrayType->getElementType();
5330 assert(!fieldType->isArrayType() && "ivar of non-constant array
type?
");
5332 // If we ended up with a zero-sized array, we've done what we can do within
5333 // the limits of this layout encoding.
5334 if (numElts == 0) return;
5336 // Recurse if the base element type is a record type.
5337 if (auto recType = fieldType->getAs<RecordType>()) {
5338 size_t oldEnd = IvarsInfo.size();
5340 visitRecord(recType, fieldOffset);
5342 // If we have an array, replicate the first entry's layout information.
5343 auto numEltEntries = IvarsInfo.size() - oldEnd;
5344 if (numElts != 1 && numEltEntries != 0) {
5345 CharUnits eltSize = CGM.getContext().getTypeSizeInChars(recType);
5346 for (uint64_t eltIndex = 1; eltIndex != numElts; ++eltIndex) {
5347 // Copy the last numEltEntries onto the end of the array, adjusting
5348 // each for the element size.
5349 for (size_t i = 0; i != numEltEntries; ++i) {
5350 auto firstEntry = IvarsInfo[oldEnd + i];
5351 IvarsInfo.push_back(IvarInfo(firstEntry.Offset + eltIndex * eltSize,
5352 firstEntry.SizeInWords));
5360 // Classify the element type.
5361 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), fieldType);
5363 // If it matches what we're looking for, add an entry.
5364 if ((ForStrongLayout && GCAttr == Qualifiers::Strong)
5365 || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
5366 assert(CGM.getContext().getTypeSizeInChars(fieldType)
5367 == CGM.getPointerSize());
5368 IvarsInfo.push_back(IvarInfo(fieldOffset, numElts));
5375llvm::Constant *IvarLayoutBuilder::buildBitmap(CGObjCCommonMac &CGObjC,
5376 llvm::SmallVectorImpl<unsigned char> &buffer) {
5377 // The bitmap is a series of skip/scan instructions, aligned to word
5378 // boundaries. The skip is performed first.
5379 const unsigned char MaxNibble = 0xF;
5380 const unsigned char SkipMask = 0xF0, SkipShift = 4;
5381 const unsigned char ScanMask = 0x0F, ScanShift = 0;
5383 assert(!IvarsInfo.empty() && "generating bitmap
for no data
");
5385 // Sort the ivar info on byte position in case we encounterred a
5386 // union nested in the ivar list.
5388 // This isn't a stable sort, but our algorithm should handle it fine.
5389 llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end());
5391 assert(llvm::is_sorted(IvarsInfo));
5393 assert(IvarsInfo.back().Offset < InstanceEnd);
5395 assert(buffer.empty());
5397 // Skip the next N words.
5398 auto skip = [&](unsigned numWords) {
5399 assert(numWords > 0);
5401 // Try to merge into the previous byte. Since scans happen second, we
5402 // can't do this if it includes a scan.
5403 if (!buffer.empty() && !(buffer.back() & ScanMask)) {
5404 unsigned lastSkip = buffer.back() >> SkipShift;
5405 if (lastSkip < MaxNibble) {
5406 unsigned claimed = std::min(MaxNibble - lastSkip, numWords);
5407 numWords -= claimed;
5408 lastSkip += claimed;
5409 buffer.back() = (lastSkip << SkipShift);
5413 while (numWords >= MaxNibble) {
5414 buffer.push_back(MaxNibble << SkipShift);
5415 numWords -= MaxNibble;
5418 buffer.push_back(numWords << SkipShift);
5422 // Scan the next N words.
5423 auto scan = [&](unsigned numWords) {
5424 assert(numWords > 0);
5426 // Try to merge into the previous byte. Since scans happen second, we can
5427 // do this even if it includes a skip.
5428 if (!buffer.empty()) {
5429 unsigned lastScan = (buffer.back() & ScanMask) >> ScanShift;
5430 if (lastScan < MaxNibble) {
5431 unsigned claimed = std::min(MaxNibble - lastScan, numWords);
5432 numWords -= claimed;
5433 lastScan += claimed;
5434 buffer.back() = (buffer.back() & SkipMask) | (lastScan << ScanShift);
5438 while (numWords >= MaxNibble) {
5439 buffer.push_back(MaxNibble << ScanShift);
5440 numWords -= MaxNibble;
5443 buffer.push_back(numWords << ScanShift);
5447 // One past the end of the last scan.
5448 unsigned endOfLastScanInWords = 0;
5449 const CharUnits WordSize = CGM.getPointerSize();
5451 // Consider all the scan requests.
5452 for (auto &request : IvarsInfo) {
5453 CharUnits beginOfScan = request.Offset - InstanceBegin;
5455 // Ignore scan requests that don't start at an even multiple of the
5456 // word size. We can't encode them.
5457 if ((beginOfScan % WordSize) != 0) continue;
5459 // Ignore scan requests that start before the instance start.
5460 // This assumes that scans never span that boundary. The boundary
5461 // isn't the true start of the ivars, because in the fragile-ARC case
5462 // it's rounded up to word alignment, but the test above should leave
5463 // us ignoring that possibility.
5464 if (beginOfScan.isNegative()) {
5465 assert(request.Offset + request.SizeInWords * WordSize <= InstanceBegin);
5469 unsigned beginOfScanInWords = beginOfScan / WordSize;
5470 unsigned endOfScanInWords = beginOfScanInWords + request.SizeInWords;
5472 // If the scan starts some number of words after the last one ended,
5474 if (beginOfScanInWords > endOfLastScanInWords) {
5475 skip(beginOfScanInWords - endOfLastScanInWords);
5477 // Otherwise, start scanning where the last left off.
5479 beginOfScanInWords = endOfLastScanInWords;
5481 // If that leaves us with nothing to scan, ignore this request.
5482 if (beginOfScanInWords >= endOfScanInWords) continue;
5485 // Scan to the end of the request.
5486 assert(beginOfScanInWords < endOfScanInWords);
5487 scan(endOfScanInWords - beginOfScanInWords);
5488 endOfLastScanInWords = endOfScanInWords;
5492 return llvm::ConstantPointerNull::get(CGM.Int8PtrTy);
5494 // For GC layouts, emit a skip to the end of the allocation so that we
5495 // have precise information about the entire thing. This isn't useful
5496 // or necessary for the ARC-style layout strings.
5497 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
5498 unsigned lastOffsetInWords =
5499 (InstanceEnd - InstanceBegin + WordSize - CharUnits::One()) / WordSize;
5500 if (lastOffsetInWords > endOfLastScanInWords) {
5501 skip(lastOffsetInWords - endOfLastScanInWords);
5505 // Null terminate the string.
5506 buffer.push_back(0);
5508 auto *Entry = CGObjC.CreateCStringLiteral(
5509 reinterpret_cast<char *>(buffer.data()), ObjCLabelType::ClassName);
5510 return getConstantGEP(CGM.getLLVMContext(), Entry, 0, 0);
5530CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD,
5531 CharUnits beginOffset, CharUnits endOffset,
5532 bool ForStrongLayout, bool HasMRCWeakIvars) {
5533 // If this is MRC, and we're either building a strong layout or there
5534 // are no weak ivars, bail out early.
5535 llvm::Type *PtrTy = CGM.Int8PtrTy;
5536 if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
5537 !CGM.getLangOpts().ObjCAutoRefCount &&
5538 (ForStrongLayout || !HasMRCWeakIvars))
5539 return llvm::Constant::getNullValue(PtrTy);
5541 const ObjCInterfaceDecl *OI = OMD->getClassInterface();
5542 SmallVector<const ObjCIvarDecl*, 32> ivars;
5544 // GC layout strings include the complete object layout, possibly
5545 // inaccurately in the non-fragile ABI; the runtime knows how to fix this
5548 // ARC layout strings only include the class's ivars. In non-fragile
5549 // runtimes, that means starting at InstanceStart, rounded up to word
5550 // alignment. In fragile runtimes, there's no InstanceStart, so it means
5551 // starting at the offset of the first ivar, rounded up to word alignment.
5553 // MRC weak layout strings follow the ARC style.
5554 CharUnits baseOffset;
5555 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
5556 for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();
5557 IVD; IVD = IVD->getNextIvar())
5558 ivars.push_back(IVD);
5560 if (isNonFragileABI()) {
5561 baseOffset = beginOffset; // InstanceStart
5562 } else if (!ivars.empty()) {
5564 CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivars[0]));
5566 baseOffset = CharUnits::Zero();
5569 baseOffset = baseOffset.alignTo(CGM.getPointerAlign());
5572 CGM.getContext().DeepCollectObjCIvars(OI, true, ivars);
5574 baseOffset = CharUnits::Zero();
5578 return llvm::Constant::getNullValue(PtrTy);
5580 IvarLayoutBuilder builder(CGM, baseOffset, endOffset, ForStrongLayout);
5582 builder.visitAggregate(ivars.begin(), ivars.end(), CharUnits::Zero(),
5583 [&](const ObjCIvarDecl *ivar) -> CharUnits {
5584 return CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivar));
5587 if (!builder.hasBitmapData())
5588 return llvm::Constant::getNullValue(PtrTy);
5590 llvm::SmallVector<unsigned char, 4> buffer;
5591 llvm::Constant *C = builder.buildBitmap(*this, buffer);
5593 if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
5594 printf("\n%
s ivar layout
for class '%s':
",
5595 ForStrongLayout ? "strong
" : "weak
",
5596 OMD->getClassInterface()->getName().str().c_str());
5597 builder.dump(buffer);
5602llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
5603 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
5604 // FIXME: Avoid std::string in "Sel.
getAsString()
"
5606 Entry = CreateCStringLiteral(Sel.getAsString(), ObjCLabelType::MethodVarName);
5607 return getConstantGEP(VMContext, Entry, 0, 0);
5610// FIXME: Merge into a single cstring creation function.
5611llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
5612 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
5615llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
5616 std::string TypeStr;
5617 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
5619 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
5621 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType);
5622 return getConstantGEP(VMContext, Entry, 0, 0);
5625llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D,
5627 std::string TypeStr =
5628 CGM.getContext().getObjCEncodingForMethodDecl(D, Extended);
5630 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
5632 Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType);
5633 return getConstantGEP(VMContext, Entry, 0, 0);
5636// FIXME: Merge into a single cstring creation function.
5637llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
5638 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
5640 Entry = CreateCStringLiteral(Ident->getName(), ObjCLabelType::PropertyName);
5641 return getConstantGEP(VMContext, Entry, 0, 0);
5644// FIXME: Merge into a single cstring creation function.
5645// FIXME: This Decl should be more precise.
5647CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
5648 const Decl *Container) {
5649 std::string TypeStr =
5650 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container);
5651 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
5654void CGObjCMac::FinishModule() {
5657 // Emit the dummy bodies for any protocols which were referenced but
5659 for (auto &entry : Protocols) {
5660 llvm::GlobalVariable *global = entry.second;
5661 if (global->hasInitializer())
5664 ConstantInitBuilder builder(CGM);
5665 auto values = builder.beginStruct(ObjCTypes.ProtocolTy);
5666 values.addNullPointer(ObjCTypes.ProtocolExtensionPtrTy);
5667 values.add(GetClassName(entry.first->getName()));
5668 values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
5669 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy);
5670 values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy);
5671 values.finishAndSetAsInitializer(global);
5672 CGM.addCompilerUsedGlobal(global);
5675 // Add assembler directives to add lazy undefined symbol references
5676 // for classes which are referenced but not defined. This is
5677 // important for correct linker interaction.
5679 // FIXME: It would be nice if we had an LLVM construct for this.
5680 if ((!LazySymbols.empty() || !DefinedSymbols.empty()) &&
5681 CGM.getTriple().isOSBinFormatMachO()) {
5682 SmallString<256> Asm;
5683 Asm += CGM.getModule().getModuleInlineAsm();
5684 if (!Asm.empty() && Asm.back() != '\n')
5687 llvm::raw_svector_ostream OS(Asm);
5688 for (const auto *Sym : DefinedSymbols)
5689 OS << "\t.objc_class_name_
" << Sym->getName() << "=0\n
"
5690 << "\t.globl .objc_class_name_
" << Sym->getName() << "\n
";
5691 for (const auto *Sym : LazySymbols)
5692 OS << "\t.lazy_reference .objc_class_name_
" << Sym->getName() << "\n
";
5693 for (const auto &Category : DefinedCategoryNames)
5694 OS << "\t.objc_category_name_
" << Category << "=0\n
"
5695 << "\t.globl .objc_category_name_
" << Category << "\n
";
5697 CGM.getModule().setModuleInlineAsm(OS.str());
5701CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
5702 : CGObjCCommonMac(cgm), ObjCTypes(cgm), ObjCEmptyCacheVar(nullptr),
5703 ObjCEmptyVtableVar(nullptr) {
5709ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
5710 : VMContext(cgm.getLLVMContext()), CGM(cgm), ExternalProtocolPtrTy(nullptr)
5712 CodeGen::CodeGenTypes &Types = CGM.getTypes();
5713 ASTContext &Ctx = CGM.getContext();
5714 unsigned ProgramAS = CGM.getDataLayout().getProgramAddressSpace();
5716 ShortTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.ShortTy));
5718 LongTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.LongTy));
5719 Int8PtrTy = CGM.Int8PtrTy;
5720 Int8PtrProgramASTy = llvm::PointerType::get(CGM.Int8Ty, ProgramAS);
5721 Int8PtrPtrTy = CGM.Int8PtrPtrTy;
5723 // arm64 targets use "int" ivar offset variables. All others,
5724 // including OS X x86_64 and Windows x86_64, use "long" ivar offsets.
5725 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::aarch64)
5726 IvarOffsetVarTy = IntTy;
5728 IvarOffsetVarTy = LongTy;
5731 cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCIdType()));
5733 llvm::PointerType::getUnqual(ObjectPtrTy);
5735 cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCSelType()));
5737 // I'm not sure I like this. The implicit coordination is a bit
5738 // gross. We should solve this in a reasonable fashion because this
5739 // is a pretty common task (match some runtime data structure with
5740 // an LLVM data structure).
5742 // FIXME: This is leaked.
5743 // FIXME: Merge with rewriter code?
5745 // struct _objc_super {
5749 RecordDecl *RD = RecordDecl::Create(
5750 Ctx, TagTypeKind::Struct, Ctx.getTranslationUnitDecl(), SourceLocation(),
5751 SourceLocation(), &Ctx.Idents.get("_objc_super
"));
5752 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5753 nullptr, Ctx.getObjCIdType(), nullptr, nullptr,
5754 false, ICIS_NoInit));
5755 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5756 nullptr, Ctx.getObjCClassType(), nullptr,
5757 nullptr, false, ICIS_NoInit));
5758 RD->completeDefinition();
5760 SuperCTy = Ctx.getTagDeclType(RD);
5761 SuperPtrCTy = Ctx.getPointerType(SuperCTy);
5763 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
5764 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
5768 // char *attributes;
5770 PropertyTy = llvm::StructType::create("struct._prop_t
", Int8PtrTy, Int8PtrTy);
5772 // struct _prop_list_t {
5773 // uint32_t entsize; // sizeof(struct _prop_t)
5774 // uint32_t count_of_properties;
5775 // struct _prop_t prop_list[count_of_properties];
5777 PropertyListTy = llvm::StructType::create(
5778 "struct._prop_list_t
", IntTy, IntTy, llvm::ArrayType::get(PropertyTy, 0));
5779 // struct _prop_list_t *
5780 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
5782 // struct _objc_method {
5784 // char *method_type;
5787 MethodTy = llvm::StructType::create("struct._objc_method
", SelectorPtrTy,
5788 Int8PtrTy, Int8PtrProgramASTy);
5790 // struct _objc_cache *
5791 CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache
");
5792 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
5795ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
5796 : ObjCCommonTypesHelper(cgm) {
5797 // struct _objc_method_description {
5801 MethodDescriptionTy = llvm::StructType::create(
5802 "struct._objc_method_description
", SelectorPtrTy, Int8PtrTy);
5804 // struct _objc_method_description_list {
5806 // struct _objc_method_description[1];
5808 MethodDescriptionListTy =
5809 llvm::StructType::create("struct._objc_method_description_list
", IntTy,
5810 llvm::ArrayType::get(MethodDescriptionTy, 0));
5812 // struct _objc_method_description_list *
5813 MethodDescriptionListPtrTy =
5814 llvm::PointerType::getUnqual(MethodDescriptionListTy);
5816 // Protocol description structures
5818 // struct _objc_protocol_extension {
5819 // uint32_t size; // sizeof(struct _objc_protocol_extension)
5820 // struct _objc_method_description_list *optional_instance_methods;
5821 // struct _objc_method_description_list *optional_class_methods;
5822 // struct _objc_property_list *instance_properties;
5823 // const char ** extendedMethodTypes;
5824 // struct _objc_property_list *class_properties;
5826 ProtocolExtensionTy = llvm::StructType::create(
5827 "struct._objc_protocol_extension
", IntTy, MethodDescriptionListPtrTy,
5828 MethodDescriptionListPtrTy, PropertyListPtrTy, Int8PtrPtrTy,
5831 // struct _objc_protocol_extension *
5832 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
5834 // Handle construction of Protocol and ProtocolList types
5836 // struct _objc_protocol {
5837 // struct _objc_protocol_extension *isa;
5838 // char *protocol_name;
5839 // struct _objc_protocol **_objc_protocol_list;
5840 // struct _objc_method_description_list *instance_methods;
5841 // struct _objc_method_description_list *class_methods;
5843 ProtocolTy = llvm::StructType::create(
5844 {ProtocolExtensionPtrTy, Int8PtrTy,
5845 llvm::PointerType::getUnqual(VMContext), MethodDescriptionListPtrTy,
5846 MethodDescriptionListPtrTy},
5847 "struct._objc_protocol
");
5850 llvm::StructType::create({llvm::PointerType::getUnqual(VMContext), LongTy,
5851 llvm::ArrayType::get(ProtocolTy, 0)},
5852 "struct._objc_protocol_list
");
5854 // struct _objc_protocol_list *
5855 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
5857 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
5859 // Class description structures
5861 // struct _objc_ivar {
5866 IvarTy = llvm::StructType::create("struct._objc_ivar
", Int8PtrTy, Int8PtrTy,
5869 // struct _objc_ivar_list *
5871 llvm::StructType::create(VMContext, "struct._objc_ivar_list
");
5872 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
5874 // struct _objc_method_list *
5876 llvm::StructType::create(VMContext, "struct._objc_method_list
");
5877 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
5879 // struct _objc_class_extension *
5880 ClassExtensionTy = llvm::StructType::create(
5881 "struct._objc_class_extension
", IntTy, Int8PtrTy, PropertyListPtrTy);
5882 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
5884 // struct _objc_class {
5886 // Class super_class;
5890 // long instance_size;
5891 // struct _objc_ivar_list *ivars;
5892 // struct _objc_method_list *methods;
5893 // struct _objc_cache *cache;
5894 // struct _objc_protocol_list *protocols;
5895 // char *ivar_layout;
5896 // struct _objc_class_ext *ext;
5898 ClassTy = llvm::StructType::create(
5899 {llvm::PointerType::getUnqual(VMContext),
5900 llvm::PointerType::getUnqual(VMContext), Int8PtrTy, LongTy, LongTy,
5901 LongTy, IvarListPtrTy, MethodListPtrTy, CachePtrTy, ProtocolListPtrTy,
5902 Int8PtrTy, ClassExtensionPtrTy},
5903 "struct._objc_class
");
5905 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
5907 // struct _objc_category {
5908 // char *category_name;
5909 // char *class_name;
5910 // struct _objc_method_list *instance_method;
5911 // struct _objc_method_list *class_method;
5912 // struct _objc_protocol_list *protocols;
5913 // uint32_t size; // sizeof(struct _objc_category)
5914 // struct _objc_property_list *instance_properties;// category's @property
5915 // struct _objc_property_list *class_properties;
5917 CategoryTy = llvm::StructType::create(
5918 "struct._objc_category
", Int8PtrTy, Int8PtrTy, MethodListPtrTy,
5919 MethodListPtrTy, ProtocolListPtrTy, IntTy, PropertyListPtrTy,
5922 // Global metadata structures
5924 // struct _objc_symtab {
5925 // long sel_ref_cnt;
5927 // short cls_def_cnt;
5928 // short cat_def_cnt;
5929 // char *defs[cls_def_cnt + cat_def_cnt];
5931 SymtabTy = llvm::StructType::create("struct._objc_symtab
", LongTy,
5932 SelectorPtrTy, ShortTy, ShortTy,
5933 llvm::ArrayType::get(Int8PtrTy, 0));
5934 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
5936 // struct _objc_module {
5938 // long size; // sizeof(struct _objc_module)
5940 // struct _objc_symtab* symtab;
5942 ModuleTy = llvm::StructType::create("struct._objc_module
", LongTy, LongTy,
5943 Int8PtrTy, SymtabPtrTy);
5945 // FIXME: This is the size of the setjmp buffer and should be target
5946 // specific. 18 is what's used on 32-bit X86.
5947 uint64_t SetJmpBufferSize = 18;
5950 llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4);
5952 ExceptionDataTy = llvm::StructType::create(
5953 "struct._objc_exception_data
",
5954 llvm::ArrayType::get(CGM.Int32Ty, SetJmpBufferSize), StackPtrTy);
5957ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm)
5958 : ObjCCommonTypesHelper(cgm) {
5959 // struct _method_list_t {
5960 // uint32_t entsize; // sizeof(struct _objc_method)
5961 // uint32_t method_count;
5962 // struct _objc_method method_list[method_count];
5965 llvm::StructType::create("struct.__method_list_t
", IntTy, IntTy,
5966 llvm::ArrayType::get(MethodTy, 0));
5967 // struct method_list_t *
5968 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy);
5970 // struct _protocol_t {
5972 // const char * const protocol_name;
5973 // const struct _protocol_list_t * protocol_list; // super protocols
5974 // const struct method_list_t * const instance_methods;
5975 // const struct method_list_t * const class_methods;
5976 // const struct method_list_t *optionalInstanceMethods;
5977 // const struct method_list_t *optionalClassMethods;
5978 // const struct _prop_list_t * properties;
5979 // const uint32_t size; // sizeof(struct _protocol_t)
5980 // const uint32_t flags; // = 0
5981 // const char ** extendedMethodTypes;
5982 // const char *demangledName;
5983 // const struct _prop_list_t * class_properties;
5986 ProtocolnfABITy = llvm::StructType::create(
5987 "struct._protocol_t
", ObjectPtrTy, Int8PtrTy,
5988 llvm::PointerType::getUnqual(VMContext), MethodListnfABIPtrTy,
5989 MethodListnfABIPtrTy, MethodListnfABIPtrTy, MethodListnfABIPtrTy,
5990 PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy, Int8PtrTy,
5993 // struct _protocol_t*
5994 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy);
5996 // struct _protocol_list_t {
5997 // long protocol_count; // Note, this is 32/64 bit
5998 // struct _protocol_t *[protocol_count];
6000 ProtocolListnfABITy = llvm::StructType::create(
6001 {LongTy, llvm::ArrayType::get(ProtocolnfABIPtrTy, 0)},
6002 "struct._objc_protocol_list
");
6004 // struct _objc_protocol_list*
6005 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy);
6008 // unsigned [long] int *offset; // pointer to ivar offset location
6011 // uint32_t alignment;
6014 IvarnfABITy = llvm::StructType::create(
6015 "struct._ivar_t
", llvm::PointerType::getUnqual(IvarOffsetVarTy),
6016 Int8PtrTy, Int8PtrTy, IntTy, IntTy);
6018 // struct _ivar_list_t {
6019 // uint32 entsize; // sizeof(struct _ivar_t)
6021 // struct _iver_t list[count];
6024 llvm::StructType::create("struct._ivar_list_t
", IntTy, IntTy,
6025 llvm::ArrayType::get(IvarnfABITy, 0));
6027 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy);
6029 // struct _class_ro_t {
6030 // uint32_t const flags;
6031 // uint32_t const instanceStart;
6032 // uint32_t const instanceSize;
6033 // uint32_t const reserved; // only when building for 64bit targets
6034 // const uint8_t * const ivarLayout;
6035 // const char *const name;
6036 // const struct _method_list_t * const baseMethods;
6037 // const struct _objc_protocol_list *const baseProtocols;
6038 // const struct _ivar_list_t *const ivars;
6039 // const uint8_t * const weakIvarLayout;
6040 // const struct _prop_list_t * const properties;
6043 // FIXME. Add 'reserved' field in 64bit abi mode!
6044 ClassRonfABITy = llvm::StructType::create(
6045 "struct._class_ro_t
", IntTy, IntTy, IntTy, Int8PtrTy, Int8PtrTy,
6046 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, IvarListnfABIPtrTy,
6047 Int8PtrTy, PropertyListPtrTy);
6049 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
6050 ImpnfABITy = CGM.UnqualPtrTy;
6052 // struct _class_t {
6053 // struct _class_t *isa;
6054 // struct _class_t * const superclass;
6057 // struct class_ro_t *ro;
6060 ClassnfABITy = llvm::StructType::create(
6061 {llvm::PointerType::getUnqual(VMContext),
6062 llvm::PointerType::getUnqual(VMContext), CachePtrTy,
6063 llvm::PointerType::getUnqual(ImpnfABITy),
6064 llvm::PointerType::getUnqual(ClassRonfABITy)},
6067 // LLVM for struct _class_t *
6068 ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy);
6070 // struct _category_t {
6071 // const char * const name;
6072 // struct _class_t *const cls;
6073 // const struct _method_list_t * const instance_methods;
6074 // const struct _method_list_t * const class_methods;
6075 // const struct _protocol_list_t * const protocols;
6076 // const struct _prop_list_t * const properties;
6077 // const struct _prop_list_t * const class_properties;
6078 // const uint32_t size;
6080 CategorynfABITy = llvm::StructType::create(
6081 "struct._category_t
", Int8PtrTy, ClassnfABIPtrTy, MethodListnfABIPtrTy,
6082 MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, PropertyListPtrTy,
6083 PropertyListPtrTy, IntTy);
6085 // New types for nonfragile abi messaging.
6086 CodeGen::CodeGenTypes &Types = CGM.getTypes();
6087 ASTContext &Ctx = CGM.getContext();
6089 // MessageRefTy - LLVM for:
6090 // struct _message_ref_t {
6095 // First the clang type for struct _message_ref_t
6096 RecordDecl *RD = RecordDecl::Create(
6097 Ctx, TagTypeKind::Struct, Ctx.getTranslationUnitDecl(), SourceLocation(),
6098 SourceLocation(), &Ctx.Idents.get("_message_ref_t
"));
6099 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
6100 nullptr, Ctx.VoidPtrTy, nullptr, nullptr, false,
6102 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
6103 nullptr, Ctx.getObjCSelType(), nullptr, nullptr,
6104 false, ICIS_NoInit));
6105 RD->completeDefinition();
6107 MessageRefCTy = Ctx.getTagDeclType(RD);
6108 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy);
6109 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy));
6111 // MessageRefPtrTy - LLVM for struct _message_ref_t*
6112 MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy);
6114 // SuperMessageRefTy - LLVM for:
6115 // struct _super_message_ref_t {
6116 // SUPER_IMP messenger;
6119 SuperMessageRefTy = llvm::StructType::create("struct._super_message_ref_t
",
6120 ImpnfABITy, SelectorPtrTy);
6122 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
6123 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy);
6126 // struct objc_typeinfo {
6127 // const void** vtable; // objc_ehtype_vtable + 2
6128 // const char* name; // c++ typeinfo string
6131 EHTypeTy = llvm::StructType::create("struct._objc_typeinfo
",
6132 llvm::PointerType::getUnqual(Int8PtrTy),
6133 Int8PtrTy, ClassnfABIPtrTy);
6134 EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy);
6137llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
6138 FinishNonFragileABIModule();
6143void CGObjCNonFragileABIMac::AddModuleClassList(
6144 ArrayRef<llvm::GlobalValue *> Container, StringRef SymbolName,
6145 StringRef SectionName) {
6146 unsigned NumClasses = Container.size();
6151 SmallVector<llvm::Constant*, 8> Symbols(NumClasses);
6152 for (unsigned i=0; i<NumClasses; i++)
6153 Symbols[i] = Container[i];
6155 llvm::Constant *Init =
6156 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
6160 // Section name is obtained by calling GetSectionName, which returns
6161 // sections in the __DATA segment on MachO.
6162 assert((!CGM.getTriple().isOSBinFormatMachO() ||
6163 SectionName.starts_with("__DATA
")) &&
6164 "SectionName expected to start with __DATA on MachO
");
6165 llvm::GlobalVariable *GV = new llvm::GlobalVariable(
6166 CGM.getModule(), Init->getType(), false,
6167 llvm::GlobalValue::PrivateLinkage, Init, SymbolName);
6168 GV->setAlignment(CGM.getDataLayout().getABITypeAlign(Init->getType()));
6169 GV->setSection(SectionName);
6170 CGM.addCompilerUsedGlobal(GV);
6173void CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
6174 // nonfragile abi has no module definition.
6176 // Build list of all implemented class addresses in array
6177 // L_OBJC_LABEL_CLASS_$.
6179 for (unsigned i=0, NumClasses=ImplementedClasses.size(); i<NumClasses; i++) {
6180 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
6182 if (ObjCImplementationDecl *IMP = ID->getImplementation())
6183 // We are implementing a weak imported interface. Give it external linkage
6184 if (ID->isWeakImported() && !IMP->isWeakImported()) {
6185 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
6186 DefinedMetaClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
6190 AddModuleClassList(DefinedClasses, "OBJC_LABEL_CLASS_$
",
6191 GetSectionName("__objc_classlist
",
6192 "regular,no_dead_strip
"));
6194 AddModuleClassList(DefinedNonLazyClasses, "OBJC_LABEL_NONLAZY_CLASS_$
",
6195 GetSectionName("__objc_nlclslist
",
6196 "regular,no_dead_strip
"));
6198 // Build list of all implemented category addresses in array
6199 // L_OBJC_LABEL_CATEGORY_$.
6200 AddModuleClassList(DefinedCategories, "OBJC_LABEL_CATEGORY_$
",
6201 GetSectionName("__objc_catlist
",
6202 "regular,no_dead_strip
"));
6203 AddModuleClassList(DefinedStubCategories, "OBJC_LABEL_STUB_CATEGORY_$
",
6204 GetSectionName("__objc_catlist2
",
6205 "regular,no_dead_strip
"));
6206 AddModuleClassList(DefinedNonLazyCategories, "OBJC_LABEL_NONLAZY_CATEGORY_$
",
6207 GetSectionName("__objc_nlcatlist
",
6208 "regular,no_dead_strip
"));
6217bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
6218 // At various points we've experimented with using vtable-based
6219 // dispatch for all methods.
6220 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
6221 case CodeGenOptions::Legacy:
6223 case CodeGenOptions::NonLegacy:
6225 case CodeGenOptions::Mixed:
6229 // If so, see whether this selector is in the white-list of things which must
6230 // use the new dispatch convention. We lazily build a dense set for this.
6231 if (VTableDispatchMethods.empty()) {
6232 VTableDispatchMethods.insert(GetNullarySelector("alloc
"));
6233 VTableDispatchMethods.insert(GetNullarySelector("class"));
6234 VTableDispatchMethods.insert(GetNullarySelector("self
"));
6235 VTableDispatchMethods.insert(GetNullarySelector("isFlipped
"));
6236 VTableDispatchMethods.insert(GetNullarySelector("length"));
6237 VTableDispatchMethods.insert(GetNullarySelector("count
"));
6239 // These are vtable-based if GC is disabled.
6240 // Optimistically use vtable dispatch for hybrid compiles.
6241 if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) {
6242 VTableDispatchMethods.insert(GetNullarySelector("retain
"));
6243 VTableDispatchMethods.insert(GetNullarySelector("release
"));
6244 VTableDispatchMethods.insert(GetNullarySelector("autorelease
"));
6247 VTableDispatchMethods.insert(GetUnarySelector("allocWithZone
"));
6248 VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass
"));
6249 VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector
"));
6250 VTableDispatchMethods.insert(GetUnarySelector("objectForKey
"));
6251 VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex
"));
6252 VTableDispatchMethods.insert(GetUnarySelector("isEqualToString
"));
6253 VTableDispatchMethods.insert(GetUnarySelector("isEqual
"));
6255 // These are vtable-based if GC is enabled.
6256 // Optimistically use vtable dispatch for hybrid compiles.
6257 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
6258 VTableDispatchMethods.insert(GetNullarySelector("hash
"));
6259 VTableDispatchMethods.insert(GetUnarySelector("addObject
"));
6261 // "countByEnumeratingWithState:objects:count
"
6262 const IdentifierInfo *KeyIdents[] = {
6263 &CGM.getContext().Idents.get("countByEnumeratingWithState
"),
6264 &CGM.getContext().Idents.get("objects
"),
6265 &CGM.getContext().Idents.get("count
")};
6266 VTableDispatchMethods.insert(
6267 CGM.getContext().Selectors.getSelector(3, KeyIdents));
6271 return VTableDispatchMethods.count(Sel);
6289llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
6291 unsigned InstanceStart,
6292 unsigned InstanceSize,
6293 const ObjCImplementationDecl *ID) {
6294 std::string ClassName = std::string(ID->getObjCRuntimeNameAsString());
6296 CharUnits beginInstance = CharUnits::fromQuantity(InstanceStart);
6297 CharUnits endInstance = CharUnits::fromQuantity(InstanceSize);
6299 bool hasMRCWeak = false;
6300 if (CGM.getLangOpts().ObjCAutoRefCount)
6301 flags |= NonFragileABI_Class_CompiledByARC;
6302 else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))
6303 flags |= NonFragileABI_Class_HasMRCWeakIvars;
6305 ConstantInitBuilder builder(CGM);
6306 auto values = builder.beginStruct(ObjCTypes.ClassRonfABITy);
6308 values.addInt(ObjCTypes.IntTy, flags);
6309 values.addInt(ObjCTypes.IntTy, InstanceStart);
6310 values.addInt(ObjCTypes.IntTy, InstanceSize);
6311 values.add((flags & NonFragileABI_Class_Meta)
6312 ? GetIvarLayoutName(nullptr, ObjCTypes)
6313 : BuildStrongIvarLayout(ID, beginInstance, endInstance));
6314 values.add(GetClassName(ID->getObjCRuntimeNameAsString()));
6316 // const struct _method_list_t * const baseMethods;
6317 SmallVector<const ObjCMethodDecl*, 16> methods;
6318 if (flags & NonFragileABI_Class_Meta) {
6319 for (const auto *MD : ID->class_methods())
6320 if (!MD->isDirectMethod())
6321 methods.push_back(MD);
6323 for (const auto *MD : ID->instance_methods())
6324 if (!MD->isDirectMethod())
6325 methods.push_back(MD);
6328 values.add(emitMethodList(ID->getObjCRuntimeNameAsString(),
6329 (flags & NonFragileABI_Class_Meta)
6330 ? MethodListType::ClassMethods
6331 : MethodListType::InstanceMethods,
6334 const ObjCInterfaceDecl *OID = ID->getClassInterface();
6335 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer
");
6336 values.add(EmitProtocolList("_OBJC_CLASS_PROTOCOLS_$_
"
6337 + OID->getObjCRuntimeNameAsString(),
6338 OID->all_referenced_protocol_begin(),
6339 OID->all_referenced_protocol_end()));
6341 if (flags & NonFragileABI_Class_Meta) {
6342 values.addNullPointer(ObjCTypes.IvarListnfABIPtrTy);
6343 values.add(GetIvarLayoutName(nullptr, ObjCTypes));
6344 values.add(EmitPropertyList(
6345 "_OBJC_$_CLASS_PROP_LIST_
" + ID->getObjCRuntimeNameAsString(),
6346 ID, ID->getClassInterface(), ObjCTypes, true));
6348 values.add(EmitIvarList(ID));
6349 values.add(BuildWeakIvarLayout(ID, beginInstance, endInstance, hasMRCWeak));
6350 values.add(EmitPropertyList(
6351 "_OBJC_$_PROP_LIST_
" + ID->getObjCRuntimeNameAsString(),
6352 ID, ID->getClassInterface(), ObjCTypes, false));
6355 llvm::SmallString<64> roLabel;
6356 llvm::raw_svector_ostream(roLabel)
6357 << ((flags & NonFragileABI_Class_Meta) ? "_OBJC_METACLASS_RO_$_
"
6358 : "_OBJC_CLASS_RO_$_
")
6361 return finishAndCreateGlobal(values, roLabel, CGM);
6374llvm::GlobalVariable *
6375CGObjCNonFragileABIMac::BuildClassObject(const ObjCInterfaceDecl *CI,
6377 llvm::Constant *IsAGV,
6378 llvm::Constant *SuperClassGV,
6379 llvm::Constant *ClassRoGV,
6380 bool HiddenVisibility) {
6381 ConstantInitBuilder builder(CGM);
6382 auto values = builder.beginStruct(ObjCTypes.ClassnfABITy);
6385 values.add(SuperClassGV);
6387 values.addNullPointer(ObjCTypes.ClassnfABIPtrTy);
6389 values.add(ObjCEmptyCacheVar);
6390 values.add(ObjCEmptyVtableVar);
6391 values.add(ClassRoGV);
6393 llvm::GlobalVariable *GV =
6394 cast<llvm::GlobalVariable>(GetClassGlobal(CI, isMetaclass, ForDefinition));
6395 values.finishAndSetAsInitializer(GV);
6397 if (CGM.getTriple().isOSBinFormatMachO())
6398 GV->setSection("__DATA, __objc_data
");
6399 GV->setAlignment(CGM.getDataLayout().getABITypeAlign(ObjCTypes.ClassnfABITy));
6400 if (!CGM.getTriple().isOSBinFormatCOFF())
6401 if (HiddenVisibility)
6402 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
6406bool CGObjCNonFragileABIMac::ImplementationIsNonLazy(
6407 const ObjCImplDecl *OD) const {
6408 return OD->getClassMethod(GetNullarySelector("load
")) != nullptr ||
6409 OD->getClassInterface()->hasAttr<ObjCNonLazyClassAttr>() ||
6410 OD->hasAttr<ObjCNonLazyClassAttr>();
6413void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
6414 uint32_t &InstanceStart,
6415 uint32_t &InstanceSize) {
6416 const ASTRecordLayout &RL =
6417 CGM.getContext().getASTObjCImplementationLayout(OID);
6419 // InstanceSize is really instance end.
6420 InstanceSize = RL.getDataSize().getQuantity();
6422 // If there are no fields, the start is the same as the end.
6423 if (!RL.getFieldCount())
6424 InstanceStart = InstanceSize;
6426 InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth();
6429static llvm::GlobalValue::DLLStorageClassTypes getStorage(CodeGenModule &CGM,
6431 IdentifierInfo &II = CGM.getContext().Idents.get(Name);
6432 TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl();
6433 DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl);
6435 const VarDecl *VD = nullptr;
6436 for (const auto *Result : DC->lookup(&II))
6437 if ((VD = dyn_cast<VarDecl>(Result)))
6441 return llvm::GlobalValue::DLLImportStorageClass;
6442 if (VD->hasAttr<DLLExportAttr>())
6443 return llvm::GlobalValue::DLLExportStorageClass;
6444 if (VD->hasAttr<DLLImportAttr>())
6445 return llvm::GlobalValue::DLLImportStorageClass;
6446 return llvm::GlobalValue::DefaultStorageClass;
6449void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
6450 if (!ObjCEmptyCacheVar) {
6452 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CacheTy, false,
6453 llvm::GlobalValue::ExternalLinkage, nullptr,
6454 "_objc_empty_cache
");
6455 if (CGM.getTriple().isOSBinFormatCOFF())
6456 ObjCEmptyCacheVar->setDLLStorageClass(getStorage(CGM, "_objc_empty_cache
"));
6458 // Only OS X with deployment version <10.9 use the empty vtable symbol
6459 const llvm::Triple &Triple = CGM.getTarget().getTriple();
6460 if (Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 9))
6461 ObjCEmptyVtableVar =
6462 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ImpnfABITy, false,
6463 llvm::GlobalValue::ExternalLinkage, nullptr,
6464 "_objc_empty_vtable
");
6466 ObjCEmptyVtableVar = llvm::ConstantPointerNull::get(CGM.UnqualPtrTy);
6469 // FIXME: Is this correct (that meta class size is never computed)?
6470 uint32_t InstanceStart =
6471 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy);
6472 uint32_t InstanceSize = InstanceStart;
6473 uint32_t flags = NonFragileABI_Class_Meta;
6475 llvm::Constant *SuperClassGV, *IsAGV;
6477 const auto *CI = ID->getClassInterface();
6478 assert(CI && "CGObjCNonFragileABIMac::GenerateClass -
class is 0
");
6480 // Build the flags for the metaclass.
6481 bool classIsHidden = (CGM.getTriple().isOSBinFormatCOFF())
6482 ? !CI->hasAttr<DLLExportAttr>()
6483 : CI->getVisibility() == HiddenVisibility;
6485 flags |= NonFragileABI_Class_Hidden;
6487 // FIXME: why is this flag set on the metaclass?
6488 // ObjC metaclasses have no fields and don't really get constructed.
6489 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
6490 flags |= NonFragileABI_Class_HasCXXStructors;
6491 if (!ID->hasNonZeroConstructors())
6492 flags |= NonFragileABI_Class_HasCXXDestructorOnly;
6495 if (!CI->getSuperClass()) {
6497 flags |= NonFragileABI_Class_Root;
6499 SuperClassGV = GetClassGlobal(CI, /*metaclass*/ false, NotForDefinition);
6500 IsAGV = GetClassGlobal(CI, /*metaclass*/ true, NotForDefinition);
6502 // Has a root. Current class is not a root.
6503 const ObjCInterfaceDecl *Root = ID->getClassInterface();
6504 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
6507 const auto *Super = CI->getSuperClass();
6508 IsAGV = GetClassGlobal(Root, /*metaclass*/ true, NotForDefinition);
6509 SuperClassGV = GetClassGlobal(Super, /*metaclass*/ true, NotForDefinition);
6512 llvm::GlobalVariable *CLASS_RO_GV =
6513 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
6515 llvm::GlobalVariable *MetaTClass =
6516 BuildClassObject(CI, /*metaclass*/ true,
6517 IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden);
6518 CGM.setGVProperties(MetaTClass, CI);
6519 DefinedMetaClasses.push_back(MetaTClass);
6521 // Metadata for the class
6524 flags |= NonFragileABI_Class_Hidden;
6526 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
6527 flags |= NonFragileABI_Class_HasCXXStructors;
6529 // Set a flag to enable a runtime optimization when a class has
6530 // fields that require destruction but which don't require
6531 // anything except zero-initialization during construction. This
6532 // is most notably true of __strong and __weak types, but you can
6533 // also imagine there being C++ types with non-trivial default
6534 // constructors that merely set all fields to null.
6535 if (!ID->hasNonZeroConstructors())
6536 flags |= NonFragileABI_Class_HasCXXDestructorOnly;
6539 if (hasObjCExceptionAttribute(CGM.getContext(), CI))
6540 flags |= NonFragileABI_Class_Exception;
6542 if (!CI->getSuperClass()) {
6543 flags |= NonFragileABI_Class_Root;
6544 SuperClassGV = nullptr;
6546 // Has a root. Current class is not a root.
6547 const auto *Super = CI->getSuperClass();
6548 SuperClassGV = GetClassGlobal(Super, /*metaclass*/ false, NotForDefinition);
6551 GetClassSizeInfo(ID, InstanceStart, InstanceSize);
6553 BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
6555 llvm::GlobalVariable *ClassMD =
6556 BuildClassObject(CI, /*metaclass*/ false,
6557 MetaTClass, SuperClassGV, CLASS_RO_GV, classIsHidden);
6558 CGM.setGVProperties(ClassMD, CI);
6559 DefinedClasses.push_back(ClassMD);
6560 ImplementedClasses.push_back(CI);
6562 // Determine if this class is also "non-lazy
".
6563 if (ImplementationIsNonLazy(ID))
6564 DefinedNonLazyClasses.push_back(ClassMD);
6566 // Force the definition of the EHType if necessary.
6567 if (flags & NonFragileABI_Class_Exception)
6568 (void) GetInterfaceEHType(CI, ForDefinition);
6569 // Make sure method definition entries are all clear for next implementation.
6570 MethodDefinitions.clear();
6581llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CodeGenFunction &CGF,
6582 const ObjCProtocolDecl *PD) {
6584 // This routine is called for @protocol only. So, we must build definition
6585 // of protocol's meta-data (not a reference to it!)
6586 assert(!PD->isNonRuntimeProtocol() &&
6587 "attempting to get a protocol ref to a
static protocol.
");
6588 llvm::Constant *Init = GetOrEmitProtocol(PD);
6590 std::string ProtocolName("_OBJC_PROTOCOL_REFERENCE_$_
");
6591 ProtocolName += PD->getObjCRuntimeNameAsString();
6593 CharUnits Align = CGF.getPointerAlign();
6595 llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);
6597 return CGF.Builder.CreateAlignedLoad(PTGV->getValueType(), PTGV, Align);
6598 PTGV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
6599 llvm::GlobalValue::WeakAnyLinkage, Init,
6601 PTGV->setSection(GetSectionName("__objc_protorefs
",
6602 "coalesced,no_dead_strip
"));
6603 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
6604 PTGV->setAlignment(Align.getAsAlign());
6605 if (!CGM.getTriple().isOSBinFormatMachO())
6606 PTGV->setComdat(CGM.getModule().getOrInsertComdat(ProtocolName));
6607 CGM.addUsedGlobal(PTGV);
6608 return CGF.Builder.CreateAlignedLoad(PTGV->getValueType(), PTGV, Align);
6623void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
6624 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
6625 const char *Prefix = "_OBJC_$_CATEGORY_
";
6627 llvm::SmallString<64> ExtCatName(Prefix);
6628 ExtCatName += Interface->getObjCRuntimeNameAsString();
6629 ExtCatName += "_$_
";
6630 ExtCatName += OCD->getNameAsString();
6632 ConstantInitBuilder builder(CGM);
6633 auto values = builder.beginStruct(ObjCTypes.CategorynfABITy);
6634 values.add(GetClassName(OCD->getIdentifier()->getName()));
6635 // meta-class entry symbol
6636 values.add(GetClassGlobal(Interface, /*metaclass*/ false, NotForDefinition));
6637 std::string listName =
6638 (Interface->getObjCRuntimeNameAsString() + "_$_
" + OCD->getName()).str();
6640 SmallVector<const ObjCMethodDecl *, 16> instanceMethods;
6641 SmallVector<const ObjCMethodDecl *, 8> classMethods;
6642 for (const auto *MD : OCD->methods()) {
6643 if (MD->isDirectMethod())
6645 if (MD->isInstanceMethod()) {
6646 instanceMethods.push_back(MD);
6648 classMethods.push_back(MD);
6652 auto instanceMethodList = emitMethodList(
6653 listName, MethodListType::CategoryInstanceMethods, instanceMethods);
6654 auto classMethodList = emitMethodList(
6655 listName, MethodListType::CategoryClassMethods, classMethods);
6656 values.add(instanceMethodList);
6657 values.add(classMethodList);
6658 // Keep track of whether we have actual metadata to emit.
6659 bool isEmptyCategory =
6660 instanceMethodList->isNullValue() && classMethodList->isNullValue();
6662 const ObjCCategoryDecl *Category =
6663 Interface->FindCategoryDeclaration(OCD->getIdentifier());
6665 SmallString<256> ExtName;
6666 llvm::raw_svector_ostream(ExtName)
6667 << Interface->getObjCRuntimeNameAsString() << "_$_
" << OCD->getName();
6669 EmitProtocolList("_OBJC_CATEGORY_PROTOCOLS_$_
" +
6670 Interface->getObjCRuntimeNameAsString() + "_$_
" +
6671 Category->getName(),
6672 Category->protocol_begin(), Category->protocol_end());
6673 auto propertyList = EmitPropertyList("_OBJC_$_PROP_LIST_
" + ExtName.str(),
6674 OCD, Category, ObjCTypes, false);
6675 auto classPropertyList =
6676 EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_
" + ExtName.str(), OCD,
6677 Category, ObjCTypes, true);
6678 values.add(protocolList);
6679 values.add(propertyList);
6680 values.add(classPropertyList);
6681 isEmptyCategory &= protocolList->isNullValue() &&
6682 propertyList->isNullValue() &&
6683 classPropertyList->isNullValue();
6685 values.addNullPointer(ObjCTypes.ProtocolListnfABIPtrTy);
6686 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
6687 values.addNullPointer(ObjCTypes.PropertyListPtrTy);
6690 if (isEmptyCategory) {
6691 // Empty category, don't emit any metadata.
6693 MethodDefinitions.clear();
6698 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.CategorynfABITy);
6699 values.addInt(ObjCTypes.IntTy, Size);
6701 llvm::GlobalVariable *GCATV =
6702 finishAndCreateGlobal(values, ExtCatName.str(), CGM);
6703 CGM.addCompilerUsedGlobal(GCATV);
6704 if (Interface->hasAttr<ObjCClassStubAttr>())
6705 DefinedStubCategories.push_back(GCATV);
6707 DefinedCategories.push_back(GCATV);
6709 // Determine if this category is also "non-lazy
".
6710 if (ImplementationIsNonLazy(OCD))
6711 DefinedNonLazyCategories.push_back(GCATV);
6712 // method definition entries must be clear for next implementation.
6713 MethodDefinitions.clear();
6725void CGObjCNonFragileABIMac::emitMethodConstant(ConstantArrayBuilder &builder,
6726 const ObjCMethodDecl *MD,
6728 auto method = builder.beginStruct(ObjCTypes.MethodTy);
6729 method.add(GetMethodVarName(MD->getSelector()));
6730 method.add(GetMethodVarType(MD));
6733 // Protocol methods have no implementation. So, this entry is always NULL.
6734 method.addNullPointer(ObjCTypes.Int8PtrProgramASTy);
6736 llvm::Function *fn = GetMethodDefinition(MD);
6737 assert(fn && "no definition
for method?
");
6741 method.finishAndAddTo(builder);
6753CGObjCNonFragileABIMac::emitMethodList(Twine name, MethodListType kind,
6754 ArrayRef<const ObjCMethodDecl *> methods) {
6755 // Return null for empty list.
6756 if (methods.empty())
6757 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
6762 case MethodListType::CategoryInstanceMethods:
6763 prefix = "_OBJC_$_CATEGORY_INSTANCE_METHODS_
";
6764 forProtocol = false;
6766 case MethodListType::CategoryClassMethods:
6767 prefix = "_OBJC_$_CATEGORY_CLASS_METHODS_
";
6768 forProtocol = false;
6770 case MethodListType::InstanceMethods:
6771 prefix = "_OBJC_$_INSTANCE_METHODS_
";
6772 forProtocol = false;
6774 case MethodListType::ClassMethods:
6775 prefix = "_OBJC_$_CLASS_METHODS_
";
6776 forProtocol = false;
6779 case MethodListType::ProtocolInstanceMethods:
6780 prefix = "_OBJC_$_PROTOCOL_INSTANCE_METHODS_
";
6783 case MethodListType::ProtocolClassMethods:
6784 prefix = "_OBJC_$_PROTOCOL_CLASS_METHODS_
";
6787 case MethodListType::OptionalProtocolInstanceMethods:
6788 prefix = "_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_
";
6791 case MethodListType::OptionalProtocolClassMethods:
6792 prefix = "_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_
";
6797 ConstantInitBuilder builder(CGM);
6798 auto values = builder.beginStruct();
6800 // sizeof(struct _objc_method)
6801 unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.MethodTy);
6802 values.addInt(ObjCTypes.IntTy, Size);
6804 values.addInt(ObjCTypes.IntTy, methods.size());
6805 auto methodArray = values.beginArray(ObjCTypes.MethodTy);
6806 for (auto MD : methods)
6807 emitMethodConstant(methodArray, MD, forProtocol);
6808 methodArray.finishAndAddTo(values);
6810 llvm::GlobalVariable *GV = finishAndCreateGlobal(values, prefix + name, CGM);
6811 CGM.addCompilerUsedGlobal(GV);
6817llvm::GlobalVariable *
6818CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
6819 const ObjCIvarDecl *Ivar) {
6820 const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
6821 llvm::SmallString<64> Name("OBJC_IVAR_$_
");
6822 Name += Container->getObjCRuntimeNameAsString();
6824 Name += Ivar->getName();
6825 llvm::GlobalVariable *IvarOffsetGV = CGM.getModule().getGlobalVariable(Name);
6826 if (!IvarOffsetGV) {
6828 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.IvarOffsetVarTy,
6829 false, llvm::GlobalValue::ExternalLinkage,
6830 nullptr, Name.str());
6831 if (CGM.getTriple().isOSBinFormatCOFF()) {
6832 bool IsPrivateOrPackage =
6833 Ivar->getAccessControl() == ObjCIvarDecl::Private ||
6834 Ivar->getAccessControl() == ObjCIvarDecl::Package;
6836 const ObjCInterfaceDecl *ContainingID = Ivar->getContainingInterface();
6838 if (ContainingID->hasAttr<DLLImportAttr>())
6840 ->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
6841 else if (ContainingID->hasAttr<DLLExportAttr>() && !IsPrivateOrPackage)
6843 ->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
6846 return IvarOffsetGV;
6850CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
6851 const ObjCIvarDecl *Ivar,
6852 unsigned long int Offset) {
6853 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
6854 IvarOffsetGV->setInitializer(
6855 llvm::ConstantInt::get(ObjCTypes.IvarOffsetVarTy, Offset));
6856 IvarOffsetGV->setAlignment(
6857 CGM.getDataLayout().getABITypeAlign(ObjCTypes.IvarOffsetVarTy));
6859 if (!CGM.getTriple().isOSBinFormatCOFF()) {
6860 // FIXME: This matches gcc, but shouldn't the visibility be set on the use
6861 // as well (i.e., in ObjCIvarOffsetVariable).
6862 if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
6863 Ivar->getAccessControl() == ObjCIvarDecl::Package ||
6864 ID->getVisibility() == HiddenVisibility)
6865 IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
6867 IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility);
6870 // If ID's layout is known, then make the global constant. This serves as a
6871 // useful assertion: we'll never use this variable to calculate ivar offsets,
6872 // so if the runtime tries to patch it then we should crash.
6873 if (isClassLayoutKnownStatically(ID))
6874 IvarOffsetGV->setConstant(true);
6876 if (CGM.getTriple().isOSBinFormatMachO())
6877 IvarOffsetGV->setSection("__DATA, __objc_ivar
");
6878 return IvarOffsetGV;
6898llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
6899 const ObjCImplementationDecl *ID) {
6901 ConstantInitBuilder builder(CGM);
6902 auto ivarList = builder.beginStruct();
6903 ivarList.addInt(ObjCTypes.IntTy,
6904 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.IvarnfABITy));
6905 auto ivarCountSlot = ivarList.addPlaceholder();
6906 auto ivars = ivarList.beginArray(ObjCTypes.IvarnfABITy);
6908 const ObjCInterfaceDecl *OID = ID->getClassInterface();
6909 assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface
");
6911 // FIXME. Consolidate this with similar code in GenerateClass.
6913 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
6914 IVD; IVD = IVD->getNextIvar()) {
6915 // Ignore unnamed bit-fields.
6916 if (!IVD->getDeclName())
6919 auto ivar = ivars.beginStruct(ObjCTypes.IvarnfABITy);
6920 ivar.add(EmitIvarOffsetVar(ID->getClassInterface(), IVD,
6921 ComputeIvarBaseOffset(CGM, ID, IVD)));
6922 ivar.add(GetMethodVarName(IVD->getIdentifier()));
6923 ivar.add(GetMethodVarType(IVD));
6924 llvm::Type *FieldTy =
6925 CGM.getTypes().ConvertTypeForMem(IVD->getType());
6926 unsigned Size = CGM.getDataLayout().getTypeAllocSize(FieldTy);
6927 unsigned Align = CGM.getContext().getPreferredTypeAlign(
6928 IVD->getType().getTypePtr()) >> 3;
6929 Align = llvm::Log2_32(Align);
6930 ivar.addInt(ObjCTypes.IntTy, Align);
6931 // NOTE. Size of a bitfield does not match gcc's, because of the
6932 // way bitfields are treated special in each. But I am told that
6933 // 'size' for bitfield ivars is ignored by the runtime so it does
6934 // not matter. If it matters, there is enough info to get the
6936 ivar.addInt(ObjCTypes.IntTy, Size);
6937 ivar.finishAndAddTo(ivars);
6939 // Return null for empty list.
6940 if (ivars.empty()) {
6943 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
6946 auto ivarCount = ivars.size();
6947 ivars.finishAndAddTo(ivarList);
6948 ivarList.fillPlaceholderWithInt(ivarCountSlot, ObjCTypes.IntTy, ivarCount);
6950 const char *Prefix = "_OBJC_$_INSTANCE_VARIABLES_
";
6951 llvm::GlobalVariable *GV = finishAndCreateGlobal(
6952 ivarList, Prefix + OID->getObjCRuntimeNameAsString(), CGM);
6953 CGM.addCompilerUsedGlobal(GV);
6957llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(
6958 const ObjCProtocolDecl *PD) {
6959 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
6961 assert(!PD->isNonRuntimeProtocol() &&
6962 "attempting to GetOrEmit a non-runtime protocol
");
6964 // We use the initializer as a marker of whether this is a forward
6965 // reference or not. At module finalization we add the empty
6966 // contents for protocols which were referenced but never defined.
6967 llvm::SmallString<64> Protocol;
6968 llvm::raw_svector_ostream(Protocol) << "_OBJC_PROTOCOL_$_
"
6969 << PD->getObjCRuntimeNameAsString();
6971 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
6972 false, llvm::GlobalValue::ExternalLinkage,
6974 if (!CGM.getTriple().isOSBinFormatMachO())
6975 Entry->setComdat(CGM.getModule().getOrInsertComdat(Protocol));
7001llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
7002 const ObjCProtocolDecl *PD) {
7003 llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
7005 // Early exit if a defining object has already been generated.
7006 if (Entry && Entry->hasInitializer())
7009 // Use the protocol definition, if there is one.
7010 assert(PD->hasDefinition() &&
7011 "emitting protocol metadata without definition
");
7012 PD = PD->getDefinition();
7014 auto methodLists = ProtocolMethodLists::get(PD);
7016 ConstantInitBuilder builder(CGM);
7017 auto values = builder.beginStruct(ObjCTypes.ProtocolnfABITy);
7020 values.addNullPointer(ObjCTypes.ObjectPtrTy);
7021 values.add(GetClassName(PD->getObjCRuntimeNameAsString()));
7022 values.add(EmitProtocolList("_OBJC_$_PROTOCOL_REFS_
"
7023 + PD->getObjCRuntimeNameAsString(),
7024 PD->protocol_begin(),
7025 PD->protocol_end()));
7026 values.add(methodLists.emitMethodList(this, PD,
7027 ProtocolMethodLists::RequiredInstanceMethods));
7028 values.add(methodLists.emitMethodList(this, PD,
7029 ProtocolMethodLists::RequiredClassMethods));
7030 values.add(methodLists.emitMethodList(this, PD,
7031 ProtocolMethodLists::OptionalInstanceMethods));
7032 values.add(methodLists.emitMethodList(this, PD,
7033 ProtocolMethodLists::OptionalClassMethods));
7034 values.add(EmitPropertyList(
7035 "_OBJC_$_PROP_LIST_
" + PD->getObjCRuntimeNameAsString(),
7036 nullptr, PD, ObjCTypes, false));
7038 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
7039 values.addInt(ObjCTypes.IntTy, Size);
7040 values.addInt(ObjCTypes.IntTy, 0);
7041 values.add(EmitProtocolMethodTypes("_OBJC_$_PROTOCOL_METHOD_TYPES_
"
7042 + PD->getObjCRuntimeNameAsString(),
7043 methodLists.emitExtendedTypesArray(this),
7046 // const char *demangledName;
7047 values.addNullPointer(ObjCTypes.Int8PtrTy);
7049 values.add(EmitPropertyList(
7050 "_OBJC_$_CLASS_PROP_LIST_
" + PD->getObjCRuntimeNameAsString(),
7051 nullptr, PD, ObjCTypes, true));
7054 // Already created, fix the linkage and update the initializer.
7055 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
7056 values.finishAndSetAsInitializer(Entry);
7058 llvm::SmallString<64> symbolName;
7059 llvm::raw_svector_ostream(symbolName)
7060 << "_OBJC_PROTOCOL_$_
" << PD->getObjCRuntimeNameAsString();
7062 Entry = values.finishAndCreateGlobal(symbolName, CGM.getPointerAlign(),
7064 llvm::GlobalValue::WeakAnyLinkage);
7065 if (!CGM.getTriple().isOSBinFormatMachO())
7066 Entry->setComdat(CGM.getModule().getOrInsertComdat(symbolName));
7068 Protocols[PD->getIdentifier()] = Entry;
7070 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
7071 CGM.addUsedGlobal(Entry);
7073 // Use this protocol meta-data to build protocol list table in section
7074 // __DATA, __objc_protolist
7075 llvm::SmallString<64> ProtocolRef;
7076 llvm::raw_svector_ostream(ProtocolRef) << "_OBJC_LABEL_PROTOCOL_$_
"
7077 << PD->getObjCRuntimeNameAsString();
7079 llvm::GlobalVariable *PTGV =
7080 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy,
7081 false, llvm::GlobalValue::WeakAnyLinkage, Entry,
7083 if (!CGM.getTriple().isOSBinFormatMachO())
7084 PTGV->setComdat(CGM.getModule().getOrInsertComdat(ProtocolRef));
7086 CGM.getDataLayout().getABITypeAlign(ObjCTypes.ProtocolnfABIPtrTy));
7087 PTGV->setSection(GetSectionName("__objc_protolist
",
7088 "coalesced,no_dead_strip
"));
7089 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
7090 CGM.addUsedGlobal(PTGV);
7103CGObjCNonFragileABIMac::EmitProtocolList(Twine Name,
7104 ObjCProtocolDecl::protocol_iterator begin,
7105 ObjCProtocolDecl::protocol_iterator end) {
7106 // Just return null for empty protocol lists
7107 auto Protocols = GetRuntimeProtocolList(begin, end);
7108 if (Protocols.empty())
7109 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
7111 SmallVector<llvm::Constant *, 16> ProtocolRefs;
7112 ProtocolRefs.reserve(Protocols.size());
7114 for (const auto *PD : Protocols)
7115 ProtocolRefs.push_back(GetProtocolRef(PD));
7117 // If all of the protocols in the protocol list are objc_non_runtime_protocol
7119 if (ProtocolRefs.size() == 0)
7120 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
7122 // FIXME: We shouldn't need to do this lookup here, should we?
7123 SmallString<256> TmpName;
7124 Name.toVector(TmpName);
7125 llvm::GlobalVariable *GV =
7126 CGM.getModule().getGlobalVariable(TmpName.str(), true);
7130 ConstantInitBuilder builder(CGM);
7131 auto values = builder.beginStruct();
7132 auto countSlot = values.addPlaceholder();
7134 // A null-terminated array of protocols.
7135 auto array = values.beginArray(ObjCTypes.ProtocolnfABIPtrTy);
7136 for (auto const &proto : ProtocolRefs)
7138 auto count = array.size();
7139 array.addNullPointer(ObjCTypes.ProtocolnfABIPtrTy);
7141 array.finishAndAddTo(values);
7142 values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
7144 GV = finishAndCreateGlobal(values, Name, CGM);
7145 CGM.addCompilerUsedGlobal(GV);
7155LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
7156 CodeGen::CodeGenFunction &CGF,
7158 llvm::Value *BaseValue,
7159 const ObjCIvarDecl *Ivar,
7160 unsigned CVRQualifiers) {
7161 ObjCInterfaceDecl *ID = ObjectTy->castAs<ObjCObjectType>()->getInterface();
7162 llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
7163 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
7168CGObjCNonFragileABIMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
7169 const ObjCInterfaceDecl *Interface,
7170 const ObjCIvarDecl *Ivar) {
7171 llvm::Value *IvarOffsetValue;
7172 if (isClassLayoutKnownStatically(Interface)) {
7173 IvarOffsetValue = llvm::ConstantInt::get(
7174 ObjCTypes.IvarOffsetVarTy,
7175 ComputeIvarBaseOffset(CGM, Interface->getImplementation(), Ivar));
7177 llvm::GlobalVariable *GV = ObjCIvarOffsetVariable(Interface, Ivar);
7179 CGF.Builder.CreateAlignedLoad(GV->getValueType(), GV,
7180 CGF.getSizeAlign(), "ivar
");
7181 if (IsIvarOffsetKnownIdempotent(CGF, Ivar))
7182 cast<llvm::LoadInst>(IvarOffsetValue)
7183 ->setMetadata(llvm::LLVMContext::MD_invariant_load,
7184 llvm::MDNode::get(VMContext, {}));
7187 // This could be 32bit int or 64bit integer depending on the architecture.
7188 // Cast it to 64bit integer value, if it is a 32bit integer ivar offset value
7189 // as this is what caller always expects.
7190 if (ObjCTypes.IvarOffsetVarTy == ObjCTypes.IntTy)
7191 IvarOffsetValue = CGF.Builder.CreateIntCast(
7192 IvarOffsetValue, ObjCTypes.LongTy, true, "ivar.conv
");
7193 return IvarOffsetValue;
7196static void appendSelectorForMessageRefTable(std::string &buffer,
7197 Selector selector) {
7198 if (selector.isUnarySelector()) {
7199 buffer += selector.getNameForSlot(0);
7203 for (unsigned i = 0, e = selector.getNumArgs(); i != e; ++i) {
7204 buffer += selector.getNameForSlot(i);
7220CGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF,
7221 ReturnValueSlot returnSlot,
7222 QualType resultType,
7227 const CallArgList &formalArgs,
7228 const ObjCMethodDecl *method) {
7229 // Compute the actual arguments.
7232 // First argument: the receiver / super-call structure.
7234 arg0 = CGF.Builder.CreateBitCast(arg0, ObjCTypes.ObjectPtrTy);
7235 args.add(RValue::get(arg0), arg0Type);
7237 // Second argument: a pointer to the message ref structure. Leave
7238 // the actual argument value blank for now.
7239 args.add(RValue::get(nullptr), ObjCTypes.MessageRefCPtrTy);
7241 args.insert(args.end(), formalArgs.begin(), formalArgs.end());
7243 MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);
7245 NullReturnState nullReturn;
7247 // Find the function to call and the mangled name for the message
7248 // ref structure. Using a different mangled name wouldn't actually
7249 // be a problem; it would just be a waste.
7251 // The runtime currently never uses vtable dispatch for anything
7252 // except normal, non-super message-sends.
7253 // FIXME: don't use this for that.
7254 llvm::FunctionCallee fn = nullptr;
7255 std::string messageRefName("_
");
7256 if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
7258 fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
7259 messageRefName += "objc_msgSendSuper2_stret_fixup
";
7261 nullReturn.init(CGF, arg0);
7262 fn = ObjCTypes.getMessageSendStretFixupFn();
7263 messageRefName += "objc_msgSend_stret_fixup
";
7265 } else if (!isSuper && CGM.ReturnTypeUsesFPRet(resultType)) {
7266 fn = ObjCTypes.getMessageSendFpretFixupFn();
7267 messageRefName += "objc_msgSend_fpret_fixup
";
7270 fn = ObjCTypes.getMessageSendSuper2FixupFn();
7271 messageRefName += "objc_msgSendSuper2_fixup
";
7273 fn = ObjCTypes.getMessageSendFixupFn();
7274 messageRefName += "objc_msgSend_fixup
";
7277 assert(fn && "CGObjCNonFragileABIMac::EmitMessageSend
");
7278 messageRefName += '_';
7280 // Append the selector name, except use underscores anywhere we
7281 // would have used colons.
7282 appendSelectorForMessageRefTable(messageRefName, selector);
7284 llvm::GlobalVariable *messageRef
7285 = CGM.getModule().getGlobalVariable(messageRefName);
7287 // Build the message ref structure.
7288 ConstantInitBuilder builder(CGM);
7289 auto values = builder.beginStruct();
7290 values.add(cast<llvm::Constant>(fn.getCallee()));
7291 values.add(GetMethodVarName(selector));
7292 messageRef = values.finishAndCreateGlobal(messageRefName,
7293 CharUnits::fromQuantity(16),
7295 llvm::GlobalValue::WeakAnyLinkage);
7296 messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility);
7297 messageRef->setSection(GetSectionName("__objc_msgrefs
", "coalesced
"));
7300 bool requiresnullCheck = false;
7301 if (CGM.getLangOpts().ObjCAutoRefCount && method)
7302 for (const auto *ParamDecl : method->parameters()) {
7303 if (ParamDecl->isDestroyedInCallee()) {
7304 if (!nullReturn.NullBB)
7305 nullReturn.init(CGF, arg0);
7306 requiresnullCheck = true;
7312 Address(CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy),
7313 ObjCTypes.MessageRefTy, CGF.getPointerAlign());
7315 // Update the message ref argument.
7316 args[1].setRValue(RValue::get(mref, CGF));
7318 // Load the function to call from the message ref table.
7319 Address calleeAddr = CGF.Builder.CreateStructGEP(mref, 0);
7320 llvm::Value *calleePtr = CGF.Builder.CreateLoad(calleeAddr, "msgSend_fn
");
7322 calleePtr = CGF.Builder.CreateBitCast(calleePtr, MSI.MessengerType);
7323 CGCallee callee(CGCalleeInfo(), calleePtr);
7325 RValue result = CGF.EmitCall(MSI.CallInfo, callee, returnSlot, args);
7326 return nullReturn.complete(CGF, returnSlot, result, resultType, formalArgs,
7327 requiresnullCheck ? method : nullptr);
7332CGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
7333 ReturnValueSlot Return,
7334 QualType ResultType,
7336 llvm::Value *Receiver,
7337 const CallArgList &CallArgs,
7338 const ObjCInterfaceDecl *Class,
7339 const ObjCMethodDecl *Method) {
7340 return isVTableDispatchedSelector(Sel)
7341 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
7342 Receiver, CGF.getContext().getObjCIdType(),
7343 false, CallArgs, Method)
7344 : EmitMessageSend(CGF, Return, ResultType, Sel,
7345 Receiver, CGF.getContext().getObjCIdType(),
7346 false, CallArgs, Method, Class, ObjCTypes);
7350CGObjCNonFragileABIMac::GetClassGlobal(const ObjCInterfaceDecl *ID,
7352 ForDefinition_t isForDefinition) {
7354 (metaclass ? getMetaclassSymbolPrefix() : getClassSymbolPrefix());
7355 return GetClassGlobal((prefix + ID->getObjCRuntimeNameAsString()).str(),
7357 ID->isWeakImported(),
7359 && CGM.getTriple().isOSBinFormatCOFF()
7360 && ID->hasAttr<DLLImportAttr>());
7364CGObjCNonFragileABIMac::GetClassGlobal(StringRef Name,
7365 ForDefinition_t IsForDefinition,
7366 bool Weak, bool DLLImport) {
7367 llvm::GlobalValue::LinkageTypes L =
7368 Weak ? llvm::GlobalValue::ExternalWeakLinkage
7369 : llvm::GlobalValue::ExternalLinkage;
7371 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
7372 if (!GV || GV->getValueType() != ObjCTypes.ClassnfABITy) {
7373 auto *NewGV = new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, L,
7377 NewGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
7380 GV->replaceAllUsesWith(NewGV);
7381 GV->eraseFromParent();
7384 CGM.getModule().insertGlobalVariable(GV);
7387 assert(GV->getLinkage() == L);
7392CGObjCNonFragileABIMac::GetClassGlobalForClassRef(const ObjCInterfaceDecl *ID) {
7393 llvm::Constant *ClassGV = GetClassGlobal(ID, /*metaclass*/ false,
7396 if (!ID->hasAttr<ObjCClassStubAttr>())
7399 ClassGV = llvm::ConstantExpr::getPointerCast(ClassGV, ObjCTypes.Int8PtrTy);
7401 // Stub classes are pointer-aligned. Classrefs pointing at stub classes
7402 // must set the least significant bit set to 1.
7403 auto *Idx = llvm::ConstantInt::get(CGM.Int32Ty, 1);
7404 return llvm::ConstantExpr::getGetElementPtr(CGM.Int8Ty, ClassGV, Idx);
7408CGObjCNonFragileABIMac::EmitLoadOfClassRef(CodeGenFunction &CGF,
7409 const ObjCInterfaceDecl *ID,
7410 llvm::GlobalVariable *Entry) {
7411 if (ID && ID->hasAttr<ObjCClassStubAttr>()) {
7412 // Classrefs pointing at Objective-C stub classes must be loaded by calling
7413 // a special runtime function.
7414 return CGF.EmitRuntimeCall(
7415 ObjCTypes.getLoadClassrefFn(), Entry, "load_classref_result
");
7418 CharUnits Align = CGF.getPointerAlign();
7419 return CGF.Builder.CreateAlignedLoad(Entry->getValueType(), Entry, Align);
7423CGObjCNonFragileABIMac::EmitClassRefFromId(CodeGenFunction &CGF,
7425 const ObjCInterfaceDecl *ID) {
7426 llvm::GlobalVariable *&Entry = ClassReferences[II];
7429 llvm::Constant *ClassGV;
7431 ClassGV = GetClassGlobalForClassRef(ID);
7433 ClassGV = GetClassGlobal((getClassSymbolPrefix() + II->getName()).str(),
7435 assert(ClassGV->getType() == ObjCTypes.ClassnfABIPtrTy &&
7436 "classref was emitted with the wrong
type?
");
7439 std::string SectionName =
7440 GetSectionName("__objc_classrefs
", "regular,no_dead_strip
");
7441 Entry = new llvm::GlobalVariable(
7442 CGM.getModule(), ClassGV->getType(), false,
7443 getLinkageTypeForObjCMetadata(CGM, SectionName), ClassGV,
7444 "OBJC_CLASSLIST_REFERENCES_$_
");
7445 Entry->setAlignment(CGF.getPointerAlign().getAsAlign());
7446 if (!ID || !ID->hasAttr<ObjCClassStubAttr>())
7447 Entry->setSection(SectionName);
7449 CGM.addCompilerUsedGlobal(Entry);
7452 return EmitLoadOfClassRef(CGF, ID, Entry);
7455llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CodeGenFunction &CGF,
7456 const ObjCInterfaceDecl *ID) {
7457 // If the class has the objc_runtime_visible attribute, we need to
7458 // use the Objective-C runtime to get the class.
7459 if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
7460 return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
7462 return EmitClassRefFromId(CGF, ID->getIdentifier(), ID);
7465llvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(
7466 CodeGenFunction &CGF) {
7467 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool
");
7468 return EmitClassRefFromId(CGF, II, nullptr);
7472CGObjCNonFragileABIMac::EmitSuperClassRef(CodeGenFunction &CGF,
7473 const ObjCInterfaceDecl *ID) {
7474 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
7477 llvm::Constant *ClassGV = GetClassGlobalForClassRef(ID);
7478 std::string SectionName =
7479 GetSectionName("__objc_superrefs
", "regular,no_dead_strip
");
7480 Entry = new llvm::GlobalVariable(CGM.getModule(), ClassGV->getType(), false,
7481 llvm::GlobalValue::PrivateLinkage, ClassGV,
7482 "OBJC_CLASSLIST_SUP_REFS_$_
");
7483 Entry->setAlignment(CGF.getPointerAlign().getAsAlign());
7484 Entry->setSection(SectionName);
7485 CGM.addCompilerUsedGlobal(Entry);
7488 return EmitLoadOfClassRef(CGF, ID, Entry);
7494llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CodeGenFunction &CGF,
7495 const ObjCInterfaceDecl *ID,
7497 CharUnits Align = CGF.getPointerAlign();
7498 llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()];
7500 auto MetaClassGV = GetClassGlobal(ID, /*metaclass*/ true, NotForDefinition);
7501 std::string SectionName =
7502 GetSectionName("__objc_superrefs
", "regular,no_dead_strip
");
7503 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
7504 false, llvm::GlobalValue::PrivateLinkage,
7505 MetaClassGV, "OBJC_CLASSLIST_SUP_REFS_$_
");
7506 Entry->setAlignment(Align.getAsAlign());
7507 Entry->setSection(SectionName);
7508 CGM.addCompilerUsedGlobal(Entry);
7511 return CGF.Builder.CreateAlignedLoad(ObjCTypes.ClassnfABIPtrTy, Entry, Align);
7516llvm::Value *CGObjCNonFragileABIMac::GetClass(CodeGenFunction &CGF,
7517 const ObjCInterfaceDecl *ID) {
7518 if (ID->isWeakImported()) {
7519 auto ClassGV = GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition);
7521 assert(!isa<llvm::GlobalVariable>(ClassGV) ||
7522 cast<llvm::GlobalVariable>(ClassGV)->hasExternalWeakLinkage());
7525 return EmitClassRef(CGF, ID);
7532CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
7533 ReturnValueSlot Return,
7534 QualType ResultType,
7536 const ObjCInterfaceDecl *Class,
7537 bool isCategoryImpl,
7538 llvm::Value *Receiver,
7539 bool IsClassMessage,
7540 const CodeGen::CallArgList &CallArgs,
7541 const ObjCMethodDecl *Method) {
7543 // Create and init a super structure; this is a (receiver, class)
7544 // pair we will pass to objc_msgSendSuper.
7545 RawAddress ObjCSuper = CGF.CreateTempAlloca(
7546 ObjCTypes.SuperTy, CGF.getPointerAlign(), "objc_super
");
7548 llvm::Value *ReceiverAsObject =
7549 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
7550 CGF.Builder.CreateStore(ReceiverAsObject,
7551 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
7553 // If this is a class message the metaclass is passed as the target.
7554 llvm::Value *Target;
7556 Target = EmitMetaClassRef(CGF, Class, Class->isWeakImported());
7558 Target = EmitSuperClassRef(CGF, Class);
7560 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
7562 llvm::Type *ClassTy =
7563 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
7564 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
7565 CGF.Builder.CreateStore(Target, CGF.Builder.CreateStructGEP(ObjCSuper, 1));
7567 return (isVTableDispatchedSelector(Sel))
7568 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
7569 ObjCSuper.getPointer(), ObjCTypes.SuperPtrCTy,
7570 true, CallArgs, Method)
7571 : EmitMessageSend(CGF, Return, ResultType, Sel,
7572 ObjCSuper.getPointer(), ObjCTypes.SuperPtrCTy,
7573 true, CallArgs, Method, Class, ObjCTypes);
7576llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CodeGenFunction &CGF,
7578 Address Addr = EmitSelectorAddr(Sel);
7580 llvm::LoadInst* LI = CGF.Builder.CreateLoad(Addr);
7581 LI->setMetadata(llvm::LLVMContext::MD_invariant_load,
7582 llvm::MDNode::get(VMContext, {}));
7586ConstantAddress CGObjCNonFragileABIMac::EmitSelectorAddr(Selector Sel) {
7587 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
7588 CharUnits Align = CGM.getPointerAlign();
7590 std::string SectionName =
7591 GetSectionName("__objc_selrefs
", "literal_pointers,no_dead_strip
");
7592 Entry = new llvm::GlobalVariable(
7593 CGM.getModule(), ObjCTypes.SelectorPtrTy, false,
7594 getLinkageTypeForObjCMetadata(CGM, SectionName), GetMethodVarName(Sel),
7595 "OBJC_SELECTOR_REFERENCES_
");
7596 Entry->setExternallyInitialized(true);
7597 Entry->setSection(SectionName);
7598 Entry->setAlignment(Align.getAsAlign());
7599 CGM.addCompilerUsedGlobal(Entry);
7602 return ConstantAddress(Entry, ObjCTypes.SelectorPtrTy, Align);
7608void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
7611 llvm::Value *ivarOffset) {
7612 llvm::Type * SrcTy = src->getType();
7613 if (!isa<llvm::PointerType>(SrcTy)) {
7614 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7615 assert(Size <= 8 && "does
not support size > 8
");
7616 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7617 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7618 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7620 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7621 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
7622 ObjCTypes.PtrObjectPtrTy);
7623 llvm::Value *args[] = {src, dstVal, ivarOffset};
7624 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
7630void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
7631 CodeGen::CodeGenFunction &CGF,
7632 llvm::Value *src, Address dst) {
7633 llvm::Type * SrcTy = src->getType();
7634 if (!isa<llvm::PointerType>(SrcTy)) {
7635 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7636 assert(Size <= 8 && "does
not support size > 8
");
7637 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7638 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7639 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7641 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7642 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
7643 ObjCTypes.PtrObjectPtrTy);
7644 llvm::Value *args[] = {src, dstVal};
7645 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(),
7646 args, "weakassign
");
7649void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
7650 CodeGen::CodeGenFunction &CGF, Address DestPtr, Address SrcPtr,
7651 llvm::Value *Size) {
7652 llvm::Value *args[] = {DestPtr.emitRawPointer(CGF),
7653 SrcPtr.emitRawPointer(CGF), Size};
7654 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
7660llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(
7661 CodeGen::CodeGenFunction &CGF,
7662 Address AddrWeakObj) {
7663 llvm::Type *DestTy = AddrWeakObj.getElementType();
7664 llvm::Value *AddrWeakObjVal = CGF.Builder.CreateBitCast(
7665 AddrWeakObj.emitRawPointer(CGF), ObjCTypes.PtrObjectPtrTy);
7666 llvm::Value *read_weak =
7667 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(),
7668 AddrWeakObjVal, "weakread
");
7669 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
7676void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
7677 llvm::Value *src, Address dst) {
7678 llvm::Type * SrcTy = src->getType();
7679 if (!isa<llvm::PointerType>(SrcTy)) {
7680 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7681 assert(Size <= 8 && "does
not support size > 8
");
7682 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7683 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7684 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7686 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7687 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
7688 ObjCTypes.PtrObjectPtrTy);
7689 llvm::Value *args[] = {src, dstVal};
7690 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(),
7691 args, "weakassign
");
7697void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
7698 llvm::Value *src, Address dst,
7700 llvm::Type * SrcTy = src->getType();
7701 if (!isa<llvm::PointerType>(SrcTy)) {
7702 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7703 assert(Size <= 8 && "does
not support size > 8
");
7704 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7705 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7706 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7708 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7709 llvm::Value *dstVal = CGF.Builder.CreateBitCast(dst.emitRawPointer(CGF),
7710 ObjCTypes.PtrObjectPtrTy);
7711 llvm::Value *args[] = {src, dstVal};
7713 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(),
7714 args, "globalassign
");
7716 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(),
7717 args, "threadlocalassign
");
7721CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
7722 const ObjCAtSynchronizedStmt &S) {
7723 EmitAtSynchronizedStmt(CGF, S, ObjCTypes.getSyncEnterFn(),
7724 ObjCTypes.getSyncExitFn());
7728CGObjCNonFragileABIMac::GetEHType(QualType T) {
7729 // There's a particular fixed type info for 'id'.
7730 if (T->isObjCIdType() || T->isObjCQualifiedIdType()) {
7731 auto *IDEHType = CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id
");
7734 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
7735 llvm::GlobalValue::ExternalLinkage, nullptr,
7737 if (CGM.getTriple().isOSBinFormatCOFF())
7738 IDEHType->setDLLStorageClass(getStorage(CGM, "OBJC_EHTYPE_id
"));
7743 // All other types should be Objective-C interface pointer types.
7744 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
7747 const ObjCInterfaceType *IT = PT->getInterfaceType();
7748 assert(IT && "Invalid
@catch type.
");
7750 return GetInterfaceEHType(IT->getDecl(), NotForDefinition);
7753void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
7754 const ObjCAtTryStmt &S) {
7755 EmitTryCatchStmt(CGF, S, ObjCTypes.getObjCBeginCatchFn(),
7756 ObjCTypes.getObjCEndCatchFn(),
7757 ObjCTypes.getExceptionRethrowFn());
7761void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
7762 const ObjCAtThrowStmt &S,
7763 bool ClearInsertionPoint) {
7764 if (const Expr *ThrowExpr = S.getThrowExpr()) {
7765 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
7766 Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
7767 llvm::CallBase *Call =
7768 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception);
7769 Call->setDoesNotReturn();
7771 llvm::CallBase *Call =
7772 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionRethrowFn());
7773 Call->setDoesNotReturn();
7776 CGF.Builder.CreateUnreachable();
7777 if (ClearInsertionPoint)
7778 CGF.Builder.ClearInsertionPoint();
7782CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
7783 ForDefinition_t IsForDefinition) {
7784 llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
7785 StringRef ClassName = ID->getObjCRuntimeNameAsString();
7787 // If we don't need a definition, return the entry if found or check
7788 // if we use an external reference.
7789 if (!IsForDefinition) {
7793 // If this type (or a super class) has the __objc_exception__
7794 // attribute, emit an external reference.
7795 if (hasObjCExceptionAttribute(CGM.getContext(), ID)) {
7796 std::string EHTypeName = ("OBJC_EHTYPE_$_
" + ClassName).str();
7797 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy,
7798 false, llvm::GlobalValue::ExternalLinkage,
7799 nullptr, EHTypeName);
7800 CGM.setGVProperties(Entry, ID);
7805 // Otherwise we need to either make a new entry or fill in the initializer.
7806 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition
");
7808 std::string VTableName = "objc_ehtype_vtable
";
7809 auto *VTableGV = CGM.getModule().getGlobalVariable(VTableName);
7812 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy, false,
7813 llvm::GlobalValue::ExternalLinkage, nullptr,
7815 if (CGM.getTriple().isOSBinFormatCOFF())
7816 VTableGV->setDLLStorageClass(getStorage(CGM, VTableName));
7819 llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2);
7820 ConstantInitBuilder builder(CGM);
7821 auto values = builder.beginStruct(ObjCTypes.EHTypeTy);
7823 llvm::ConstantExpr::getInBoundsGetElementPtr(VTableGV->getValueType(),
7824 VTableGV, VTableIdx));
7825 values.add(GetClassName(ClassName));
7826 values.add(GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition));
7828 llvm::GlobalValue::LinkageTypes L = IsForDefinition
7829 ? llvm::GlobalValue::ExternalLinkage
7830 : llvm::GlobalValue::WeakAnyLinkage;
7832 values.finishAndSetAsInitializer(Entry);
7833 Entry->setAlignment(CGM.getPointerAlign().getAsAlign());
7835 Entry = values.finishAndCreateGlobal("OBJC_EHTYPE_$_
" + ClassName,
7836 CGM.getPointerAlign(),
7839 if (hasObjCExceptionAttribute(CGM.getContext(), ID))
7840 CGM.setGVProperties(Entry, ID);
7842 assert(Entry->getLinkage() == L);
7844 if (!CGM.getTriple().isOSBinFormatCOFF())
7845 if (ID->getVisibility() == HiddenVisibility)
7846 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
7848 if (IsForDefinition)
7849 if (CGM.getTriple().isOSBinFormatMachO())
7850 Entry->setSection("__DATA,__objc_const
");
7857CodeGen::CGObjCRuntime *
7858CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
7859 switch (CGM.getLangOpts().ObjCRuntime.getKind()) {
7860 case ObjCRuntime::FragileMacOSX:
7861 return new CGObjCMac(CGM);
7863 case ObjCRuntime::MacOSX:
7864 case ObjCRuntime::iOS:
7865 case ObjCRuntime::WatchOS:
7866 return new CGObjCNonFragileABIMac(CGM);
7868 case ObjCRuntime::GNUstep:
7869 case ObjCRuntime::GCC:
7870 case ObjCRuntime::ObjFW:
7871 llvm_unreachable("these runtimes are
not Mac runtimes
");
7873 llvm_unreachable("bad runtime
");
Defines the clang::ASTContext interface.
ASTImporterLookupTable & LT
@ FragileABI_Class_Meta
Is a meta-class.
@ FragileABI_Class_Hidden
Has hidden visibility.
@ FragileABI_Class_Factory
Apparently: is not a meta-class.
@ FragileABI_Class_HasCXXStructors
Has a non-trivial constructor or destructor.
@ FragileABI_Class_HasMRCWeakIvars
Class implementation was compiled under MRC and has MRC weak ivars.
@ FragileABI_Class_CompiledByARC
Class implementation was compiled under ARC.
static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT, bool pointee=false)
static bool hasWeakMember(QualType type)
static std::string getBlockLayoutInfoString(const SmallVectorImpl< CGObjCCommonMac::RUN_SKIP > &RunSkipBlockVars, bool HasCopyDisposeHelpers)
@ kCFTaggedObjectID_Integer
static llvm::StringMapEntry< llvm::GlobalVariable * > & GetConstantStringEntry(llvm::StringMap< llvm::GlobalVariable * > &Map, const StringLiteral *Literal, unsigned &StringLength)
static llvm::GlobalValue::LinkageTypes getLinkageTypeForObjCMetadata(CodeGenModule &CGM, StringRef Section)
static void addIfPresent(llvm::DenseSet< llvm::Value * > &S, Address V)
static void PushProtocolProperties(llvm::SmallPtrSet< const IdentifierInfo *, 16 > &PropertySet, SmallVectorImpl< const ObjCPropertyDecl * > &Properties, const ObjCProtocolDecl *Proto, bool IsClassProperty)
static llvm::GlobalVariable * finishAndCreateGlobal(ConstantInitBuilder::StructBuilder &Builder, const llvm::Twine &Name, CodeGenModule &CGM)
A helper function to create an internal or private global variable.
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...
@ NonFragileABI_Class_HasCXXDestructorOnly
Class has non-trivial destructors, but zero-initialization is okay.
@ NonFragileABI_Class_Hidden
Has hidden visibility.
@ NonFragileABI_Class_HasCXXStructors
Has a non-trivial constructor or destructor.
@ NonFragileABI_Class_Exception
Has the exception attribute.
@ NonFragileABI_Class_HasIvarReleaser
(Obsolete) ARC-specific: this class has a .release_ivars method
@ NonFragileABI_Class_Root
Is a root class.
@ NonFragileABI_Class_Meta
Is a meta-class.
@ NonFragileABI_Class_HasMRCWeakIvars
Class implementation was compiled under MRC and has MRC weak ivars.
@ NonFragileABI_Class_CompiledByARC
Class implementation was compiled under ARC.
static llvm::Constant * getConstantGEP(llvm::LLVMContext &VMContext, llvm::GlobalVariable *C, unsigned idx0, unsigned idx1)
getConstantGEP() - Help routine to construct simple GEPs.
static bool hasObjCExceptionAttribute(ASTContext &Context, const ObjCInterfaceDecl *OID)
hasObjCExceptionAttribute - Return true if this class or any super class has the objc_exception attri...
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
Defines the clang::LangOptions interface.
llvm::MachO::Target Target
Defines the Objective-C statement AST node classes.
__device__ __2f16 float __ockl_bool s
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CanQualType getCanonicalParamType(QualType T) const
Return the canonical parameter type corresponding to the specific potentially non-canonical one.
QualType getObjCClassType() const
Represents the Objective-C Class type.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const ASTRecordLayout & getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const
Get or compute information about the layout of the specified Objective-C implementation.
const LangOptions & getLangOpts() const
SelectorTable & Selectors
QualType getObjCProtoType() const
Retrieve the type of the Objective-C Protocol class.
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
QualType getObjCIdType() const
Represents the Objective-CC id type.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType getObjCClassRedefinitionType() const
Retrieve the type that Class has been defined to, which may be different from the built-in Class if C...
QualType getObjCIdRedefinitionType() const
Retrieve the type that id has been defined to, which may be different from the built-in id if id has ...
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getSize() const
getSize - Get the record size in characters.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
QualType withConst() const
Retrieves a version of this type with const applied.
CharUnits - This is an opaque type for sizes expressed in character units.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
llvm::Type * getElementType() const
Return the type of the values stored in this address.
unsigned getIndex() const
CharUnits getOffset() const
CGBlockInfo - Information to generate a block literal.
const BlockDecl * getBlockDecl() const
llvm::StructType * StructureType
CharUnits BlockHeaderForcedGapOffset
bool NeedsCopyDispose
True if the block has captures that would necessitate custom copy or dispose helper functions if the ...
CharUnits BlockHeaderForcedGapSize
const Capture & getCapture(const VarDecl *var) const
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::Value * CreateIsNull(Address Addr, const Twine &Name="")
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
All available information about a concrete callee.
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
Implements runtime-specific code generation functions.
virtual llvm::Constant * BuildByrefLayout(CodeGen::CodeGenModule &CGM, QualType T)=0
Returns an i8* which points to the byref layout information.
static void destroyCalleeDestroyedArguments(CodeGenFunction &CGF, const ObjCMethodDecl *method, const CallArgList &callArgs)
Destroy the callee-destroyed arguments of the given method, if it has any.
virtual llvm::Function * GenerateMethod(const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD)=0
Generate a function preamble for a method with the specified types.
virtual std::string getRCBlockLayoutStr(CodeGen::CodeGenModule &CGM, const CGBlockInfo &blockInfo)
virtual llvm::Constant * BuildGCBlockLayout(CodeGen::CodeGenModule &CGM, const CodeGen::CGBlockInfo &blockInfo)=0
virtual ConstantAddress GenerateConstantString(const StringLiteral *)=0
Generate a constant string object.
virtual void GenerateProtocol(const ObjCProtocolDecl *OPD)=0
Generate the named protocol.
virtual llvm::Constant * BuildRCBlockLayout(CodeGen::CodeGenModule &CGM, const CodeGen::CGBlockInfo &blockInfo)=0
virtual void GenerateDirectMethodPrologue(CodeGenFunction &CGF, llvm::Function *Fn, const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD)=0
Generates prologue for direct Objective-C Methods.
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
void addFrom(const CallArgList &other)
Add all the arguments from another CallArgList to this one.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Value * EmitFromMemory(llvm::Value *Value, QualType Ty)
EmitFromMemory - Change a scalar value from its memory representation to its value representation.
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
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...
void EmitAutoVarDecl(const VarDecl &D)
EmitAutoVarDecl - Emit an auto variable declaration.
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
SmallVector< llvm::Value *, 8 > ObjCEHValueStack
ObjCEHValueStack - Stack of Objective-C exception values, used for rethrows.
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...
RawAddress getNormalCleanupDestSlot()
JumpDest ReturnBlock
ReturnBlock - Unified return block.
llvm::Value * EmitObjCThrowOperand(const Expr *expr)
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
void EmitVarDecl(const VarDecl &D)
EmitVarDecl - Emit a local variable declaration.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})
EmitStmt - Emit the code for the statement.
void PopCleanupBlock(bool FallThroughIsBranchThrough=false, bool ForDeactivation=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
llvm::Type * ConvertType(QualType T)
RawAddress NormalCleanupDest
i32s containing the indexes of the cleanup destinations.
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
llvm::LLVMContext & getLLVMContext()
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
This class organizes the cross-function state that is used while generating LLVM code.
llvm::Module & getModule() const
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
void addCompilerUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.compiler.used metadata.
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
bool ReturnTypeUsesFPRet(QualType ResultType)
Return true iff the given type uses 'fpret' when used as a return type.
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
const llvm::DataLayout & getDataLayout() const
bool ReturnTypeUsesFP2Ret(QualType ResultType)
Return true iff the given type uses 'fp2ret' when used as a return type.
const llvm::Triple & getTriple() const
bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI)
Return true iff the given type uses an argument slot when 'sret' is used as a return type.
llvm::Constant * CreateRuntimeVariable(llvm::Type *Ty, StringRef Name)
Create a new runtime global variable with the specified type and name.
ConstantAddress GetAddrOfConstantCFString(const StringLiteral *Literal)
Return a pointer to a constant CFString object for the given string.
ASTContext & getContext() const
bool ReturnTypeUsesSRet(const CGFunctionInfo &FI)
Return true iff the given type uses 'sret' when used as a return type.
llvm::LLVMContext & getLLVMContext()
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
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.
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
A specialization of Address that requires the address to be an LLVM Constant.
llvm::Constant * getPointer() const
StructBuilder beginStruct(llvm::StructType *ty=nullptr)
A helper class of ConstantInitBuilder, used for building constant array initializers.
The standard implementation of ConstantInitBuilder used in Clang.
A helper class of ConstantInitBuilder, used for building constant struct initializers.
Information for lazily generating a cleanup.
LValue - This represents an lvalue references.
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
An abstract representation of an aligned address.
llvm::Value * getPointer() const
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
Decl - This represents one declaration (or definition), e.g.
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
This represents one expression.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
One of these records is kept for each identifier that is lexed.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
clang::ObjCRuntime ObjCRuntime
std::string ObjCConstantStringClass
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Represents Objective-C's @catch statement.
Represents Objective-C's @finally statement.
Represents Objective-C's @synchronized statement.
Represents Objective-C's @throw statement.
Represents Objective-C's @try ... @catch ... @finally statement.
const ObjCAtFinallyStmt * getFinallyStmt() const
Retrieve the @finally statement, if any.
catch_range catch_stmts()
ObjCCategoryDecl - Represents a category declaration.
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
ObjCCompatibleAliasDecl - Represents alias of a class.
ObjCContainerDecl - Represents a container for method declarations.
method_range methods() const
prop_range properties() const
const ObjCInterfaceDecl * getClassInterface() const
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Represents an ObjC class declaration.
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for class's metadata.
ObjCInterfaceDecl * getSuperClass() const
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...
ObjCIvarDecl - Represents an ObjC instance variable.
ObjCInterfaceDecl * getContainingInterface()
Return the class interface that this ivar is logically contained in; this is either the interface whe...
ObjCIvarDecl * getNextIvar()
ObjCMethodDecl - Represents an instance or class method declaration.
ImplicitParamDecl * getSelfDecl() const
bool hasParamDestroyedInCallee() const
True if the method has a parameter that's destroyed in the callee.
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
ObjCMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Selector getSelector() const
ImplicitParamDecl * getCmdDecl() const
QualType getReturnType() const
bool isClassMethod() const
ObjCInterfaceDecl * getClassInterface()
Represents a pointer to an Objective C object.
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
bool isObjCIdType() const
True if this is equivalent to the 'id' type, i.e.
Represents a class type in Objective C.
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface.
Represents one property declaration in an Objective-C interface.
Represents an Objective-C protocol declaration.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
StringRef getObjCRuntimeNameAsString() const
Produce a name to be used for protocol's metadata.
ObjCProtocolList::iterator protocol_iterator
protocol_iterator protocol_begin() const
protocol_range protocols() const
protocol_iterator protocol_end() const
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
bool isObjCGCStrong() const
true when Type is objc's strong.
bool isObjCGCWeak() const
true when Type is objc's weak.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
Represents a struct/union/class.
field_range fields() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
Selector getSelector(unsigned NumArgs, const IdentifierInfo **IIV)
Can create any sort of selector.
Smart pointer class that efficiently represents Objective-C method names.
std::string getAsString() const
Derive the full selector name (e.g.
Stmt - This represents one statement.
StringLiteral - This represents a string literal expression, e.g.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
unsigned getCharWidth() const
The base class of the type hierarchy.
bool isBlockPointerType() const
CanQualType getCanonicalTypeUnqualified() const
const T * castAs() const
Member-template castAs<specific type>.
bool isObjCQualifiedIdType() const
bool isObjCIdType() const
bool isObjCObjectPointerType() const
bool isObjCQualifiedClassType() const
bool isObjCClassType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
Represents a variable declaration or definition.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, BlockDecl > blockDecl
Matches block declarations.
bool Zero(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
Selector GetUnarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing an unary selector.
Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
const FunctionProtoType * T
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ HiddenVisibility
Objects with "hidden" visibility are not seen by the dynamic linker.
int printf(__constant const char *st,...) __attribute__((format(printf
float __ovld __cnfn length(float)
Return the length of vector p, i.e., sqrt(p.x2 + p.y 2 + ...)
llvm::CallingConv::ID getRuntimeCC() const
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::IntegerType * IntTy
int
llvm::PointerType * Int8PtrTy
llvm::PointerType * UnqualPtrTy
llvm::IntegerType * PtrDiffTy
CharUnits getPointerAlign() const